From c5432960d94c62defc79cbd94a361c469bfb75a1 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 16 Nov 2022 14:11:59 -0600 Subject: [PATCH 01/33] device-mapper-multipath-0.9.3-1 Update to the head of the upstream staging branch * Previous patches 0001-0042 are included in the source tarball * Patches 0001-0032 are from the upstream staging branch Rename redhat patches * Previous patches 0043-0053 are now patches 0033-0043 Change back to using readline instead of libedit * The code the uses readline has been isolated from the code that is licensed gpl v2 only. Add libmpathutil libraries to spec file Add multipathc program to spec file Add multipath.conf systemd tempfile configuration to spec file Misc spec file cleanups --- .gitignore | 1 + ...github-workflows-switch-to-fedora-36.patch | 29 - ...tipath-fix-show-paths-format-failure.patch | 35 + ...kefile.inc-fix-man-and-include-paths.patch | 41 + ...fix-multipath-ll-bug-for-Native-NVME.patch | 103 -- ...s-Makefile.inc-Fix-paths-for-systemd.patch | 65 ++ ...update-Huawei-OceanStor-NVMe-vendor-.patch | 40 - ...Makefile.inc-don-t-take-values-from-.patch | 113 +++ ...update-Generic-NVMe-vendor-regex-in-.patch | 33 - ...-find_multipaths_timeout-for-unknown.patch | 29 - ...th-tools-Makefile.inc-get-rid-of-RUN.patch | 63 ++ ...Makefile.inc-more-compact-code-for-L.patch | 38 + ...-update-devel-repo-info-in-README.md.patch | 52 -- ...Makefiles-simplify-code-for-include-.patch | 139 +++ 0007-multipath-tools-delete-README.alua.patch | 48 - ...multipath-tools-Makefiles-use-mandir.patch | 185 ++++ ...ath-tools-add-ALUA-info-to-README.md.patch | 53 -- ...multipath-alua-remove-get_sysfs_pg83.patch | 95 -- ...Makefile.inc-simplify-expression-for.patch | 36 + ...libmultipath-remove-sysfs_get_binary.patch | 77 -- ...Makefile.inc-untangle-paths-and-sour.patch | 68 ++ ...fs_bin_attr_get_value-no-error-if-bu.patch | 65 -- ...Makefiles-replace-libdir-by-plugindi.patch | 110 +++ ...mon-code-path-for-sysfs_attr_get_val.patch | 115 --- ...Makefile.inc-use-simple-make-variabl.patch | 112 +++ ...itize-error-checking-in-sysfs-access.patch | 165 ---- ...tools-Makefile.inc-fix-a-log-message.patch | 24 + 0014-libmultipath-get-rid-of-PATH_SIZE.patch | 115 --- ...Makefile.inc-set-systemd-specific-fl.patch | 129 +++ ...fs_attr_get_value-don-t-return-0-if-.patch | 172 ---- ...ile-fix-compilation-flags-for-libedi.patch | 54 ++ ...fs_attr_set_value-don-t-return-0-on-.patch | 251 ----- ...Makefiles-clean-up-executable-Makefi.patch | 136 +++ ...fs-cleanup-file-descriptors-on-pthre.patch | 71 -- ...Makefiles-use-common-code-for-librar.patch | 261 ++++++ ...tipathd-log-failure-setting-sysfs-at.patch | 168 ---- ...Makefiles-move-common-code-to-rules..patch | 172 ++++ ...expect_condlog-skip-depending-on-ver.patch | 37 - ...ath-tools-Makefiles-create-config.mk.patch | 603 ++++++++++++ ...-tests-__wrap_dlog-print-log-message.patch | 27 - ...h-tools-Makefiles-enable-quiet-build.patch | 879 ++++++++++++++++++ 0021-multipath-tests-add-sysfs-test.patch | 538 ----------- ...quiet-build-support-for-top-level-Ma.patch | 183 ++++ ...itHub-workflows-use-make-j8-Orecurse.patch | 132 +++ ...sion-bump-version-for-sysfs-accessor.patch | 43 - ...ection-about-libedit-and-libreadline.patch | 48 + ...et-detect_checker-for-clariion-Unity.patch | 31 - ...dentation-in-paragraph-about-device-.patch | 34 + 0024-libmultipath-spelling-cplusplus.patch | 26 - ...nt-options-for-paths-and-optimizatio.patch | 47 + 0025-libmultipath-spelling-ascii.patch | 25 - ...E.md-document-how-to-customize-build.patch | 37 + 0026-libmultipath-spelling-progress.patch | 25 - ...id-Warray-bounds-error-with-gcc-12-a.patch | 63 ++ 0027-multipath-tools-spelling-fixes.patch | 599 ------------ ...d-NULL-string-in-released_to_systemd.patch | 26 + ...remove-list-of-rebranded-arrays-vend.patch | 57 -- ...h-avoid-NULL-string-in-is_udev_ready.patch | 26 + ...correct-CLARiiON-info-from-multipath.patch | 47 - ...th-impove-add_feature-variable-names.patch | 115 +++ ...add-basic-info-on-how-to-use-multipa.patch | 41 - ...-initialize-the-field-width-in-show_.patch | 31 + ...r-out-the-code-to-flush-a-map-with-n.patch | 90 -- ...mprove-remove_feature-variable-names.patch | 144 +++ ...urn-success-if-we-raced-to-remove-a-.patch | 47 - 0033-RH-fixup-udev-rules-for-redhat.patch | 66 ++ ...Handle-losing-all-path-in-update_map.patch | 36 - ...property-blacklist-exception-builtin.patch | 6 +- ...-fix-systemd-timers-in-the-initramfs.patch | 35 - ...RH-don-t-start-without-a-config-file.patch | 28 +- ...multipathd-Add-missing-ctype-include.patch | 26 - ...H-Fix-nvme-function-missing-argument.patch | 0 ...thd-replace-libreadline-with-libedit.patch | 102 -- ... 0037-RH-use-rpm-optflags-if-present.patch | 29 +- ...vert-license-of-strbuf-code-to-GPL-2.patch | 42 - ...hconf.patch => 0038-RH-add-mpathconf.patch | 55 +- ...-build-and-unittest.yaml-add-libedit.patch | 44 - ...om-kernel-cmdline-mpath.wwids-with-A.patch | 10 +- ...kflows-coverity.yaml-add-libedit-dev.patch | 26 - ...-default-find_mutipaths-value-to-off.patch | 2 +- ...b-workflows-abi.yaml-add-libedit-dev.patch | 26 - ...-native.yaml-add-libedit-dev-except-.patch | 71 -- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-foreign.yaml-switch-to-Debian-11-bu.patch | 40 - ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...si-device-handlers-to-modules-load.d.patch | 4 +- 0043-RH-fixup-udev-rules-for-redhat.patch | 63 -- ...-RH-compile-with-libreadline-support.patch | 26 + device-mapper-multipath.spec | 159 ++-- sources | 2 +- 90 files changed, 4400 insertions(+), 3968 deletions(-) delete mode 100644 0001-github-workflows-switch-to-fedora-36.patch create mode 100644 0001-libmultipath-fix-show-paths-format-failure.patch create mode 100644 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch delete mode 100644 0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch create mode 100644 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch delete mode 100644 0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch create mode 100644 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch delete mode 100644 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch delete mode 100644 0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch create mode 100644 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch create mode 100644 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch delete mode 100644 0006-multipath-tools-update-devel-repo-info-in-README.md.patch create mode 100644 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch delete mode 100644 0007-multipath-tools-delete-README.alua.patch create mode 100644 0008-multipath-tools-Makefiles-use-mandir.patch delete mode 100644 0008-multipath-tools-add-ALUA-info-to-README.md.patch delete mode 100644 0009-libmultipath-alua-remove-get_sysfs_pg83.patch create mode 100644 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch delete mode 100644 0010-libmultipath-remove-sysfs_get_binary.patch create mode 100644 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch delete mode 100644 0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch create mode 100644 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch delete mode 100644 0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch create mode 100644 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch delete mode 100644 0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch create mode 100644 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch delete mode 100644 0014-libmultipath-get-rid-of-PATH_SIZE.patch create mode 100644 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch delete mode 100644 0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch create mode 100644 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch delete mode 100644 0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch create mode 100644 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch delete mode 100644 0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch create mode 100644 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch delete mode 100644 0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch create mode 100644 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch delete mode 100644 0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch create mode 100644 0019-multipath-tools-Makefiles-create-config.mk.patch delete mode 100644 0020-multipath-tests-__wrap_dlog-print-log-message.patch create mode 100644 0020-multipath-tools-Makefiles-enable-quiet-build.patch delete mode 100644 0021-multipath-tests-add-sysfs-test.patch create mode 100644 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch create mode 100644 0022-GitHub-workflows-use-make-j8-Orecurse.patch delete mode 100644 0022-libmultipath.version-bump-version-for-sysfs-accessor.patch create mode 100644 0023-README.md-Move-section-about-libedit-and-libreadline.patch delete mode 100644 0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch create mode 100644 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch delete mode 100644 0024-libmultipath-spelling-cplusplus.patch create mode 100644 0025-README.md-document-options-for-paths-and-optimizatio.patch delete mode 100644 0025-libmultipath-spelling-ascii.patch create mode 100644 0026-README.md-document-how-to-customize-build.patch delete mode 100644 0026-libmultipath-spelling-progress.patch create mode 100644 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch delete mode 100644 0027-multipath-tools-spelling-fixes.patch create mode 100644 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch delete mode 100644 0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch create mode 100644 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch delete mode 100644 0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch create mode 100644 0030-libmultipath-impove-add_feature-variable-names.patch delete mode 100644 0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch create mode 100644 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch delete mode 100644 0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch create mode 100644 0032-libmultipath-improve-remove_feature-variable-names.patch delete mode 100644 0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch create mode 100644 0033-RH-fixup-udev-rules-for-redhat.patch delete mode 100644 0033-multipathd-Handle-losing-all-path-in-update_map.patch rename 0044-RH-Remove-the-property-blacklist-exception-builtin.patch => 0034-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) delete mode 100644 0034-multipath-fix-systemd-timers-in-the-initramfs.patch rename 0045-RH-don-t-start-without-a-config-file.patch => 0035-RH-don-t-start-without-a-config-file.patch (83%) delete mode 100644 0035-multipathd-Add-missing-ctype-include.patch rename 0046-RH-Fix-nvme-function-missing-argument.patch => 0036-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0036-multipathd-replace-libreadline-with-libedit.patch rename 0047-RH-use-rpm-optflags-if-present.patch => 0037-RH-use-rpm-optflags-if-present.patch (71%) delete mode 100644 0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch rename 0048-RH-add-mpathconf.patch => 0038-RH-add-mpathconf.patch (94%) delete mode 100644 0038-github-workflows-build-and-unittest.yaml-add-libedit.patch rename 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (95%) delete mode 100644 0039-github-workflows-coverity.yaml-add-libedit-dev.patch rename 0050-RH-reset-default-find_mutipaths-value-to-off.patch => 0040-RH-reset-default-find_mutipaths-value-to-off.patch (96%) delete mode 100644 0040-github-workflows-abi.yaml-add-libedit-dev.patch delete mode 100644 0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch rename 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch rename 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) rename 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch (92%) delete mode 100644 0043-RH-fixup-udev-rules-for-redhat.patch create mode 100644 0044-RH-compile-with-libreadline-support.patch diff --git a/.gitignore b/.gitignore index 7a13460..c9e44d7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.7.tgz /multipath-tools-0.8.9.tgz /multipath-tools-0.9.0.tgz +/multipath-tools-0.9.3.tgz diff --git a/0001-github-workflows-switch-to-fedora-36.patch b/0001-github-workflows-switch-to-fedora-36.patch deleted file mode 100644 index 1583fd8..0000000 --- a/0001-github-workflows-switch-to-fedora-36.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 10 Jun 2022 22:44:11 +0200 -Subject: [PATCH] github workflows: switch to fedora 36 - -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 19c9e297..ddfd4a09 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -12,12 +12,10 @@ jobs: - runs-on: ubuntu-20.04 - strategy: - matrix: -- os: [buster, jessie, bullseye, fedora-35] -+ os: [buster, jessie, bullseye, fedora-36] - arch: ['', '-i386'] - exclude: -- - os: fedora-34 -- arch: '-i386' -- - os: fedora-35 -+ - os: fedora-36 - arch: '-i386' - container: mwilck/multipath-build-${{ matrix.os }}${{ matrix.arch }} - steps: diff --git a/0001-libmultipath-fix-show-paths-format-failure.patch b/0001-libmultipath-fix-show-paths-format-failure.patch new file mode 100644 index 0000000..4f56830 --- /dev/null +++ b/0001-libmultipath-fix-show-paths-format-failure.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paul Koetsier +Date: Thu, 27 Oct 2022 19:29:28 +0200 +Subject: [PATCH] libmultipath: fix 'show paths format' failure + +Prevent 'multipathd show paths format "%c"' from failing on orphan paths. +For orphan paths the checker class isn't set, which caused +snprint_path_checker() to fail which in turn caused 'show paths format' to fail +when the format string contained "%c". + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index d7d522c8..3193dbe0 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -734,8 +734,12 @@ snprint_host_adapter (struct strbuf *buff, const struct path * pp) + static int + snprint_path_checker (struct strbuf *buff, const struct path * pp) + { +- const struct checker * c = &pp->checker; +- return snprint_str(buff, checker_name(c)); ++ const char * n = checker_name(&pp->checker); ++ ++ if (n) ++ return snprint_str(buff, n); ++ else ++ return snprint_str(buff, "(null)"); + } + + static int diff --git a/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch b/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch new file mode 100644 index 0000000..4afae52 --- /dev/null +++ b/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 18:22:59 +0200 +Subject: [PATCH] fixup! Makefile.inc: fix man and include paths + +Paths would now be wrong with the default (empty) prefix. +Fix it. + +Fixes: 2b2885c ("Makefile.inc: fix man and include paths") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 4d843ce5..32001434 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -89,9 +89,9 @@ modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d + multipathdir = $(TOPDIR)/libmultipath + daemondir = $(TOPDIR)/multipathd + mpathutildir = $(TOPDIR)/libmpathutil +-man8dir = $(prefix)/share/man/man8 +-man5dir = $(prefix)/share/man/man5 +-man3dir = $(prefix)/share/man/man3 ++man8dir = $(usr_prefix)/share/man/man8 ++man5dir = $(usr_prefix)/share/man/man5 ++man3dir = $(usr_prefix)/share/man/man3 + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath +@@ -102,7 +102,7 @@ mpathvaliddir = $(TOPDIR)/libmpathvalid + thirdpartydir = $(TOPDIR)/third-party + libdmmpdir = $(TOPDIR)/libdmmp + nvmedir = $(TOPDIR)/libmultipath/nvme +-includedir = $(prefix)/include ++includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d diff --git a/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch b/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch deleted file mode 100644 index c54b4cd..0000000 --- a/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: chengjike -Date: Fri, 8 Oct 2021 20:24:49 +0800 -Subject: [PATCH] multipath-tools: fix "multipath -ll" bug for Native NVME - Multipath devices - -After "Native NVME Multipath" is configured, -the content displayed is incorrect when you run "multipath -ll" command. -Each NVME devices have the same path name. For example: - -[root@localhost home]# multipath -ll -eui.710032e8fb22a86c24a52c1000000db8 [nvme]:nvme1n1 NVMe,Huawei-XSG1,1000001 -size=10485760 features='n/a' hwhandler='ANA' wp=rw -|-+- policy='n/a' prio=50 status=optimized -| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live -`-+- policy='n/a' prio=50 status=optimized - `- 1:9:1 nvme1c9n1 0:0 n/a optimized live -eui.710032e8fb22a86b24a52c7c00000db7 [nvme]:nvme1n2 NVMe,Huawei-XSG1,1000001 -size=10485760 features='n/a' hwhandler='ANA' wp=rw -|-+- policy='n/a' prio=50 status=optimized -| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live -`-+- policy='n/a' prio=50 status=optimized - `- 1:9:1 nvme1c9n1 0:0 n/a optimized live -[root@localhost home]# - -The logical paths of "nvme1n1" and "nvme1n2" are both "nvme1c4n1" and "nvme1c9n1". -So when multipath-tools aggregates disks, use "nvme_ns_head->instance" for matching. -such as ,Use "b" in "nvmeanb" string to match "z" in "nvmexcynz"(a,b,x,y,z can be any number), -and if "b" and "z" are the same, they are related. - -Signed-off-by: chengjike -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/foreign/nvme.c | 26 ++++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c -index 52ca56d8..9a05b333 100644 ---- a/libmultipath/foreign/nvme.c -+++ b/libmultipath/foreign/nvme.c -@@ -531,14 +531,18 @@ static int _dirent_controller(const struct dirent *di) - - /* Find the block device for a given nvme controller */ - struct udev_device *get_ctrl_blkdev(const struct context *ctx, -- struct udev_device *ctrl) -+ struct udev_device *ctrl, const char *ctrl_name) - { -+ int ctrl_num, ns_num; - struct udev_list_entry *item; - struct udev_device *blkdev = NULL; - struct udev_enumerate *enm = udev_enumerate_new(ctx->udev); - const char *devtype; - -- if (enm == NULL) -+ if (enm == NULL || ctrl_name == NULL) -+ return NULL; -+ -+ if (sscanf(ctrl_name, "nvme%dn%d", &ctrl_num, &ns_num) != 2) - return NULL; - - pthread_cleanup_push(_udev_enumerate_unref, enm); -@@ -556,6 +560,8 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, - item != NULL; - item = udev_list_entry_get_next(item)) { - struct udev_device *tmp; -+ const char *name = NULL ; -+ int m, n, l; - - tmp = udev_device_new_from_syspath(ctx->udev, - udev_list_entry_get_name(item)); -@@ -563,11 +569,19 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, - continue; - - devtype = udev_device_get_devtype(tmp); -- if (devtype && !strcmp(devtype, "disk")) { -+ if (devtype == NULL || strcmp(devtype, "disk")) { -+ udev_device_unref(tmp); -+ continue; -+ } -+ -+ name = udev_device_get_sysname(tmp); -+ if (name != NULL && -+ sscanf(name, "nvme%dc%dn%d", &m, &n, &l) == 3 && -+ l == ns_num) { - blkdev = tmp; - break; -- } else -- udev_device_unref(tmp); -+ } -+ udev_device_unref(tmp); - } - - if (blkdev == NULL) -@@ -680,7 +694,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - } - - pthread_cleanup_push(_udev_device_unref, ctrl); -- udev = get_ctrl_blkdev(ctx, ctrl); -+ udev = get_ctrl_blkdev(ctx, ctrl, udev_device_get_sysname(map->udev)); - /* - * We give up the reference to the nvme device here and get - * it back from the child below. diff --git a/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch b/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch new file mode 100644 index 0000000..8a25fe0 --- /dev/null +++ b/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:09:52 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: Fix paths for systemd + +With prefix=/usr, systemd files were installed under /usr/usr/lib, +which is bogus. Clean this up, and document how to handle systemd's +"rootprefix" options. Remove the previous SYSTEMDPATH option. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 32001434..351358a9 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -53,10 +53,6 @@ ifndef SYSTEMD + endif + endif + +-ifndef SYSTEMDPATH +- SYSTEMDPATH=usr/lib +-endif +- + ifndef DEVMAPPER_INCDIR + ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) + DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) +@@ -78,14 +74,22 @@ ifndef LINUX_HEADERS_INCDIR + LINUX_HEADERS_INCDIR = /usr/include + endif + ++# Paths. All these can be overridden on the "make" command line. + prefix = ++# Prefix for binaries + exec_prefix = $(prefix) ++# Prefix for non-essential libraries (libdmmp) + usr_prefix = $(prefix) ++# Where to install systemd-related files. systemd is usually installed under /usr ++# Note: some systemd installations use separate "prefix" and "rootprefix". ++# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) ++systemd_prefix := /usr ++unitdir := $(systemd_prefix)/lib/systemd/system ++tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d ++modulesloaddir := $(systemd_prefix)/lib/modules-load.d ++libudevdir := $(systemd_prefix)/lib/udev ++udevrulesdir := $(libudevdir)/rules.d + bindir = $(exec_prefix)/sbin +-libudevdir = $(prefix)/$(SYSTEMDPATH)/udev +-tmpfilesdir = $(prefix)/$(SYSTEMDPATH)/tmpfiles.d +-udevrulesdir = $(libudevdir)/rules.d +-modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d + multipathdir = $(TOPDIR)/libmultipath + daemondir = $(TOPDIR)/multipathd + mpathutildir = $(TOPDIR)/libmpathutil +@@ -95,7 +99,6 @@ man3dir = $(usr_prefix)/share/man/man3 + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath +-unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system + mpathpersistdir = $(TOPDIR)/libmpathpersist + mpathcmddir = $(TOPDIR)/libmpathcmd + mpathvaliddir = $(TOPDIR)/libmpathvalid diff --git a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch deleted file mode 100644 index 9643721..0000000 --- a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 10 Jul 2022 01:07:08 +0200 -Subject: [PATCH] multipath-tools: update Huawei OceanStor NVMe vendor id - -"NVME" in the doc, but "NVMe" is the real output: -(page 61-62): https://drive.google.com/file/d/1c5RK4GXX7ofZBFxTtZ_IN1qHyIjw5eR1 -https://marc.info/?l=dm-devel&m=163393151312418 -Use both, just in case. - -Cc: -Cc: -Cc: -Cc: Zhouweigang (Jack) -Cc: Zou Ming -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 513fa679..fc0252ba 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1116,7 +1116,7 @@ static struct hwentry default_hw[] = { - }, - { - /* OceanStor NVMe */ -- .vendor = "NVME", -+ .vendor = "NVM[eE]", - .product = "Huawei-XSG1", - .checker_name = DIRECTIO, - .no_path_retry = 12, diff --git a/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch b/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch new file mode 100644 index 0000000..5c1b7b3 --- /dev/null +++ b/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch @@ -0,0 +1,113 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 13:24:34 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: don't take values from + environment + +Don't use environment variables to initialize LIB, RUN, SYSTEMD, SYSTEMDPATH, +DEVMAPPER_INCDIR, LIBUDEV_INCDIR, and LINUX_HEADERS_INCDIR. Taking +such variables from the environment is generally discouraged +(see https://www.gnu.org/software/make/manual/html_node/Environment.html). + +Overriding variables from the commandline is still possible +(https://www.gnu.org/software/make/manual/html_node/Overriding.html). +So now, when building multipath-tools, rather then running +"RUN=/somedir make", users need to run "make RUN=/somedir". + +This simplifies the Makefile without losing important functionality. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 60 ++++++++++++++++++++++------------------------------ + 1 file changed, 25 insertions(+), 35 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 351358a9..d897ac7a 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -20,59 +20,49 @@ SCSI_DH_MODULES_PRELOAD := + + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) + ++# PKGCONFIG must be read from the environment to enable compilation ++# in Debian multiarch setups + PKGCONFIG ?= pkg-config + + ifeq ($(TOPDIR),) + TOPDIR = .. + endif + +-ifndef LIB +- ifeq ($(shell test -d /lib64 && echo 1),1) +- LIB=lib64 +- else +- LIB=lib +- endif ++ifeq ($(shell test -d /lib64 && echo 1),1) ++ LIB=lib64 ++else ++ LIB=lib + endif + +-ifndef RUN +- ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) +- RUN=run +- else +- RUN=var/run +- endif ++ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) ++ RUN=run ++else ++ RUN=var/run + endif + +-ifndef SYSTEMD +- ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') +- else +- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ +- sed -n 's/systemd \([0-9]*\).*/\1/p') +- endif ++ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) ++ SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') ++else ++ ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) ++ SYSTEMD = $(shell systemctl --version 2> /dev/null | \ ++ sed -n 's/systemd \([0-9]*\).*/\1/p') + endif + endif + +-ifndef DEVMAPPER_INCDIR +- ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) +- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) +- else +- DEVMAPPER_INCDIR = /usr/include +- endif ++ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) ++ DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) ++else ++ DEVMAPPER_INCDIR = /usr/include + endif + +-ifndef LIBUDEV_INCDIR +- ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) +- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) +- else +- LIBUDEV_INCDIR = /usr/include +- endif ++ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) ++ LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) ++else ++ LIBUDEV_INCDIR = /usr/include + endif + + # Allow user to override default location. +-ifndef LINUX_HEADERS_INCDIR +- LINUX_HEADERS_INCDIR = /usr/include +-endif ++LINUX_HEADERS_INCDIR = /usr/include + + # Paths. All these can be overridden on the "make" command line. + prefix = diff --git a/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch deleted file mode 100644 index 4ef193d..0000000 --- a/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 10 Jul 2022 01:07:09 +0200 -Subject: [PATCH] multipath-tools: update "Generic NVMe" vendor regex in - hwtable - -to accept NVME and NVMe - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index fc0252ba..c88fa09a 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -86,7 +86,7 @@ static struct hwentry default_hw[] = { - */ - { - /* Generic NVMe */ -- .vendor = "NVME", -+ .vendor = "NVM[eE]", - .product = ".*", - .uid_attribute = DEFAULT_NVME_UID_ATTRIBUTE, - .checker_name = NONE, diff --git a/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch b/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch deleted file mode 100644 index c2abfaa..0000000 --- a/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 12 Jul 2022 17:02:51 -0500 -Subject: [PATCH] libmultipath: fix find_multipaths_timeout for unknown - hardware - -pp->hwe is now a vector that will always be allocated for all path -devices. Instead of checking if it is NULL, check if it is empty. - -Fixes: f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/propsel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 50d0b5c8..f782f251 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -1293,7 +1293,7 @@ out: - */ - if (pp->find_multipaths_timeout < 0) { - pp->find_multipaths_timeout = -pp->find_multipaths_timeout; -- if (!pp->hwe) { -+ if (VECTOR_SIZE(pp->hwe) == 0) { - pp->find_multipaths_timeout = - DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT; - origin = "(default for unknown hardware)"; diff --git a/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch b/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch new file mode 100644 index 0000000..c0543f5 --- /dev/null +++ b/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 15:25:31 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: get rid of RUN + +Just use $(runtimedir). Also, make the code more compact by using +the "if" function instead of a conditional. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 10 ++-------- + libmultipath/defaults.h | 2 +- + 2 files changed, 3 insertions(+), 9 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index d897ac7a..b4ec647c 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -34,12 +34,6 @@ else + LIB=lib + endif + +-ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) +- RUN=run +-else +- RUN=var/run +-endif +- + ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) + SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') + else +@@ -99,7 +93,7 @@ includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d +-runtimedir := /$(RUN) ++runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + + GZIP_PROG = gzip -9 -c + RM = rm -f +@@ -143,7 +137,7 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) + CPPFLAGS := $(FORTIFY_OPT) \ +- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ ++ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" \ + -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 3d552b33..a5e9ea0c 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -62,7 +62,7 @@ + + #define DEV_LOSS_TMO_UNSET 0U + #define MAX_DEV_LOSS_TMO UINT_MAX +-#define DEFAULT_PIDFILE "/" RUN_DIR "/multipathd.pid" ++#define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" + #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" + #define DEFAULT_CONFIGFILE "/etc/multipath.conf" + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" diff --git a/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch b/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch new file mode 100644 index 0000000..2a0eda4 --- /dev/null +++ b/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:14:22 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: more compact code for LIB + +Use make's "if" function instead of a conditional. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index b4ec647c..c39cec9b 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -28,12 +28,6 @@ ifeq ($(TOPDIR),) + TOPDIR = .. + endif + +-ifeq ($(shell test -d /lib64 && echo 1),1) +- LIB=lib64 +-else +- LIB=lib +-endif +- + ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) + SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') + else +@@ -80,6 +74,7 @@ mpathutildir = $(TOPDIR)/libmpathutil + man8dir = $(usr_prefix)/share/man/man8 + man5dir = $(usr_prefix)/share/man/man5 + man3dir = $(usr_prefix)/share/man/man3 ++LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath diff --git a/0006-multipath-tools-update-devel-repo-info-in-README.md.patch b/0006-multipath-tools-update-devel-repo-info-in-README.md.patch deleted file mode 100644 index 3eaf2c0..0000000 --- a/0006-multipath-tools-update-devel-repo-info-in-README.md.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 14 Jul 2022 21:05:39 +0200 -Subject: [PATCH] multipath-tools: update devel repo info in README.md - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 10 +++------- - 1 file changed, 3 insertions(+), 7 deletions(-) - -diff --git a/README.md b/README.md -index f06f8cea..dcf51f20 100644 ---- a/README.md -+++ b/README.md -@@ -3,7 +3,6 @@ - multipath-tools for Linux - ========================= - -- - https://github.com/opensvc/multipath-tools - - This package provides the following binaries to drive the Device Mapper multipathing driver: -@@ -42,14 +41,12 @@ Go to: https://github.com/opensvc/multipath-tools/tags - Select a release-tag and then click on "zip" or "tar.gz". - - --Source code --=========== -+Devel code -+========== - - To get latest devel code: - -- git clone https://github.com/opensvc/multipath-tools.git -- --Github page: https://github.com/opensvc/multipath-tools -+ git clone -b queue https://github.com/openSUSE/multipath-tools - - - Building multipath-tools -@@ -149,4 +146,3 @@ The multipath-tools source code is covered by several different licences. - Refer to the individual source files for details. - Source files which do not specify a licence are shipped under LGPL-2.0 - (see `LICENSES/LGPL-2.0`). -- diff --git a/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch b/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch new file mode 100644 index 0000000..c6be343 --- /dev/null +++ b/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch @@ -0,0 +1,139 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:17:40 +0200 +Subject: [PATCH] multipath-tools: Makefiles: simplify code for include dirs + +Use make's if function, and use lower-case latters for make variable +names that represent directories, such as elsewhere. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 16 +++------------- + kpartx/Makefile | 2 +- + libmultipath/Makefile | 14 +++++++------- + libmultipath/prioritizers/Makefile | 2 +- + multipathd/Makefile | 4 ++-- + 5 files changed, 14 insertions(+), 24 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index c39cec9b..38bd1d80 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -37,20 +37,7 @@ else + endif + endif + +-ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) +- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) +-else +- DEVMAPPER_INCDIR = /usr/include +-endif +- +-ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) +- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) +-else +- LIBUDEV_INCDIR = /usr/include +-endif +- + # Allow user to override default location. +-LINUX_HEADERS_INCDIR = /usr/include + + # Paths. All these can be overridden on the "make" command line. + prefix = +@@ -89,6 +76,9 @@ pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) ++devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/usr/include) ++libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) ++kernel_incdir := /usr/include + + GZIP_PROG = gzip -9 -c + RM = rm -f +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 742d3bcd..bdf2d035 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -9,7 +9,7 @@ LDFLAGS += $(BIN_LDFLAGS) + + LIBDEPS += -ldevmapper + +-ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_COOKIE + endif + +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 3b60a525..f0df27c0 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -22,31 +22,31 @@ ifdef SYSTEMD + endif + endif + +-ifneq ($(call check_func,dm_task_no_flush,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_FLUSH + endif + +-ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_GET_ERRNO + endif + +-ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_COOKIE + endif + +-ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(LIBUDEV_INCDIR)/libudev.h),0) ++ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) + CPPFLAGS += -DLIBUDEV_API_RECVBUF + endif + +-ifneq ($(call check_func,dm_task_deferred_remove,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_DEFERRED + endif + +-ifneq ($(call check_func,dm_hold_control_dev,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_HOLD_CONTROL + endif + +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) + CPPFLAGS += -DFPIN_EVENT_HANDLER + endif + +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 400f7735..97155f51 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -26,7 +26,7 @@ LIBS = \ + libpriopath_latency.so \ + libpriosysfs.so + +-ifneq ($(call check_file,$(LINUX_HEADERS_INCDIR)/linux/nvme_ioctl.h),0) ++ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) + LIBS += libprioana.so + CPPFLAGS += -I../nvme + endif +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 3ce9465e..c462d7b1 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -1,10 +1,10 @@ + include ../Makefile.inc + +-ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) ++ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_GET_ERRNO + endif + +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) + CPPFLAGS += -DFPIN_EVENT_HANDLER + FPIN_SUPPORT = 1 + endif diff --git a/0007-multipath-tools-delete-README.alua.patch b/0007-multipath-tools-delete-README.alua.patch deleted file mode 100644 index 8682745..0000000 --- a/0007-multipath-tools-delete-README.alua.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 14 Jul 2022 21:05:40 +0200 -Subject: [PATCH] multipath-tools: delete README.alua - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.alua | 24 ------------------------ - 1 file changed, 24 deletions(-) - delete mode 100644 README.alua - -diff --git a/README.alua b/README.alua -deleted file mode 100644 -index 5d2b1c64..00000000 ---- a/README.alua -+++ /dev/null -@@ -1,24 +0,0 @@ --This is a rough guide, consult your storage device manufacturer documentation. -- --ALUA is supported in some devices, but usually it's disabled by default. --To enable ALUA, the following options should be changed: -- --- EMC CLARiiON/VNX: -- "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" -- --- HPE 3PAR, Primera, and Alletra 9000: -- "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". -- --- Promise VTrak/Vess: -- "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" -- must be "Active-Active". -- --- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: -- "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". -- --- NetApp ONTAP: -- To check ALUA state: "igroup show -v ", and to enable ALUA: -- "igroup set alua yes". -- --- Huawei OceanStor: -- "Host Access Mode" should be changed to "Asymmetric". diff --git a/0008-multipath-tools-Makefiles-use-mandir.patch b/0008-multipath-tools-Makefiles-use-mandir.patch new file mode 100644 index 0000000..10e1ca8 --- /dev/null +++ b/0008-multipath-tools-Makefiles-use-mandir.patch @@ -0,0 +1,185 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:25:04 +0200 +Subject: [PATCH] multipath-tools: Makefiles: use $(mandir) + +Simply use $(mandir) rather than 3 different variables. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 4 +--- + kpartx/Makefile | 6 +++--- + libdmmp/Makefile | 8 ++++---- + libmpathpersist/Makefile | 10 +++++----- + mpathpersist/Makefile | 6 +++--- + multipath/Makefile | 12 ++++++------ + multipathd/Makefile | 10 +++++----- + 7 files changed, 27 insertions(+), 29 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 38bd1d80..f3c84771 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -58,9 +58,7 @@ bindir = $(exec_prefix)/sbin + multipathdir = $(TOPDIR)/libmultipath + daemondir = $(TOPDIR)/multipathd + mpathutildir = $(TOPDIR)/libmpathutil +-man8dir = $(usr_prefix)/share/man/man8 +-man5dir = $(usr_prefix)/share/man/man5 +-man3dir = $(usr_prefix)/share/man/man3 ++mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) +diff --git a/kpartx/Makefile b/kpartx/Makefile +index bdf2d035..464925ad 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -32,12 +32,12 @@ install: $(EXEC) $(EXEC).8 + $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules + $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules + $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(RM) $(DESTDIR)$(libudevdir)/kpartx_id + $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules + $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index e4589250..985b694b 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -45,17 +45,17 @@ install: + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(man3dir) +- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(man3dir) docs/man/*.3 ++ $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 ++ $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 + + uninstall: + $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) + $(RM) $(DESTDIR)$(includedir)/$(HEADERS) + $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) +- @for file in $(DESTDIR)$(man3dir)/dmmp_*; do \ ++ @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ + $(RM) $$file; \ + done +- $(RM) $(DESTDIR)$(man3dir)/libdmmp.h* ++ $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* + $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + + clean: dep_clean +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 4e1717ef..479524d4 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -36,17 +36,17 @@ install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(man3dir) ++ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) + $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(man3dir) +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(man3dir) ++ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 ++ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 + $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) + + uninstall: + $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_in.3 +- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_out.3 ++ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 ++ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 + $(RM) $(DESTDIR)$(includedir)/mpath_persist.h + $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + +diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile +index 2219c86a..d62537b5 100644 +--- a/mpathpersist/Makefile ++++ b/mpathpersist/Makefile +@@ -19,8 +19,8 @@ $(EXEC): $(OBJS) + install: + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + clean: dep_clean + $(RM) core *.o $(EXEC) +@@ -29,7 +29,7 @@ include $(wildcard $(OBJS:.o=.d)) + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + + dep_clean: + $(RM) $(OBJS:.o=.d) +diff --git a/multipath/Makefile b/multipath/Makefile +index 116348e2..1c4e7a52 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -28,10 +28,10 @@ install: + $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf + $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) + $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 + ifneq ($(SCSI_DH_MODULES_PRELOAD),) + $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ +@@ -44,8 +44,8 @@ uninstall: + $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 +- $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + + clean: dep_clean + $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf +diff --git a/multipathd/Makefile b/multipathd/Makefile +index c462d7b1..78aefee0 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -89,14 +89,14 @@ ifdef SYSTEMD + $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) + endif +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) +- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(man8dir) ++ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) +- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 +- $(RM) $(DESTDIR)$(man8dir)/$(CLI).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 + $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service + $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket + diff --git a/0008-multipath-tools-add-ALUA-info-to-README.md.patch b/0008-multipath-tools-add-ALUA-info-to-README.md.patch deleted file mode 100644 index 2a11fce..0000000 --- a/0008-multipath-tools-add-ALUA-info-to-README.md.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 14 Jul 2022 23:14:31 +0200 -Subject: [PATCH] multipath-tools: add ALUA info to README.md - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/README.md b/README.md -index dcf51f20..2322082c 100644 ---- a/README.md -+++ b/README.md -@@ -146,3 +146,31 @@ The multipath-tools source code is covered by several different licences. - Refer to the individual source files for details. - Source files which do not specify a licence are shipped under LGPL-2.0 - (see `LICENSES/LGPL-2.0`). -+ -+ -+ALUA -+==== -+This is a rough guide, consult your storage device manufacturer documentation. -+ -+ALUA is supported in some devices, but usually it's disabled by default. -+To enable ALUA, the following options should be changed: -+ -+- EMC CLARiiON/VNX: -+ "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" -+ -+- HPE 3PAR, Primera, and Alletra 9000: -+ "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". -+ -+- Promise VTrak/Vess: -+ "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" -+ must be "Active-Active". -+ -+- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: -+ "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". -+ -+- NetApp ONTAP: -+ To check ALUA state: "igroup show -v ", and to enable ALUA: -+ "igroup set alua yes". -+ -+- Huawei OceanStor: -+ "Host Access Mode" should be changed to "Asymmetric". diff --git a/0009-libmultipath-alua-remove-get_sysfs_pg83.patch b/0009-libmultipath-alua-remove-get_sysfs_pg83.patch deleted file mode 100644 index 4aa92fc..0000000 --- a/0009-libmultipath-alua-remove-get_sysfs_pg83.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Jul 2022 15:57:21 +0200 -Subject: [PATCH] libmultipath: alua: remove get_sysfs_pg83() - -Since b72e753 ("libmultipath: alua: try to retrieve inquiry data from sysfs"), -we fetch inquiry and VPD data from sysfs anyway. No need to do this twice. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/prioritizers/alua_rtpg.c | 57 ++++++++------------------- - 1 file changed, 16 insertions(+), 41 deletions(-) - -diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c -index 3f9c0e73..4db13c20 100644 ---- a/libmultipath/prioritizers/alua_rtpg.c -+++ b/libmultipath/prioritizers/alua_rtpg.c -@@ -228,25 +228,6 @@ get_target_port_group_support(const struct path *pp, unsigned int timeout) - return rc; - } - --static int --get_sysfs_pg83(const struct path *pp, unsigned char *buff, int buflen) --{ -- struct udev_device *parent = pp->udev; -- -- while (parent) { -- const char *subsys = udev_device_get_subsystem(parent); -- if (subsys && !strncmp(subsys, "scsi", 4)) -- break; -- parent = udev_device_get_parent(parent); -- } -- -- if (!parent || sysfs_get_vpd(parent, 0x83, buff, buflen) <= 0) { -- PRINT_DEBUG("failed to read sysfs vpd pg83"); -- return -1; -- } -- return 0; --} -- - int - get_target_port_group(const struct path * pp, unsigned int timeout) - { -@@ -265,32 +246,26 @@ get_target_port_group(const struct path * pp, unsigned int timeout) - } - - memset(buf, 0, buflen); -+ rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); -+ if (rc < 0) -+ goto out; - -- rc = get_sysfs_pg83(pp, buf, buflen); -- -- if (rc < 0) { -+ scsi_buflen = get_unaligned_be16(&buf[2]) + 4; -+ if (scsi_buflen >= USHRT_MAX) -+ scsi_buflen = USHRT_MAX; -+ if (buflen < scsi_buflen) { -+ free(buf); -+ buf = (unsigned char *)malloc(scsi_buflen); -+ if (!buf) { -+ PRINT_DEBUG("malloc failed: could not allocate" -+ "%u bytes", scsi_buflen); -+ return -RTPG_RTPG_FAILED; -+ } -+ buflen = scsi_buflen; -+ memset(buf, 0, buflen); - rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); - if (rc < 0) - goto out; -- -- scsi_buflen = get_unaligned_be16(&buf[2]) + 4; -- /* Paranoia */ -- if (scsi_buflen >= USHRT_MAX) -- scsi_buflen = USHRT_MAX; -- if (buflen < scsi_buflen) { -- free(buf); -- buf = (unsigned char *)malloc(scsi_buflen); -- if (!buf) { -- PRINT_DEBUG("malloc failed: could not allocate" -- "%u bytes", scsi_buflen); -- return -RTPG_RTPG_FAILED; -- } -- buflen = scsi_buflen; -- memset(buf, 0, buflen); -- rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); -- if (rc < 0) -- goto out; -- } - } - - vpd83 = (struct vpd83_data *) buf; diff --git a/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch b/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch new file mode 100644 index 0000000..9b0dbc5 --- /dev/null +++ b/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:34:34 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: simplify expression for + SYSTEMD + +Use a shell "or" function here. Note the use of "strip" to remove +the whitespace that are caused by the line break. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index f3c84771..1a08b8fa 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -28,14 +28,8 @@ ifeq ($(TOPDIR),) + TOPDIR = .. + endif + +-ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') +-else +- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) +- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ +- sed -n 's/systemd \([0-9]*\).*/\1/p') +- endif +-endif ++SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ ++ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) + + # Allow user to override default location. + diff --git a/0010-libmultipath-remove-sysfs_get_binary.patch b/0010-libmultipath-remove-sysfs_get_binary.patch deleted file mode 100644 index c2661ed..0000000 --- a/0010-libmultipath-remove-sysfs_get_binary.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 10:54:02 +0200 -Subject: [PATCH] libmultipath: remove sysfs_get_binary() - -This function adds no value on top of sysfs_bin_attr_get_value(). -Remove it. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 26 ++------------------------ - tests/test-lib.c | 1 - - 2 files changed, 2 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 0d8a558c..7e09e4e2 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -263,41 +263,19 @@ declare_sysfs_get_str(vendor); - declare_sysfs_get_str(model); - declare_sysfs_get_str(rev); - --static ssize_t --sysfs_get_binary (struct udev_device * udev, const char *attrname, -- unsigned char *buff, size_t len) --{ -- ssize_t attr_len; -- const char * devname; -- -- if (!udev) { -- condlog(3, "No udev device given\n"); -- return -ENOSYS; -- } -- -- devname = udev_device_get_sysname(udev); -- attr_len = sysfs_bin_attr_get_value(udev, attrname, buff, len); -- if (attr_len < 0) { -- condlog(3, "%s: attribute %s not found in sysfs", -- devname, attrname); -- return attr_len; -- } -- return attr_len; --} -- - ssize_t sysfs_get_vpd(struct udev_device * udev, unsigned char pg, - unsigned char *buff, size_t len) - { - char attrname[9]; - - snprintf(attrname, sizeof(attrname), "vpd_pg%02x", pg); -- return sysfs_get_binary(udev, attrname, buff, len); -+ return sysfs_bin_attr_get_value(udev, attrname, buff, len); - } - - ssize_t sysfs_get_inquiry(struct udev_device * udev, - unsigned char *buff, size_t len) - { -- return sysfs_get_binary(udev, "inquiry", buff, len); -+ return sysfs_bin_attr_get_value(udev, "inquiry", buff, len); - } - - int -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 6dd3ee88..0bc49d53 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -334,7 +334,6 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) - if (mask & DI_SERIAL) { - will_return(__wrap_udev_device_get_subsystem, "scsi"); - will_return(__wrap_udev_device_get_sysname, hbtl); -- will_return(__wrap_udev_device_get_sysname, hbtl); - } - - if (mask & DI_WWID) { diff --git a/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch b/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch new file mode 100644 index 0000000..8591ac4 --- /dev/null +++ b/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:53:04 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: untangle paths and source + directories + +Only the installation paths can be customized. Move the definitions +of $(multipathdir) etc. further down. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 1a08b8fa..6ec8201b 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -31,8 +31,6 @@ endif + SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ + $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) + +-# Allow user to override default location. +- + # Paths. All these can be overridden on the "make" command line. + prefix = + # Prefix for binaries +@@ -49,20 +47,11 @@ modulesloaddir := $(systemd_prefix)/lib/modules-load.d + libudevdir := $(systemd_prefix)/lib/udev + udevrulesdir := $(libudevdir)/rules.d + bindir = $(exec_prefix)/sbin +-multipathdir = $(TOPDIR)/libmultipath +-daemondir = $(TOPDIR)/multipathd +-mpathutildir = $(TOPDIR)/libmpathutil + mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) + libdir = $(prefix)/$(LIB)/multipath +-mpathpersistdir = $(TOPDIR)/libmpathpersist +-mpathcmddir = $(TOPDIR)/libmpathcmd +-mpathvaliddir = $(TOPDIR)/libmpathvalid +-thirdpartydir = $(TOPDIR)/third-party +-libdmmpdir = $(TOPDIR)/libdmmp +-nvmedir = $(TOPDIR)/libmultipath/nvme + includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath +@@ -124,6 +113,18 @@ SHARED_FLAGS = -shared + LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs + BIN_LDFLAGS = -pie + ++# Source code directories. Don't modify. ++ ++multipathdir = $(TOPDIR)/libmultipath ++daemondir = $(TOPDIR)/multipathd ++mpathutildir = $(TOPDIR)/libmpathutil ++mpathpersistdir = $(TOPDIR)/libmpathpersist ++mpathcmddir = $(TOPDIR)/libmpathcmd ++mpathvaliddir = $(TOPDIR)/libmpathvalid ++thirdpartydir = $(TOPDIR)/third-party ++libdmmpdir = $(TOPDIR)/libdmmp ++nvmedir = $(TOPDIR)/libmultipath/nvme ++ + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ + if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ diff --git a/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch b/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch deleted file mode 100644 index 787d230..0000000 --- a/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 10:47:51 +0200 -Subject: [PATCH] libmultipath: sysfs_bin_attr_get_value(): no error if buffer - is filled - -sysfs_bin_attr_get_value() sets the length of bytes read to 0 -when the provided buffer was too small, truncating potentially -useful data. This is harmful e.g. in do_inquiry(), if the "inquiry" -sysfs attribute contains more than 96 bytes (which is possible). - -Actually, binary attributes don't need to be 0-terminated. Thus, -unlike for string attributes, it's not an error if the requested number of -bytes is exactly equal to the number of bytes read. We expect that -the caller knows how many bytes it needs to read. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 10 ++++++---- - libmultipath/sysfs.c | 5 +---- - 2 files changed, 7 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 7e09e4e2..f5b8401c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1341,13 +1341,15 @@ static int - get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) - { - int len; -- size_t buff_len; -+ ssize_t buff_len; - unsigned char buff[VPD_BUFLEN]; - - memset(buff, 0x0, VPD_BUFLEN); -- if (!parent || sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN) <= 0) { -- condlog(3, "failed to read sysfs vpd pg%02x", pg); -- return -EINVAL; -+ buff_len = sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN); -+ if (buff_len < 0) { -+ condlog(3, "failed to read sysfs vpd pg%02x: %s", -+ pg, strerror(-buff_len)); -+ return buff_len; - } - - if (buff[1] != pg) { -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index f45dbee1..3ec92512 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -146,10 +146,7 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - if (size < 0) { - condlog(4, "read from %s failed: %s", devpath, strerror(errno)); - size = -errno; -- } else if (size == (ssize_t)value_len) { -- condlog(4, "overflow while reading from %s", devpath); -- size = 0; -- } -+ }; - - close(fd); - return size; diff --git a/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch b/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch new file mode 100644 index 0000000..82c63d1 --- /dev/null +++ b/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:17:00 +0200 +Subject: [PATCH] multipath-tools: Makefiles: replace $(libdir) by $(plugindir) + +The make variables $(libdir) and $(plugindir) are redundant. +I overlooked that in af15832 ("multipath-tools: make multipath_dir a +compiled-in option"). While libdir has existed longer, I think +plugindir describes better what this path is used for, so replace +libdir by plugindir. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 1 - + libmpathutil/Makefile | 1 - + libmultipath/Makefile | 2 +- + libmultipath/checkers/Makefile | 4 ++-- + libmultipath/foreign/Makefile | 4 ++-- + libmultipath/prioritizers/Makefile | 4 ++-- + 6 files changed, 7 insertions(+), 9 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 6ec8201b..17707a3e 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -51,7 +51,6 @@ mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) + syslibdir = $(prefix)/$(LIB) + usrlibdir = $(usr_prefix)/$(LIB) +-libdir = $(prefix)/$(LIB)/multipath + includedir = $(usr_prefix)/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 68b1c7d6..c913c761 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -54,7 +54,6 @@ abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) + $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index f0df27c0..c7d4fc99 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -119,7 +119,7 @@ test-lib: ../tests/$(LIBS) + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) + $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index c9a2c4ca..39ad76e0 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -25,10 +25,10 @@ libcheck%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done ++ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile +index d0232f20..8bf9047b 100644 +--- a/libmultipath/foreign/Makefile ++++ b/libmultipath/foreign/Makefile +@@ -17,10 +17,10 @@ libforeign-%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done ++ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 97155f51..72eefe49 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -37,10 +37,10 @@ libprio%.so: %.o + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: $(LIBS) +- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) ++ $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done ++ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(RM) core *.a *.o *.gz *.so diff --git a/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch b/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch deleted file mode 100644 index d09cd8a..0000000 --- a/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 11:14:30 +0200 -Subject: [PATCH] libmultipath: common code path for sysfs_attr_get_value() - -The code for sysfs_attr_get_value and sysfs_bin_attr_get_value() was -almost identical. Use a common code path. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 70 +++++++++++--------------------------------- - 1 file changed, 17 insertions(+), 53 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 3ec92512..4db911cc 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -44,8 +44,8 @@ - * as libudev lacks the capability to update an attribute value. - * So for modified attributes we need to implement our own function. - */ --ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, -- char * value, size_t value_len) -+static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, -+ char *value, size_t value_len, bool binary) - { - char devpath[PATH_SIZE]; - struct stat statbuf; -@@ -87,12 +87,14 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - if (size < 0) { - condlog(4, "read from %s failed: %s", devpath, strerror(errno)); - size = -errno; -- value[0] = '\0'; -- } else if (size == (ssize_t)value_len) { -+ if (!binary) -+ value[0] = '\0'; -+ } else if (!binary && size == (ssize_t)value_len) { -+ condlog(3, "%s: overflow reading from %s (required len: %zu)", -+ __func__, devpath, size); - value[size - 1] = '\0'; -- condlog(4, "overflow while reading from %s", devpath); - size = 0; -- } else { -+ } else if (!binary) { - value[size] = '\0'; - size = strchop(value); - } -@@ -101,55 +103,17 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - return size; - } - --ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, -- unsigned char * value, size_t value_len) -+ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, -+ char *value, size_t value_len) - { -- char devpath[PATH_SIZE]; -- struct stat statbuf; -- int fd; -- ssize_t size = -1; -- -- if (!dev || !attr_name || !value) -- return 0; -- -- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), -- attr_name); -- condlog(4, "open '%s'", devpath); -- /* read attribute value */ -- fd = open(devpath, O_RDONLY); -- if (fd < 0) { -- condlog(4, "attribute '%s' can not be opened: %s", -- devpath, strerror(errno)); -- return -errno; -- } -- if (fstat(fd, &statbuf) != 0) { -- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); -- close(fd); -- return -ENXIO; -- } -- -- /* skip directories */ -- if (S_ISDIR(statbuf.st_mode)) { -- condlog(4, "%s is a directory", devpath); -- close(fd); -- return -EISDIR; -- } -- -- /* skip non-writeable files */ -- if ((statbuf.st_mode & S_IRUSR) == 0) { -- condlog(4, "%s is not readable", devpath); -- close(fd); -- return -EPERM; -- } -- -- size = read(fd, value, value_len); -- if (size < 0) { -- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); -- size = -errno; -- }; -+ return __sysfs_attr_get_value(dev, attr_name, value, value_len, false); -+} - -- close(fd); -- return size; -+ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, -+ unsigned char *value, size_t value_len) -+{ -+ return __sysfs_attr_get_value(dev, attr_name, (char *)value, -+ value_len, true); - } - - ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, diff --git a/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch b/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch new file mode 100644 index 0000000..16cca1e --- /dev/null +++ b/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:35:48 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: use simple make variables + consistently + +"Simply expanded" make variables are generally preferred over "recursively +expanded" make variables, unless they reference other variables that are +defined over overwritten further down in the Makefile (see +https://www.gnu.org/software/make/manual/html_node/Flavors.html). +Using them makes the code easier to read and even somewhat faster. + +We've been adding simply expanded variables over time, but most older +code still uses recursively expanded ones. Try to be consistent, at least +in Makefile.inc. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 50 +++++++++++++++++++++++++------------------------- + 1 file changed, 25 insertions(+), 25 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 17707a3e..86602e2a 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -32,11 +32,11 @@ SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null + $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) + + # Paths. All these can be overridden on the "make" command line. +-prefix = ++prefix := + # Prefix for binaries +-exec_prefix = $(prefix) ++exec_prefix := $(prefix) + # Prefix for non-essential libraries (libdmmp) +-usr_prefix = $(prefix) ++usr_prefix := $(prefix) + # Where to install systemd-related files. systemd is usually installed under /usr + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) +@@ -46,13 +46,13 @@ tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d + modulesloaddir := $(systemd_prefix)/lib/modules-load.d + libudevdir := $(systemd_prefix)/lib/udev + udevrulesdir := $(libudevdir)/rules.d +-bindir = $(exec_prefix)/sbin ++bindir := $(exec_prefix)/sbin + mandir := $(usr_prefix)/share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) +-syslibdir = $(prefix)/$(LIB) +-usrlibdir = $(usr_prefix)/$(LIB) +-includedir = $(usr_prefix)/include +-pkgconfdir = $(usrlibdir)/pkgconfig ++syslibdir := $(prefix)/$(LIB) ++usrlibdir := $(usr_prefix)/$(LIB) ++includedir := $(usr_prefix)/include ++pkgconfdir := $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) +@@ -60,10 +60,10 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ + libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) + kernel_incdir := /usr/include + +-GZIP_PROG = gzip -9 -c +-RM = rm -f +-LN = ln -sf +-INSTALL_PROGRAM = install ++GZIP_PROG := gzip -9 -c ++RM := rm -f ++LN := ln -sf ++INSTALL_PROGRAM := install + NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) + + # $(call TEST_CC_OPTION,option,fallback) +@@ -106,23 +106,23 @@ CPPFLAGS := $(FORTIFY_OPT) \ + -DRUNTIME_DIR=\"$(runtimedir)\" \ + -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +-BIN_CFLAGS = -fPIE -DPIE +-LIB_CFLAGS = -fPIC +-SHARED_FLAGS = -shared ++BIN_CFLAGS := -fPIE -DPIE ++LIB_CFLAGS := -fPIC ++SHARED_FLAGS := -shared + LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs +-BIN_LDFLAGS = -pie ++BIN_LDFLAGS := -pie + + # Source code directories. Don't modify. + +-multipathdir = $(TOPDIR)/libmultipath +-daemondir = $(TOPDIR)/multipathd +-mpathutildir = $(TOPDIR)/libmpathutil +-mpathpersistdir = $(TOPDIR)/libmpathpersist +-mpathcmddir = $(TOPDIR)/libmpathcmd +-mpathvaliddir = $(TOPDIR)/libmpathvalid +-thirdpartydir = $(TOPDIR)/third-party +-libdmmpdir = $(TOPDIR)/libdmmp +-nvmedir = $(TOPDIR)/libmultipath/nvme ++multipathdir := $(TOPDIR)/libmultipath ++daemondir := $(TOPDIR)/multipathd ++mpathutildir := $(TOPDIR)/libmpathutil ++mpathpersistdir := $(TOPDIR)/libmpathpersist ++mpathcmddir := $(TOPDIR)/libmpathcmd ++mpathvaliddir := $(TOPDIR)/libmpathvalid ++thirdpartydir := $(TOPDIR)/third-party ++libdmmpdir := $(TOPDIR)/libdmmp ++nvmedir := $(TOPDIR)/libmultipath/nvme + + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ diff --git a/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch b/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch deleted file mode 100644 index 9dc3dc5..0000000 --- a/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 11:41:40 +0200 -Subject: [PATCH] libmultipath: sanitize error checking in sysfs accessors - -udev_device_get_syspath() may return NULL; check for it, and check -for pathname overflow. Disallow a zero buffer length. The fstat() -calls were superfluous, as a read() or write() on the fd would -return the respective error codes depending on file type or permissions, -the extra system call and code complexity adds no value. - -Log levels should be moderate in sysfs.c, because it depends -on the caller whether errors getting/setting certain attributes are -fatal. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 94 ++++++++++++++++++-------------------------- - 1 file changed, 39 insertions(+), 55 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 4db911cc..1f0f2074 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -47,46 +47,38 @@ - static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - char *value, size_t value_len, bool binary) - { -+ const char *syspath; - char devpath[PATH_SIZE]; -- struct stat statbuf; - int fd; - ssize_t size = -1; - -- if (!dev || !attr_name || !value) -- return 0; -+ if (!dev || !attr_name || !value || !value_len) { -+ condlog(1, "%s: invalid parameters", __func__); -+ return -EINVAL; -+ } - -- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), -- attr_name); -+ syspath = udev_device_get_syspath(dev); -+ if (!syspath) { -+ condlog(3, "%s: invalid udevice", __func__); -+ return -EINVAL; -+ } -+ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { -+ condlog(3, "%s: devpath overflow", __func__); -+ return -EOVERFLOW; -+ } - condlog(4, "open '%s'", devpath); - /* read attribute value */ - fd = open(devpath, O_RDONLY); - if (fd < 0) { -- condlog(4, "attribute '%s' can not be opened: %s", -- devpath, strerror(errno)); -+ condlog(3, "%s: attribute '%s' can not be opened: %s", -+ __func__, devpath, strerror(errno)); - return -errno; - } -- if (fstat(fd, &statbuf) < 0) { -- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); -- close(fd); -- return -ENXIO; -- } -- /* skip directories */ -- if (S_ISDIR(statbuf.st_mode)) { -- condlog(4, "%s is a directory", devpath); -- close(fd); -- return -EISDIR; -- } -- /* skip non-writeable files */ -- if ((statbuf.st_mode & S_IRUSR) == 0) { -- condlog(4, "%s is not readable", devpath); -- close(fd); -- return -EPERM; -- } -- - size = read(fd, value, value_len); - if (size < 0) { -- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); - size = -errno; -+ condlog(3, "%s: read from %s failed: %s", __func__, devpath, -+ strerror(errno)); - if (!binary) - value[0] = '\0'; - } else if (!binary && size == (ssize_t)value_len) { -@@ -119,51 +111,43 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - const char * value, size_t value_len) - { -+ const char *syspath; - char devpath[PATH_SIZE]; -- struct stat statbuf; - int fd; - ssize_t size = -1; - -- if (!dev || !attr_name || !value || !value_len) -- return 0; -+ if (!dev || !attr_name || !value || !value_len) { -+ condlog(1, "%s: invalid parameters", __func__); -+ return -EINVAL; -+ } -+ -+ syspath = udev_device_get_syspath(dev); -+ if (!syspath) { -+ condlog(3, "%s: invalid udevice", __func__); -+ return -EINVAL; -+ } -+ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { -+ condlog(3, "%s: devpath overflow", __func__); -+ return -EOVERFLOW; -+ } - -- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), -- attr_name); - condlog(4, "open '%s'", devpath); - /* write attribute value */ - fd = open(devpath, O_WRONLY); - if (fd < 0) { -- condlog(4, "attribute '%s' can not be opened: %s", -- devpath, strerror(errno)); -- return -errno; -- } -- if (fstat(fd, &statbuf) != 0) { -- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); -- close(fd); -+ condlog(2, "%s: attribute '%s' can not be opened: %s", -+ __func__, devpath, strerror(errno)); - return -errno; - } - -- /* skip directories */ -- if (S_ISDIR(statbuf.st_mode)) { -- condlog(4, "%s is a directory", devpath); -- close(fd); -- return -EISDIR; -- } -- -- /* skip non-writeable files */ -- if ((statbuf.st_mode & S_IWUSR) == 0) { -- condlog(4, "%s is not writeable", devpath); -- close(fd); -- return -EPERM; -- } -- - size = write(fd, value, value_len); - if (size < 0) { -- condlog(4, "write to %s failed: %s", devpath, strerror(errno)); - size = -errno; -+ condlog(3, "%s: write to %s failed: %s", __func__, -+ devpath, strerror(errno)); - } else if (size < (ssize_t)value_len) { -- condlog(4, "tried to write %ld to %s. Wrote %ld", -- (long)value_len, devpath, (long)size); -+ condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", -+ __func__, value_len, devpath, size); - size = 0; - } - diff --git a/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch b/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch new file mode 100644 index 0000000..3e424dc --- /dev/null +++ b/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 17:40:30 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: fix a log message + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 86602e2a..77790ddf 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -159,7 +159,7 @@ check_var = $(shell \ + found=0; \ + status="no"; \ + fi; \ +- echo 1>&2 "Checking for .. $1 in $2 ... $$status"; \ ++ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ + echo "$$found" \ + ) + diff --git a/0014-libmultipath-get-rid-of-PATH_SIZE.patch b/0014-libmultipath-get-rid-of-PATH_SIZE.patch deleted file mode 100644 index a080792..0000000 --- a/0014-libmultipath-get-rid-of-PATH_SIZE.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 11:52:42 +0200 -Subject: [PATCH] libmultipath: get rid of PATH_SIZE - -replace PATH_SIZE with the system limit PATH_MAX. In some places, -PATH_SIZE was used for file names. Use FILE_NAME_SIZE in these cases. -Also, use a constant for "multipathd.service" in systemd_service_enabled_in(). - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.h | 3 --- - libmultipath/sysfs.c | 8 ++++---- - libmultipath/util.c | 8 +++++--- - multipathd/cli_handlers.c | 2 +- - 4 files changed, 10 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a6a09441..dfa12ff9 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -17,7 +17,6 @@ - #define FILE_NAME_SIZE 256 - #define CALLOUT_MAX_SIZE 256 - #define BLK_DEV_SIZE 33 --#define PATH_SIZE 512 - #define NAME_SIZE 512 - #define HOST_NAME_LEN 16 - #define SLOT_NAME_SIZE 40 -@@ -519,6 +518,4 @@ int pathcmp (const struct pathgroup *, const struct pathgroup *); - int add_feature (char **, const char *); - int remove_feature (char **, const char *); - --extern char sysfs_path[PATH_SIZE]; -- - #endif /* _STRUCTS_H */ -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 1f0f2074..e48b05ec 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -48,7 +48,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - char *value, size_t value_len, bool binary) - { - const char *syspath; -- char devpath[PATH_SIZE]; -+ char devpath[PATH_MAX]; - int fd; - ssize_t size = -1; - -@@ -112,7 +112,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - const char * value, size_t value_len) - { - const char *syspath; -- char devpath[PATH_SIZE]; -+ char devpath[PATH_MAX]; - int fd; - ssize_t size = -1; - -@@ -184,7 +184,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) - int sysfs_check_holders(char * check_devt, char * new_devt) - { - unsigned int major, new_minor, table_minor; -- char path[PATH_MAX], check_dev[PATH_SIZE]; -+ char path[PATH_MAX], check_dev[FILE_NAME_SIZE]; - char * table_name; - DIR *dirfd; - struct dirent *holder; -@@ -194,7 +194,7 @@ int sysfs_check_holders(char * check_devt, char * new_devt) - return 0; - } - -- if (devt2devname(check_dev, PATH_SIZE, check_devt)) { -+ if (devt2devname(check_dev, sizeof(check_dev), check_devt)) { - condlog(1, "can't get devname for %s", check_devt); - return 0; - } -diff --git a/libmultipath/util.c b/libmultipath/util.c -index ce5ea73e..e7e7d4c1 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -242,13 +242,15 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached) - - int systemd_service_enabled_in(const char *dev, const char *prefix) - { -- char path[PATH_SIZE], file[PATH_MAX], service[PATH_SIZE]; -+ static const char service[] = "multipathd.service"; -+ char path[PATH_MAX], file[PATH_MAX]; - DIR *dirfd; - struct dirent *d; - int found = 0; - -- snprintf(service, PATH_SIZE, "multipathd.service"); -- snprintf(path, PATH_SIZE, "%s/systemd/system", prefix); -+ if (safe_sprintf(path, "%s/systemd/system", prefix)) -+ return 0; -+ - condlog(3, "%s: checking for %s in %s", dev, service, path); - - dirfd = opendir(path); -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index d79cdd7c..db4d4412 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -688,7 +688,7 @@ cli_add_map (void * v, struct strbuf *reply, void * data) - struct vectors * vecs = (struct vectors *)data; - char * param = get_keyparam(v, MAP); - int major = -1, minor = -1; -- char dev_path[PATH_SIZE]; -+ char dev_path[FILE_NAME_SIZE]; - char *refwwid, *alias = NULL; - int rc, count = 0; - struct config *conf; diff --git a/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch b/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch new file mode 100644 index 0000000..fa37b7c --- /dev/null +++ b/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 16:40:27 +0200 +Subject: [PATCH] multipath-tools: Makefile.inc: set systemd-specific flags + +Define SYSTEMD_CPPFLAGS and SYSTEMD_LIBDEPS, and use them in Makefiles. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 3 +++ + libmpathutil/Makefile | 13 ++----------- + libmultipath/Makefile | 14 +++----------- + multipathd/Makefile | 25 ++++++++----------------- + 4 files changed, 16 insertions(+), 39 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 77790ddf..2cf25745 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -97,6 +97,9 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) + ++SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) ++SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) ++ + OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 + WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index c913c761..4be75d2d 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -8,19 +8,10 @@ DEVLIB = libmpathutil.so + LIBS = $(DEVLIB).$(SONAME) + VERSION_SCRIPT := libmpathutil.version + +-CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) ++CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE + +-LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd +- +-ifdef SYSTEMD +- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) +- LIBDEPS += -lsystemd +- else +- LIBDEPS += -lsystemd-daemon +- endif +-endif ++LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) + + # object files referencing MULTIPATH_DIR or CONFIG_DIR + # they need to be recompiled for unit tests +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index c7d4fc99..009f26a3 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -8,19 +8,11 @@ DEVLIB = libmultipath.so + LIBS = $(DEVLIB).$(SONAME) + VERSION_SCRIPT := libmultipath.version + +-CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE ++CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) + +-LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lurcu -laio +- +-ifdef SYSTEMD +- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) +- LIBDEPS += -lsystemd +- else +- LIBDEPS += -lsystemd-daemon +- endif +-endif ++LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ ++ -lurcu -laio $(SYSTEMD_LIBDEPS) + + ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_FLUSH +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 78aefee0..cdda371b 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -18,14 +18,17 @@ endif + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ + $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ + awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ +- -DBINDIR='"$(bindir)"' ++ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) ++ifeq ($(ENABLE_DMEVENTS_POLL),0) ++ CPPFLAGS += -DNO_DMEVENTS_POLL ++endif + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + +-CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread +-LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ +- -ldevmapper $(CLI_LIBDEPS) +- ++CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ ++ -ludev -ldl -lurcu -lpthread $(SYSTEMD_LIBDEPS) ++LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ ++ -ldevmapper $(CLI_LIBDEPS) + + ifeq ($(READLINE),libedit) + RL_CPPFLAGS = -DUSE_LIBEDIT +@@ -40,18 +43,6 @@ RL_CPPFLAGS += -DBROKEN_RL_COMPLETION_FUNC + endif + endif + +-ifdef SYSTEMD +- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) +- CLI_LIBDEPS += -lsystemd +- else +- CLI_LIBDEPS += -lsystemd-daemon +- endif +-endif +-ifeq ($(ENABLE_DMEVENTS_POLL),0) +- CPPFLAGS += -DNO_DMEVENTS_POLL +-endif +- + OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ + dmevents.o init_unwinder.o + diff --git a/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch b/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch deleted file mode 100644 index d58b785..0000000 --- a/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 13:33:51 +0200 -Subject: [PATCH] libmultipath: sysfs_attr_get_value(): don't return 0 if - buffer too small - -If the passed read buffer is too small to hold the value read plus -terminating 0 byte, return the given size value rather than 0. - -This way we get similar semantics as for sysfs_bin_attr_get_get_value(), -except that sysfs_attr_get_value() must always 0-terminate the value; -thus a return value equal to the length parameter is an error for -the non-binary case. - -Provide a helper macro to test this "overflow" condition. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 2 +- - libmultipath/discovery.c | 14 +++++++------- - libmultipath/propsel.c | 6 +++++- - libmultipath/sysfs.c | 3 +-- - libmultipath/sysfs.h | 13 +++++++++++++ - multipathd/main.c | 2 +- - 6 files changed, 28 insertions(+), 12 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 09ae708d..467bbaa6 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -589,7 +589,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, - sizeof(buff)); - udev_device_unref(udd); -- if (ret <= 0) { -+ if (!sysfs_attr_value_ok(ret, sizeof(buff))) { - condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); - return 1; - } -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f5b8401c..54b1caf0 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -560,10 +560,10 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) - if (!parent) - return -1; - -- if (sysfs_attr_get_value(parent, "access_state", buff, buflen) <= 0) -+ if (!sysfs_attr_get_value_ok(parent, "access_state", buff, buflen)) - return -1; - -- if (sysfs_attr_get_value(parent, "preferred_path", value, 16) <= 0) -+ if (!sysfs_attr_get_value_ok(parent, "preferred_path", value, sizeof(value))) - return 0; - - preferred = strtoul(value, &eptr, 0); -@@ -638,8 +638,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - /* - * read the current dev_loss_tmo value from sysfs - */ -- ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, 16); -- if (ret <= 0) { -+ ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, sizeof(value)); -+ if (!sysfs_attr_value_ok(ret, sizeof(value))) { - condlog(0, "%s: failed to read dev_loss_tmo value, " - "error %d", rport_id, -ret); - goto out; -@@ -1737,8 +1737,8 @@ path_offline (struct path * pp) - } - - memset(buff, 0x0, SCSI_STATE_SIZE); -- err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE); -- if (err <= 0) { -+ err = sysfs_attr_get_value(parent, "state", buff, sizeof(buff)); -+ if (!sysfs_attr_value_ok(err, sizeof(buff))) { - if (err == -ENXIO) - return PATH_REMOVED; - else -@@ -2142,7 +2142,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, - return -1; - len = sysfs_attr_get_value(pp->udev, "wwid", value, - sizeof(value)); -- if (len <= 0) -+ if (!sysfs_attr_value_ok(len, sizeof(value))) - return -1; - len = strlcpy(pp->wwid, value, WWID_SIZE); - if (len >= WWID_SIZE) { -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index f782f251..98e3aad1 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -435,6 +435,7 @@ out: - static int get_dh_state(struct path *pp, char *value, size_t value_len) - { - struct udev_device *ud; -+ ssize_t rc; - - if (pp->udev == NULL) - return -1; -@@ -444,7 +445,10 @@ static int get_dh_state(struct path *pp, char *value, size_t value_len) - if (ud == NULL) - return -1; - -- return sysfs_attr_get_value(ud, "dh_state", value, value_len); -+ rc = sysfs_attr_get_value(ud, "dh_state", value, value_len); -+ if (!sysfs_attr_value_ok(rc, value_len)) -+ return -1; -+ return rc; - } - - int select_hwhandler(struct config *conf, struct multipath *mp) -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index e48b05ec..125f1c2b 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -85,7 +85,6 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - condlog(3, "%s: overflow reading from %s (required len: %zu)", - __func__, devpath, size); - value[size - 1] = '\0'; -- size = 0; - } else if (!binary) { - value[size] = '\0'; - size = strchop(value); -@@ -165,7 +164,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) - return 1; - - attr[0] = '\0'; -- if (sysfs_attr_get_value(pp->udev, "size", attr, 255) <= 0) { -+ if (!sysfs_attr_get_value_ok(pp->udev, "size", attr, sizeof(attr))) { - condlog(3, "%s: No size attribute in sysfs", pp->dev); - return 1; - } -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index 72b39ab2..cdc84e40 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -12,6 +12,19 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, - char * value, size_t value_len); - ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - unsigned char * value, size_t value_len); -+#define sysfs_attr_value_ok(rc, value_len) \ -+ ({ \ -+ ssize_t __r = rc; \ -+ __r >= 0 && (size_t)__r < (size_t)value_len; \ -+ }) -+ -+#define sysfs_attr_get_value_ok(dev, attr, val, len) \ -+ ({ \ -+ size_t __l = (len); \ -+ ssize_t __rc = sysfs_attr_get_value(dev, attr, val, __l); \ -+ sysfs_attr_value_ok(__rc, __l); \ -+ }) -+ - int sysfs_get_size (struct path *pp, unsigned long long * size); - int sysfs_check_holders(char * check_devt, char * new_devt); - bool sysfs_is_multipathed(struct path *pp, bool set_wwid); -diff --git a/multipathd/main.c b/multipathd/main.c -index 2f2b9d4c..68eca925 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1126,7 +1126,7 @@ sysfs_get_ro (struct path *pp) - if (!pp->udev) - return -1; - -- if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { -+ if (!sysfs_attr_get_value_ok(pp->udev, "ro", buff, sizeof(buff))) { - condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); - return -1; - } diff --git a/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch b/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch new file mode 100644 index 0000000..0013036 --- /dev/null +++ b/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 18:51:52 +0200 +Subject: [PATCH] multipathd: Makefile: fix compilation flags for libedit + +The workaround for the wrong prototype in older libedit versions +had ended up in the code for libreadline. Fix it, and use simple +make variables. + +Fixes: 2bd80f6 ("multipathd: fix incompatible pointer type error with libedit") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/Makefile | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/multipathd/Makefile b/multipathd/Makefile +index cdda371b..7221b6af 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -31,17 +31,17 @@ LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ + -ldevmapper $(CLI_LIBDEPS) + + ifeq ($(READLINE),libedit) +-RL_CPPFLAGS = -DUSE_LIBEDIT +-RL_LIBDEPS += -ledit +-endif +-ifeq ($(READLINE),libreadline) +-RL_CPPFLAGS += -DUSE_LIBREADLINE +-RL_LIBDEPS += -lreadline +-# See comment in uxclnt.c ++RL_CPPFLAGS := -DUSE_LIBEDIT ++RL_LIBDEPS := -ledit ++# See comment in multipathc.c + ifeq ($(shell sed -En 's/.*\ -Date: Tue, 5 Jul 2022 17:51:41 +0200 -Subject: [PATCH] libmultipath: sysfs_attr_set_value(): don't return 0 on - partial write - -sysfs_attr_set_value() returned 0 if not all requested bytes were written. -Change this to return the number of bytes written. Error checking is now -somewhat more involved; provide a helper macro for it. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 10 ++++-- - libmultipath/discovery.c | 74 +++++++++++++++++++++++++--------------- - libmultipath/sysfs.c | 6 ++-- - libmultipath/sysfs.h | 10 ++++++ - 4 files changed, 66 insertions(+), 34 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 467bbaa6..0607dbac 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -568,6 +568,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - struct pathgroup * pgp; - struct path *pp; - char buff[11]; -+ ssize_t len; - int i, j, ret, err = 0; - struct udev_device *udd; - int max_sectors_kb; -@@ -600,14 +601,17 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - } - } - snprintf(buff, 11, "%d", max_sectors_kb); -+ len = strlen(buff); - - vector_foreach_slot (mpp->pg, pgp, i) { - vector_foreach_slot(pgp->paths, pp, j) { - ret = sysfs_attr_set_value(pp->udev, - "queue/max_sectors_kb", -- buff, strlen(buff)); -- if (ret < 0) { -- condlog(1, "failed setting max_sectors_kb on %s : %s", pp->dev, strerror(-ret)); -+ buff, len); -+ if (ret != len) { -+ log_sysfs_attr_set_value(1, ret, -+ "failed setting max_sectors_kb on %s", -+ pp->dev); - err = 1; - } - } -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 54b1caf0..ee290093 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -598,13 +598,15 @@ sysfs_set_eh_deadline(struct path *pp) - len = sprintf(value, "%d", pp->eh_deadline); - - ret = sysfs_attr_set_value(hostdev, "eh_deadline", -- value, len + 1); -+ value, len); - /* - * not all scsi drivers support setting eh_deadline, so failing - * is totally reasonable - */ -- if (ret <= 0) -- condlog(3, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "%s: failed to set eh_deadline to %s", -+ udev_device_get_sysname(hostdev), value); - - udev_device_unref(hostdev); - return (ret <= 0); -@@ -667,19 +669,22 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - pp->fast_io_fail != MP_FAST_IO_FAIL_OFF) { - /* Check if we need to temporarily increase dev_loss_tmo */ - if ((unsigned int)pp->fast_io_fail >= tmo) { -+ ssize_t len; -+ - /* Increase dev_loss_tmo temporarily */ - snprintf(value, sizeof(value), "%u", - (unsigned int)pp->fast_io_fail + 1); -+ len = strlen(value); - ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", -- value, strlen(value)); -- if (ret <= 0) { -+ value, len); -+ if (ret != len) { - if (ret == -EBUSY) - condlog(3, "%s: rport blocked", - rport_id); - else -- condlog(0, "%s: failed to set " -- "dev_loss_tmo to %s, error %d", -- rport_id, value, -ret); -+ log_sysfs_attr_set_value(0, ret, -+ "%s: failed to set dev_loss_tmo to %s", -+ rport_id, value); - goto out; - } - } -@@ -691,32 +696,39 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - pp->dev_loss = DEFAULT_DEV_LOSS_TMO; - } - if (pp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -+ ssize_t len; -+ - if (pp->fast_io_fail == MP_FAST_IO_FAIL_OFF) - sprintf(value, "off"); - else if (pp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) - sprintf(value, "0"); - else - snprintf(value, 16, "%u", pp->fast_io_fail); -+ len = strlen(value); - ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo", -- value, strlen(value)); -- if (ret <= 0) { -+ value, len); -+ if (ret != len) { - if (ret == -EBUSY) - condlog(3, "%s: rport blocked", rport_id); - else -- condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d", -- rport_id, value, -ret); -+ log_sysfs_attr_set_value(0, ret, -+ "%s: failed to set fast_io_fail_tmo to %s", -+ rport_id, value); - } - } - if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { -+ ssize_t len; -+ - snprintf(value, 16, "%u", pp->dev_loss); -- ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", -- value, strlen(value)); -- if (ret <= 0) { -+ len = strlen(value); -+ ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, len); -+ if (ret != len) { - if (ret == -EBUSY) - condlog(3, "%s: rport blocked", rport_id); - else -- condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d", -- rport_id, value, -ret); -+ log_sysfs_attr_set_value(0, ret, -+ "%s: failed to set dev_loss_tmo to %s", -+ rport_id, value); - } - } - out: -@@ -754,12 +766,16 @@ sysfs_set_session_tmo(struct path *pp) - condlog(3, "%s: can't set fast_io_fail_tmo to '0'" - "on iSCSI", pp->dev); - } else { -+ ssize_t len, ret; -+ - snprintf(value, 11, "%u", pp->fast_io_fail); -- if (sysfs_attr_set_value(session_dev, "recovery_tmo", -- value, strlen(value)) <= 0) { -- condlog(3, "%s: Failed to set recovery_tmo, " -- " error %d", pp->dev, errno); -- } -+ len = strlen(value); -+ ret = sysfs_attr_set_value(session_dev, "recovery_tmo", -+ value, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "%s: Failed to set recovery_tmo to %s", -+ pp->dev, value); - } - } - udev_device_unref(session_dev); -@@ -802,12 +818,16 @@ sysfs_set_nexus_loss_tmo(struct path *pp) - pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id); - - if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { -+ ssize_t len, ret; -+ - snprintf(value, 11, "%u", pp->dev_loss); -- if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", -- value, strlen(value)) <= 0) -- condlog(3, "%s: failed to update " -- "I_T Nexus loss timeout, error %d", -- pp->dev, errno); -+ len = strlen(value); -+ ret = sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", -+ value, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "%s: failed to update I_T Nexus loss timeout", -+ pp->dev); - } - udev_device_unref(sas_dev); - return; -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 125f1c2b..9c84af70 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -134,7 +134,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - /* write attribute value */ - fd = open(devpath, O_WRONLY); - if (fd < 0) { -- condlog(2, "%s: attribute '%s' can not be opened: %s", -+ condlog(3, "%s: attribute '%s' can not be opened: %s", - __func__, devpath, strerror(errno)); - return -errno; - } -@@ -144,11 +144,9 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - size = -errno; - condlog(3, "%s: write to %s failed: %s", __func__, - devpath, strerror(errno)); -- } else if (size < (ssize_t)value_len) { -+ } else if (size < (ssize_t)value_len) - condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", - __func__, value_len, devpath, size); -- size = 0; -- } - - close(fd); - return size; -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index cdc84e40..799f68e9 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -5,6 +5,7 @@ - #ifndef _LIBMULTIPATH_SYSFS_H - #define _LIBMULTIPATH_SYSFS_H - #include -+#include "strbuf.h" - - ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - const char * value, size_t value_len); -@@ -25,6 +26,15 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, - sysfs_attr_value_ok(__rc, __l); \ - }) - -+#define log_sysfs_attr_set_value(prio, rc, fmt, __args...) \ -+do { \ -+ STRBUF_ON_STACK(__buf); \ -+ if (print_strbuf(&__buf, fmt, ##__args) >= 0 && \ -+ print_strbuf(&__buf, ": %s", rc < 0 ? strerror(-rc) : \ -+ "write underflow") >= 0) \ -+ condlog(prio, "%s", get_strbuf_str(&__buf)); \ -+} while(0) -+ - int sysfs_get_size (struct path *pp, unsigned long long * size); - int sysfs_check_holders(char * check_devt, char * new_devt); - bool sysfs_is_multipathed(struct path *pp, bool set_wwid); diff --git a/0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch b/0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch new file mode 100644 index 0000000..3dd4a8a --- /dev/null +++ b/0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch @@ -0,0 +1,136 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 21:59:36 +0200 +Subject: [PATCH] multipath-tools Makefiles: clean up executable Makefiles + +Move the EXEC definition to the top, and use simple make variables +where possible. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + kpartx/Makefile | 15 +++++++-------- + multipath/Makefile | 6 +++--- + multipathd/Makefile | 30 ++++++++++++++---------------- + 3 files changed, 24 insertions(+), 27 deletions(-) + +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 464925ad..7ceae96b 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -3,20 +3,19 @@ + # + include ../Makefile.inc + +-CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +-CFLAGS += $(BIN_CFLAGS) +-LDFLAGS += $(BIN_LDFLAGS) +- +-LIBDEPS += -ldevmapper ++EXEC := kpartx + ++CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 + ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_COOKIE + endif + +-OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ +- gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o ++CFLAGS += $(BIN_CFLAGS) ++LDFLAGS += $(BIN_LDFLAGS) ++LIBDEPS += -ldevmapper + +-EXEC = kpartx ++OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ ++ gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o + + all: $(EXEC) + +diff --git a/multipath/Makefile b/multipath/Makefile +index 1c4e7a52..7f7b341d 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -3,15 +3,15 @@ + # + include ../Makefile.inc + ++EXEC := multipath ++ + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ + -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ldl -ludev + +-EXEC = multipath +- +-OBJS = main.o ++OBJS := main.o + + all: $(EXEC) multipath.rules tmpfiles.conf + +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 7221b6af..bb8f7770 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -1,27 +1,30 @@ + include ../Makefile.inc + ++EXEC := multipathd ++CLI := multipathc ++ ++CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ ++ $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ ++ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ ++ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) ++ ++ifeq ($(ENABLE_DMEVENTS_POLL),0) ++ CPPFLAGS += -DNO_DMEVENTS_POLL ++endif + ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) + CPPFLAGS += -DLIBDM_API_GET_ERRNO + endif +- + ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) + CPPFLAGS += -DFPIN_EVENT_HANDLER + FPIN_SUPPORT = 1 + endif ++ + # + # debugging stuff + # + #CPPFLAGS += -DLCKDBG +-#CPPFLAGS += -D_DEBUG_ + #CPPFLAGS += -DLOGDBG + +-CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ +- $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ +- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ +- -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) +-ifeq ($(ENABLE_DMEVENTS_POLL),0) +- CPPFLAGS += -DNO_DMEVENTS_POLL +-endif + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + +@@ -43,18 +46,13 @@ RL_CPPFLAGS := -DUSE_LIBREADLINE + RL_LIBDEPS := -lreadline + endif + +-OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ ++CLI_OBJS := multipathc.o cli.o ++OBJS := main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ + dmevents.o init_unwinder.o +- +-CLI_OBJS = multipathc.o cli.o +- + ifeq ($(FPIN_SUPPORT),1) + OBJS += fpin_handlers.o + endif + +-EXEC = multipathd +-CLI = multipathc +- + all : $(EXEC) $(CLI) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so diff --git a/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch b/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch deleted file mode 100644 index 90fbfdf..0000000 --- a/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 18:07:57 +0200 -Subject: [PATCH] libmultipath: sysfs: cleanup file descriptors on - pthread_cancel() - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 9c84af70..64946385 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -49,7 +49,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - { - const char *syspath; - char devpath[PATH_MAX]; -- int fd; -+ long fd; - ssize_t size = -1; - - if (!dev || !attr_name || !value || !value_len) { -@@ -74,6 +74,8 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - __func__, devpath, strerror(errno)); - return -errno; - } -+ pthread_cleanup_push(close_fd, (void *)fd); -+ - size = read(fd, value, value_len); - if (size < 0) { - size = -errno; -@@ -90,7 +92,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ - size = strchop(value); - } - -- close(fd); -+ pthread_cleanup_pop(1); - return size; - } - -@@ -112,7 +114,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - { - const char *syspath; - char devpath[PATH_MAX]; -- int fd; -+ long fd; - ssize_t size = -1; - - if (!dev || !attr_name || !value || !value_len) { -@@ -138,6 +140,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - __func__, devpath, strerror(errno)); - return -errno; - } -+ pthread_cleanup_push(close_fd, (void *)fd); - - size = write(fd, value, value_len); - if (size < 0) { -@@ -148,7 +151,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, - condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", - __func__, value_len, devpath, size); - -- close(fd); -+ pthread_cleanup_pop(1); - return size; - } - diff --git a/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch b/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch new file mode 100644 index 0000000..0b45e62 --- /dev/null +++ b/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch @@ -0,0 +1,261 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 21:52:06 +0200 +Subject: [PATCH] multipath-tools: Makefiles: use common code for libraries + +Move shared code to Makefile.inc as far as possible. Use simple +make variables where possible. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 15 ++++++++++++++- + libdmmp/Makefile | 17 ++++++++--------- + libmpathcmd/Makefile | 14 ++------------ + libmpathpersist/Makefile | 14 ++------------ + libmpathutil/Makefile | 14 +------------- + libmpathvalid/Makefile | 14 ++------------ + libmultipath/Makefile | 12 +----------- + 7 files changed, 30 insertions(+), 70 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 2cf25745..fe6bc088 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -64,7 +64,6 @@ GZIP_PROG := gzip -9 -c + RM := rm -f + LN := ln -sf + INSTALL_PROGRAM := install +-NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) + + # $(call TEST_CC_OPTION,option,fallback) + # Test if the C compiler supports the option. +@@ -127,6 +126,13 @@ thirdpartydir := $(TOPDIR)/third-party + libdmmpdir := $(TOPDIR)/libdmmp + nvmedir := $(TOPDIR)/libmultipath/nvme + ++# Common code for libraries - library Makefiles just set DEVLIB ++# SONAME defaults to 0 (we use version scripts) ++SONAME := 0 ++LIBS = $(DEVLIB).$(SONAME) ++VERSION_SCRIPT = $(DEVLIB:%.so=%.version) ++NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) ++ + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ + if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ +@@ -175,3 +181,10 @@ check_var = $(shell \ + + %.abi: %.so + abidw $< >$@ ++ ++%-nv.version: %.version ++ @echo creating $@ from $< ++ @printf 'NOVERSION {\nglobal:\n' >$@ ++ @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ ++ @printf 'local:\n\t*;\n};\n' >>$@ ++ +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index 985b694b..67b6f86f 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -5,15 +5,14 @@ + # + include ../Makefile.inc + +-LIBDMMP_VERSION=0.2.0 +-SONAME=$(LIBDMMP_VERSION) +-DEVLIB = libdmmp.so +-LIBS = $(DEVLIB).$(SONAME) +-PKGFILE = libdmmp.pc +-EXTRA_MAN_FILES = libdmmp.h.3 +-HEADERS = libdmmp/libdmmp.h +- +-OBJS = libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o ++LIBDMMP_VERSION := 0.2.0 ++SONAME := $(LIBDMMP_VERSION) ++DEVLIB := libdmmp.so ++PKGFILE := libdmmp.pc ++EXTRA_MAN_FILES := libdmmp.h.3 ++HEADERS := libdmmp/libdmmp.h ++ ++OBJS := libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o + + CPPFLAGS += -I$(libdmmpdir) -I$(mpathcmddir) $(shell $(PKGCONFIG) --cflags json-c) + CFLAGS += $(LIB_CFLAGS) -fvisibility=hidden +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index 0f83fe7b..f705c7f0 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -1,13 +1,8 @@ + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathcmd.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmpathcmd.version +- ++DEVLIB := libmpathcmd.so + CFLAGS += $(LIB_CFLAGS) +- +-OBJS = mpath_cmd.o ++OBJS := mpath_cmd.o + + all: $(DEVLIB) + +@@ -15,11 +10,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 479524d4..6f69168f 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -1,16 +1,11 @@ + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathpersist.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT:= libmpathpersist.version +- ++DEVLIB := libmpathpersist.so + CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) + LDFLAGS += -L$(multipathdir) -L$(mpathutildir) -L$(mpathcmddir) +- + LIBDEPS += -lmultipath -lmpathutil -lmpathcmd -ldevmapper -lpthread -ldl + +-OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o ++OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o + + all: $(DEVLIB) + +@@ -18,11 +13,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 4be75d2d..5665af28 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -3,14 +3,9 @@ + # + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathutil.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmpathutil.version +- ++DEVLIB := libmpathutil.so + CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE +- + LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) + + # object files referencing MULTIPATH_DIR or CONFIG_DIR +@@ -22,8 +17,6 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ + + all: $(DEVLIB) + +-make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) +- + $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +@@ -31,11 +24,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile +index 5dbfb923..bd4ccc0d 100644 +--- a/libmpathvalid/Makefile ++++ b/libmpathvalid/Makefile +@@ -1,17 +1,12 @@ + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmpathvalid.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmpathvalid.version +- ++DEVLIB := libmpathvalid.so + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) + CFLAGS += $(LIB_CFLAGS) +- + LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ + -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev + +-OBJS = mpath_valid.o ++OBJS := mpath_valid.o + + all: $(LIBS) + +@@ -20,11 +15,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + -Wl,--version-script=$(VERSION_SCRIPT) + $(LN) $(LIBS) $(DEVLIB) + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 009f26a3..9dc229ae 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -3,14 +3,9 @@ + # + include ../Makefile.inc + +-SONAME = 0 +-DEVLIB = libmultipath.so +-LIBS = $(DEVLIB).$(SONAME) +-VERSION_SCRIPT := libmultipath.version +- ++DEVLIB := libmultipath.so + CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) +- + LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ + -lurcu -laio $(SYSTEMD_LIBDEPS) + +@@ -85,11 +80,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) + $(DEVLIB): $(LIBS) + $(LN) $(LIBS) $@ + +-$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) +- @printf 'NOVERSION {\nglobal:\n' >$@ +- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ +- @printf 'local:\n\t*;\n};\n' >>$@ +- + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) diff --git a/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch b/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch deleted file mode 100644 index 710f633..0000000 --- a/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 18:45:11 +0200 -Subject: [PATCH] libmultipath, multipathd: log failure setting sysfs - attributes - -Failure to set a sysfs attribute is worth noting, normally. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 18 ++++++++++++++--- - multipathd/fpin_handlers.c | 11 +++++++++-- - multipathd/main.c | 40 ++++++++++++++++++++++++++++++-------- - 3 files changed, 56 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 0607dbac..4427f910 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -489,9 +489,15 @@ void trigger_partitions_udev_change(struct udev_device *dev, - - devtype = udev_device_get_devtype(part); - if (devtype && !strcmp("partition", devtype)) { -+ ssize_t ret; -+ - condlog(4, "%s: triggering %s event for %s", __func__, - action, syspath); -- sysfs_attr_set_value(part, "uevent", action, len); -+ ret = sysfs_attr_set_value(part, "uevent", action, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to trigger %s uevent", -+ syspath, action); - } - udev_device_unref(part); - } -@@ -510,6 +516,7 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) - */ - const char *action = is_mpath ? "change" : "add"; - const char *env; -+ ssize_t len, ret; - - if (!pp->udev) - return; -@@ -536,8 +543,13 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) - - condlog(3, "triggering %s uevent for %s (is %smultipath member)", - action, pp->dev, is_mpath ? "" : "no "); -- sysfs_attr_set_value(pp->udev, "uevent", -- action, strlen(action)); -+ -+ len = strlen(action); -+ ret = sysfs_attr_set_value(pp->udev, "uevent", action, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to trigger %s uevent", -+ pp->dev, action); - trigger_partitions_udev_change(pp->udev, action, - strlen(action)); - } -diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c -index 384ae318..00195721 100644 ---- a/multipathd/fpin_handlers.c -+++ b/multipathd/fpin_handlers.c -@@ -172,8 +172,15 @@ fpin_els_add_li_frame(struct fc_nl_event *fc_event) - /*Sets the rport port_state to marginal*/ - static void fpin_set_rport_marginal(struct udev_device *rport_dev) - { -- sysfs_attr_set_value(rport_dev, "port_state", -- "Marginal", strlen("Marginal")); -+ static const char marginal[] = "Marginal"; -+ ssize_t ret; -+ -+ ret = sysfs_attr_set_value(rport_dev, "port_state", -+ marginal, sizeof(marginal) - 1); -+ if (ret != sizeof(marginal) - 1) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to set port_state to marginal", -+ udev_device_get_syspath(rport_dev)); - } - - /*Add the marginal devices info into the list*/ -diff --git a/multipathd/main.c b/multipathd/main.c -index 68eca925..a160c824 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -911,14 +911,22 @@ rescan_path(struct udev_device *ud) - { - ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi", - "scsi_device"); -- if (ud) -- sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); -+ if (ud) { -+ ssize_t ret = -+ sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); -+ if (ret != strlen("1")) -+ log_sysfs_attr_set_value(1, ret, -+ "%s: failed to trigger rescan", -+ udev_device_get_syspath(ud)); -+ } - } - - void - handle_path_wwid_change(struct path *pp, struct vectors *vecs) - { - struct udev_device *udd; -+ static const char add[] = "add"; -+ ssize_t ret; - - if (!pp || !pp->udev) - return; -@@ -929,8 +937,12 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) - dm_fail_path(pp->mpp->alias, pp->dev_t); - } - rescan_path(udd); -- sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); -+ ret = sysfs_attr_set_value(udd, "uevent", add, sizeof(add) - 1); - udev_device_unref(udd); -+ if (ret != sizeof(add) - 1) -+ log_sysfs_attr_set_value(1, ret, -+ "%s: failed to trigger add event", -+ pp->dev); - } - - bool -@@ -2003,9 +2015,14 @@ partial_retrigger_tick(vector pathvec) - --pp->partial_retrigger_delay == 0) { - const char *msg = udev_device_get_is_initialized(pp->udev) ? - "change" : "add"; -- -- sysfs_attr_set_value(pp->udev, "uevent", msg, -- strlen(msg)); -+ ssize_t len = strlen(msg); -+ ssize_t ret = sysfs_attr_set_value(pp->udev, "uevent", msg, -+ len); -+ -+ if (len != ret) -+ log_sysfs_attr_set_value(2, ret, -+ "%s: failed to trigger %s event", -+ pp->dev, msg); - } - } - } -@@ -2245,12 +2262,19 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - - if (!pp->mpp && pp->initialized == INIT_MISSING_UDEV) { - if (pp->retriggers < retrigger_tries) { -+ static const char change[] = "change"; -+ ssize_t ret; -+ - condlog(2, "%s: triggering change event to reinitialize", - pp->dev); - pp->initialized = INIT_REQUESTED_UDEV; - pp->retriggers++; -- sysfs_attr_set_value(pp->udev, "uevent", "change", -- strlen("change")); -+ ret = sysfs_attr_set_value(pp->udev, "uevent", change, -+ sizeof(change) - 1); -+ if (ret != sizeof(change) - 1) -+ log_sysfs_attr_set_value(1, ret, -+ "%s: failed to trigger change event", -+ pp->dev); - return 0; - } else { - condlog(1, "%s: not initialized after %d udev retriggers", diff --git a/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch b/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch new file mode 100644 index 0000000..1a2069f --- /dev/null +++ b/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch @@ -0,0 +1,172 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 27 Oct 2022 22:18:22 +0200 +Subject: [PATCH] multipath-tools: Makefiles: move common code to rules.mk + +The library Makefiles contain a lot of similar rules. Just +maintain them in a single file. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathcmd/Makefile | 13 +------------ + libmpathpersist/Makefile | 13 +------------ + libmpathutil/Makefile | 13 +------------ + libmpathvalid/Makefile | 13 ++----------- + libmultipath/Makefile | 16 ++-------------- + rules.mk | 15 +++++++++++++++ + 6 files changed, 22 insertions(+), 61 deletions(-) + create mode 100644 rules.mk + +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index f705c7f0..cfb202b8 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -6,18 +6,7 @@ OBJS := mpath_cmd.o + + all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++include $(TOPDIR)/rules.mk + + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 6f69168f..94672556 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -9,18 +9,7 @@ OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o + + all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++include $(TOPDIR)/rules.mk + + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 5665af28..5ab33c09 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -17,18 +17,7 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ + + all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) ++include $(TOPDIR)/rules.mk + + install: all + $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile +index bd4ccc0d..88034df3 100644 +--- a/libmpathvalid/Makefile ++++ b/libmpathvalid/Makefile +@@ -8,18 +8,9 @@ LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ + + OBJS := mpath_valid.o + +-all: $(LIBS) ++all: $(DEVLIB) + +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) \ +- -Wl,--version-script=$(VERSION_SCRIPT) +- $(LN) $(LIBS) $(DEVLIB) +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) ++include $(TOPDIR)/rules.mk + + install: $(LIBS) + $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 9dc229ae..e24eab8a 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -56,6 +56,8 @@ OBJS := $(OBJS-O) $(OBJS-U) + + all: $(DEVLIB) + ++include $(TOPDIR)/rules.mk ++ + nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h + $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< + +@@ -72,20 +74,6 @@ nvme-ioctl.c: nvme/nvme-ioctl.c + nvme-ioctl.h: nvme/nvme-ioctl.h + $(call make_static,$<,$@) + +- +-$(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-$(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ +- +-$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ +- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) +- +-abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) +- + ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) + $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ + -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) +diff --git a/rules.mk b/rules.mk +new file mode 100644 +index 00000000..c1d80820 +--- /dev/null ++++ b/rules.mk +@@ -0,0 +1,15 @@ ++# Copyright (c) SUSE LLC ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++$(DEVLIB): $(LIBS) ++ $(LN) $(LIBS) $@ ++ ++$(LIBS): $(OBJS) $(VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) ++ ++$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) ++ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) ++ ++abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) diff --git a/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch b/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch deleted file mode 100644 index 6b7c06b..0000000 --- a/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 23:18:07 +0200 -Subject: [PATCH] multipath tests: expect_condlog: skip depending on verbosity - -otherwise we'll get failures if verbosity level is low. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/test-log.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/tests/test-log.c b/tests/test-log.c -index 14f25b9b..0c17cd96 100644 ---- a/tests/test-log.c -+++ b/tests/test-log.c -@@ -6,6 +6,8 @@ - #include - #include "log.h" - #include "test-log.h" -+#include "debug.h" -+ - - __attribute__((format(printf, 2, 0))) - void __wrap_dlog (int prio, const char * fmt, ...) -@@ -24,6 +26,8 @@ void __wrap_dlog (int prio, const char * fmt, ...) - - void expect_condlog(int prio, char *string) - { -+ if (prio > MAX_VERBOSITY || prio > libmp_verbosity) -+ return; - expect_value(__wrap_dlog, prio, prio); - will_return(__wrap_dlog, string); - } diff --git a/0019-multipath-tools-Makefiles-create-config.mk.patch b/0019-multipath-tools-Makefiles-create-config.mk.patch new file mode 100644 index 0000000..4d403d0 --- /dev/null +++ b/0019-multipath-tools-Makefiles-create-config.mk.patch @@ -0,0 +1,603 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 00:01:46 +0200 +Subject: [PATCH] multipath-tools Makefiles: create config.mk + +Rather than running the test scripts for certain system features +every time "make" is called, save the configuration in "config.mk" +and "libmultipath/autoconfig.h", and reuse it later. This reduces +build time, especially in subsequent builds, and the build output is +less garbled by compiler options. + +It works by invoking the separate make file "create-config.mk" at +the beginning of the build process. Most of the complex makefile +functions are moved to "create-config.mk". + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/foreign.yaml | 2 +- + .gitignore | 2 + + Makefile | 19 +++- + Makefile.inc | 76 +-------------- + create-config.mk | 144 +++++++++++++++++++++++++++++ + kpartx/Makefile | 4 - + kpartx/devmapper.c | 1 + + kpartx/kpartx.c | 1 + + libdmmp/test/Makefile | 1 + + libmultipath/Makefile | 30 +----- + libmultipath/devmapper.h | 2 +- + libmultipath/dict.c | 1 + + libmultipath/prioritizers/Makefile | 2 +- + libmultipath/propsel.c | 1 + + libmultipath/uevent.c | 1 + + multipathd/Makefile | 11 --- + multipathd/fpin.h | 1 + + multipathd/main.c | 1 + + rules.mk | 3 + + tests/Makefile | 8 -- + 20 files changed, 179 insertions(+), 132 deletions(-) + create mode 100644 create-config.mk + +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index bd4e9c12..5a19913a 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -30,7 +30,7 @@ jobs: + if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + run: > + tar cfv binaries.tar +- Makefile* ++ Makefile* config.mk + libmpathcmd/*.so* libmultipath/*.so* libmpathutil/*.so* + libmultipath/checkers/*.so libmultipath/prioritizers/*.so + libmultipath/foreign/*.so +diff --git a/.gitignore b/.gitignore +index 83f8a552..535353e5 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -8,6 +8,7 @@ + *.gz + *.d + \#* ++config.mk + cscope.files + cscope.out + kpartx/kpartx +@@ -35,5 +36,6 @@ tests/*.out + tests/*.vgr + libmultipath/nvme-ioctl.c + libmultipath/nvme-ioctl.h ++libmultipath/autoconfig.h + */*-nv.version + reference-abi +diff --git a/Makefile b/Makefile +index 27b4641f..1b28db62 100644 +--- a/Makefile ++++ b/Makefile +@@ -30,7 +30,14 @@ BUILDDIRS.clean := $(BUILDDIRS:=.clean) tests.clean + + all: $(BUILDDIRS) + +-$(BUILDDIRS): ++config.mk libmultipath/autoconfig.h: ++ @$(MAKE) -f create-config.mk ++ @echo ==== config.mk ==== ++ @cat config.mk ++ @echo ==== autoconfig.h ==== ++ @cat libmultipath/autoconfig.h ++ ++$(BUILDDIRS): config.mk + $(MAKE) -C $@ + + $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) +@@ -83,7 +90,7 @@ libmultipath/checkers.install \ + libmultipath/prioritizers.install \ + libmultipath/foreign.install: libmultipath.install + +-$(BUILDDIRS.clean): ++%.clean: + $(MAKE) -C ${@:.clean=} clean + + %.install: % +@@ -92,8 +99,12 @@ $(BUILDDIRS.clean): + $(BUILDDIRS:=.uninstall): + $(MAKE) -C ${@:.uninstall=} uninstall + +-clean: $(BUILDDIRS.clean) +- rm -rf abi abi.tar.gz abi-test compile_commands.json ++# If config.mk is missing, "make clean" in subdir either fails, or tries to ++# build it. Both is undesirable. Avoid it by creating config.mk temporarily. ++clean: ++ @touch config.mk ++ $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true ++ rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk + + install: $(BUILDDIRS:=.install) + uninstall: $(BUILDDIRS:=.uninstall) +diff --git a/Makefile.inc b/Makefile.inc +index fe6bc088..415634f5 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -27,9 +27,9 @@ PKGCONFIG ?= pkg-config + ifeq ($(TOPDIR),) + TOPDIR = .. + endif +- +-SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ +- $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) ++ifneq ($(CREATE_CONFIG),1) ++include $(TOPDIR)/config.mk ++endif + + # Paths. All these can be overridden on the "make" command line. + prefix := +@@ -65,37 +65,6 @@ RM := rm -f + LN := ln -sf + INSTALL_PROGRAM := install + +-# $(call TEST_CC_OPTION,option,fallback) +-# Test if the C compiler supports the option. +-# Evaluates to "option" if yes, and "fallback" otherwise. +-TEST_CC_OPTION = $(shell \ +- if echo 'int main(void){return 0;}' | \ +- $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ +- then \ +- echo "$(1)"; \ +- else \ +- echo "$(2)"; \ +- fi) +- +-# "make" on some distros will fail on explicit '#' or '\#' in the program text below +-__HASH__ := \# +-# Check if _DFORTIFY_SOURCE=3 is supported. +-# On some distros (e.g. Debian Buster) it will be falsely reported as supported +-# but it doesn't seem to make a difference wrt the compilation result. +-FORTIFY_OPT := $(shell \ +- if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ +- $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ +- then \ +- echo "-D_FORTIFY_SOURCE=3"; \ +- else \ +- echo "-D_FORTIFY_SOURCE=2"; \ +- fi) +- +-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) +-ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) +-WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) +-WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) +- + SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) + SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) + +@@ -133,45 +102,6 @@ LIBS = $(DEVLIB).$(SONAME) + VERSION_SCRIPT = $(DEVLIB:%.so=%.version) + NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + +-# Check whether a function with name $1 has been declared in header file $2. +-check_func = $(shell \ +- if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ +- found=1; \ +- status="yes"; \ +- else \ +- found=0; \ +- status="no"; \ +- fi; \ +- echo 1>&2 "Checking for $1 in $2 ... $$status"; \ +- echo "$$found" \ +- ) +- +-# Checker whether a file with name $1 exists +-check_file = $(shell \ +- if [ -f "$1" ]; then \ +- found=1; \ +- status="yes"; \ +- else \ +- found=0; \ +- status="no"; \ +- fi; \ +- echo 1>&2 "Checking if $1 exists ... $$status"; \ +- echo "$$found" \ +- ) +- +-# Check whether a file contains a variable with name $1 in header file $2 +-check_var = $(shell \ +- if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ +- found=1; \ +- status="yes"; \ +- else \ +- found=0; \ +- status="no"; \ +- fi; \ +- echo 1>&2 "Checking for $1 in $2 ... $$status"; \ +- echo "$$found" \ +- ) +- + %.o: %.c + @echo building $@ because of $? + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< +diff --git a/create-config.mk b/create-config.mk +new file mode 100644 +index 00000000..2cc5284f +--- /dev/null ++++ b/create-config.mk +@@ -0,0 +1,144 @@ ++# Copyright (c) SUSE LLC ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++TOPDIR := . ++CREATE_CONFIG := 1 ++include $(TOPDIR)/Makefile.inc ++ ++# Check whether a function with name $1 has been declared in header file $2. ++check_func = $(shell \ ++ if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ ++ found=1; \ ++ status="yes"; \ ++ else \ ++ found=0; \ ++ status="no"; \ ++ fi; \ ++ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ ++ echo "$$found" \ ++ ) ++ ++# Checker whether a file with name $1 exists ++check_file = $(shell \ ++ if [ -f "$1" ]; then \ ++ found=1; \ ++ status="yes"; \ ++ else \ ++ found=0; \ ++ status="no"; \ ++ fi; \ ++ echo 1>&2 "Checking if $1 exists ... $$status"; \ ++ echo "$$found" \ ++ ) ++ ++# Check whether a file contains a variable with name $1 in header file $2 ++check_var = $(shell \ ++ if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ ++ found=1; \ ++ status="yes"; \ ++ else \ ++ found=0; \ ++ status="no"; \ ++ fi; \ ++ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ ++ echo "$$found" \ ++ ) ++ ++# Test special behavior of gcc 4.8 with nested initializers ++# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers ++TEST_MISSING_INITIALIZERS = $(shell \ ++ echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ ++ $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ ++ || echo -Wno-missing-field-initializers) ++ ++DEFINES := ++ ++ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_FLUSH ++endif ++ ++ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_GET_ERRNO ++endif ++ ++ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_COOKIE ++endif ++ ++ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) ++ DEFINES += LIBUDEV_API_RECVBUF ++endif ++ ++ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_DEFERRED ++endif ++ ++ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) ++ DEFINES += LIBDM_API_HOLD_CONTROL ++endif ++ ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) ++ DEFINES += FPIN_EVENT_HANDLER ++ FPIN_SUPPORT = 1 ++endif ++ ++ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) ++ ANA_SUPPORT := 1 ++endif ++ ++ifeq ($(ENABLE_DMEVENTS_POLL),0) ++ DEFINES += -DNO_DMEVENTS_POLL ++endif ++ ++SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ ++ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) ++ ++ ++# $(call TEST_CC_OPTION,option,fallback) ++# Test if the C compiler supports the option. ++# Evaluates to "option" if yes, and "fallback" otherwise. ++TEST_CC_OPTION = $(shell \ ++ if echo 'int main(void){return 0;}' | \ ++ $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ ++ then \ ++ echo "$(1)"; \ ++ else \ ++ echo "$(2)"; \ ++ fi) ++ ++# "make" on some distros will fail on explicit '#' or '\#' in the program text below ++__HASH__ := \# ++# Check if _DFORTIFY_SOURCE=3 is supported. ++# On some distros (e.g. Debian Buster) it will be falsely reported as supported ++# but it doesn't seem to make a difference wrt the compilation result. ++FORTIFY_OPT := $(shell \ ++ if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ ++ $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ ++ then \ ++ echo "-D_FORTIFY_SOURCE=3"; \ ++ else \ ++ echo "-D_FORTIFY_SOURCE=2"; \ ++ fi) ++ ++STACKPROT := ++ ++all: $(multipathdir)/autoconfig.h $(TOPDIR)/config.mk ++ ++$(multipathdir)/autoconfig.h: ++ @echo creating $@ ++ @echo '#ifndef _AUTOCONFIG_H' >$@ ++ @echo '#define _AUTOCONFIG_H' >>$@ ++ @for x in $(DEFINES); do echo "#define $$x" >>$@; done ++ @echo '#endif' >>$@ ++ ++$(TOPDIR)/config.mk: ++ @echo creating $@ ++ @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ ++ @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ ++ @echo "SYSTEMD := $(SYSTEMD)" >>$@ ++ @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ ++ @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ ++ @echo "ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)" >>$@ ++ @echo "WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)" >>$@ ++ @echo "WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,)" >>$@ ++ @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 7ceae96b..31b1138a 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -6,10 +6,6 @@ include ../Makefile.inc + EXEC := kpartx + + CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +-ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_COOKIE +-endif +- + CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + LIBDEPS += -ldevmapper +diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c +index bf14c784..f12762c5 100644 +--- a/kpartx/devmapper.c ++++ b/kpartx/devmapper.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include "autoconfig.h" + #include "devmapper.h" + #include "kpartx.h" + +diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c +index 1d568c9e..46cb76ba 100644 +--- a/kpartx/kpartx.c ++++ b/kpartx/kpartx.c +@@ -34,6 +34,7 @@ + #include + #include + ++#include "autoconfig.h" + #include "devmapper.h" + #include "crc32.h" + #include "lopart.h" +diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile +index 76b24d61..93de64a0 100644 +--- a/libdmmp/test/Makefile ++++ b/libdmmp/test/Makefile +@@ -2,6 +2,7 @@ + # + # Copyright (C) 2015-2016 Gris Ge + # ++TOPDIR := ../.. + include ../../Makefile.inc + + _libdmmpdir=../$(libdmmpdir) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index e24eab8a..1cc13577 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -9,34 +9,6 @@ CFLAGS += $(LIB_CFLAGS) + LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ + -lurcu -laio $(SYSTEMD_LIBDEPS) + +-ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_FLUSH +-endif +- +-ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_GET_ERRNO +-endif +- +-ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_COOKIE +-endif +- +-ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) +- CPPFLAGS += -DLIBUDEV_API_RECVBUF +-endif +- +-ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_DEFERRED +-endif +- +-ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_HOLD_CONTROL +-endif +- +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) +- CPPFLAGS += -DFPIN_EVENT_HANDLER +-endif +- + # object files referencing MULTIPATH_DIR or CONFIG_DIR + # they need to be recompiled for unit tests + OBJS-U := prio.o checkers.o foreign.o config.o +@@ -97,7 +69,7 @@ uninstall: + $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) ++ $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 703f3bf8..42f8eccd 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -1,6 +1,6 @@ + #ifndef _DEVMAPPER_H + #define _DEVMAPPER_H +- ++#include "autoconfig.h" + #include "structs.h" + + #define TGT_MPATH "multipath" +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index aa93fe43..6fc77315 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include "autoconfig.h" + #include "mpath_cmd.h" + #include "dict.h" + #include "strbuf.h" +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index 72eefe49..a699e8a6 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -26,7 +26,7 @@ LIBS = \ + libpriopath_latency.so \ + libpriosysfs.so + +-ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) ++ifneq ($(ANA_SUPPORT),1) + LIBS += libprioana.so + CPPFLAGS += -I../nvme + endif +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index d4f19897..d1d5cc25 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -5,6 +5,7 @@ + */ + #include + ++#include "autoconfig.h" + #include "nvme-lib.h" + #include "checkers.h" + #include "vector.h" +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index 57447ca0..bbc8e9e5 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -42,6 +42,7 @@ + #include + #include + ++#include "autoconfig.h" + #include "debug.h" + #include "list.h" + #include "uevent.h" +diff --git a/multipathd/Makefile b/multipathd/Makefile +index bb8f7770..587bb916 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -8,17 +8,6 @@ CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcm + awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ + -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) + +-ifeq ($(ENABLE_DMEVENTS_POLL),0) +- CPPFLAGS += -DNO_DMEVENTS_POLL +-endif +-ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) +- CPPFLAGS += -DLIBDM_API_GET_ERRNO +-endif +-ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) +- CPPFLAGS += -DFPIN_EVENT_HANDLER +- FPIN_SUPPORT = 1 +-endif +- + # + # debugging stuff + # +diff --git a/multipathd/fpin.h b/multipathd/fpin.h +index bfcc1ce2..3c374441 100644 +--- a/multipathd/fpin.h ++++ b/multipathd/fpin.h +@@ -1,5 +1,6 @@ + #ifndef __FPIN_H__ + #define __FPIN_H__ ++#include "autoconfig.h" + + #ifdef FPIN_EVENT_HANDLER + void *fpin_fabric_notification_receiver(void *unused); +diff --git a/multipathd/main.c b/multipathd/main.c +index ba52d393..1e1b254f 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -4,6 +4,7 @@ + * Copyright (c) 2005 Benjamin Marzinski, Redhat + * Copyright (c) 2005 Edward Goggin, EMC + */ ++#include "autoconfig.h" + #include + #include + #include +diff --git a/rules.mk b/rules.mk +index c1d80820..d8612527 100644 +--- a/rules.mk ++++ b/rules.mk +@@ -13,3 +13,6 @@ $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) ++ ++$(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: ++ $(MAKE) -C $(TOPDIR) -f create-config.mk +diff --git a/tests/Makefile b/tests/Makefile +index 3a5b161c..d9856d17 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -3,14 +3,6 @@ include ../Makefile.inc + # directory where to run the tests + TESTDIR := $(CURDIR) + +-# Test special behavior of gcc 4.8 with nested initializers +-# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers +-TEST_MISSING_INITIALIZERS = $(shell \ +- echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ +- $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ +- || echo -Wno-missing-field-initializers) +-W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) +- + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) -I$(daemondir) \ + -DTESTCONFDIR=\"$(TESTDIR)/conf.d\" + CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) diff --git a/0020-multipath-tests-__wrap_dlog-print-log-message.patch b/0020-multipath-tests-__wrap_dlog-print-log-message.patch deleted file mode 100644 index 216e5a2..0000000 --- a/0020-multipath-tests-__wrap_dlog-print-log-message.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Jul 2022 11:15:27 +0200 -Subject: [PATCH] multipath tests: __wrap_dlog: print log message - -This makes it easier to analyze errors from __wrap_dlog(). - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/test-log.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/test-log.c b/tests/test-log.c -index 0c17cd96..c1745872 100644 ---- a/tests/test-log.c -+++ b/tests/test-log.c -@@ -20,6 +20,7 @@ void __wrap_dlog (int prio, const char * fmt, ...) - va_start(ap, fmt); - vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); - va_end(ap); -+ fprintf(stderr, "%s(%d): %s", __func__, prio, buff); - expected = mock_ptr_type(char *); - assert_memory_equal(buff, expected, strlen(expected)); - } diff --git a/0020-multipath-tools-Makefiles-enable-quiet-build.patch b/0020-multipath-tools-Makefiles-enable-quiet-build.patch new file mode 100644 index 0000000..dbe1129 --- /dev/null +++ b/0020-multipath-tools-Makefiles-enable-quiet-build.patch @@ -0,0 +1,879 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 12:39:06 +0200 +Subject: [PATCH] multipath-tools Makefiles: enable quiet build + +Like many other projects, make it possible to print much less +output during build. Verbose output is enabled with "make V=1", as +usual. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile | 12 +++---- + Makefile.inc | 10 +++--- + kpartx/Makefile | 41 ++++++++++++----------- + libdmmp/Makefile | 48 +++++++++++++------------- + libdmmp/test/Makefile | 8 ++--- + libmpathcmd/Makefile | 20 +++++------ + libmpathpersist/Makefile | 32 +++++++++--------- + libmpathutil/Makefile | 14 ++++---- + libmpathvalid/Makefile | 20 +++++------ + libmultipath/Makefile | 30 ++++++++--------- + libmultipath/checkers/Makefile | 8 ++--- + libmultipath/foreign/Makefile | 8 ++--- + libmultipath/prioritizers/Makefile | 8 ++--- + mpathpersist/Makefile | 18 +++++----- + multipath/Makefile | 54 ++++++++++++++++-------------- + multipathd/Makefile | 42 ++++++++++++----------- + rules.mk | 8 ++--- + tests/Makefile | 23 +++++++------ + 18 files changed, 206 insertions(+), 198 deletions(-) + +diff --git a/Makefile b/Makefile +index 1b28db62..e3ce1a8d 100644 +--- a/Makefile ++++ b/Makefile +@@ -38,17 +38,17 @@ config.mk libmultipath/autoconfig.h: + @cat libmultipath/autoconfig.h + + $(BUILDDIRS): config.mk +- $(MAKE) -C $@ ++ @$(MAKE) -C $@ + + $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) +- $(MAKE) -C ${@:.abi=} abi ++ @$(MAKE) -C ${@:.abi=} abi + + # Create formal representation of the ABI + # Useful for verifying ABI compatibility + # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) + .PHONY: abi + abi: $(LIB_BUILDDIRS:=.abi) +- mkdir -p $@ ++ @mkdir -p $@ + ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) + + abi.tar.gz: abi +@@ -91,13 +91,13 @@ libmultipath/checkers.install \ + libmultipath/foreign.install: libmultipath.install + + %.clean: +- $(MAKE) -C ${@:.clean=} clean ++ @$(MAKE) -C ${@:.clean=} clean + + %.install: % +- $(MAKE) -C ${@:.install=} install ++ @$(MAKE) -C ${@:.install=} install + + $(BUILDDIRS:=.uninstall): +- $(MAKE) -C ${@:.uninstall=} uninstall ++ @$(MAKE) -C ${@:.uninstall=} uninstall + + # If config.mk is missing, "make clean" in subdir either fails, or tries to + # build it. Both is undesirable. Avoid it by creating config.mk temporarily. +diff --git a/Makefile.inc b/Makefile.inc +index 415634f5..3e14cb8c 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -1,4 +1,4 @@ +-# ++# -*- Makefile -*- + # Copyright (C) 2004 Christophe Varoqui, + # + +@@ -60,6 +60,8 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ + libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) + kernel_incdir := /usr/include + ++Q := $(if $(V),,@) ++ + GZIP_PROG := gzip -9 -c + RM := rm -f + LN := ln -sf +@@ -104,13 +106,13 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + + %.o: %.c + @echo building $@ because of $? +- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + + %.abi: %.so.0 +- abidw $< >$@ ++ $(Q)abidw $< >$@ + + %.abi: %.so +- abidw $< >$@ ++ $(Q)abidw $< >$@ + + %-nv.version: %.version + @echo creating $@ from $< +diff --git a/kpartx/Makefile b/kpartx/Makefile +index 31b1138a..7720a740 100644 +--- a/kpartx/Makefile ++++ b/kpartx/Makefile +@@ -16,33 +16,34 @@ OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ + all: $(EXEC) + + $(EXEC): $(OBJS) +- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + + install: $(EXEC) $(EXEC).8 +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) +- $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d +- $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules +- $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules +- $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d ++ $(Q)$(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules ++ $(Q)$(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules ++ $(Q)$(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 +- $(RM) $(DESTDIR)$(libudevdir)/kpartx_id +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/kpartx_id ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules + + clean: dep_clean +- $(RM) core *.o $(EXEC) ++ $(Q)$(RM) core *.o $(EXEC) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index 67b6f86f..7693facb 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -23,62 +23,62 @@ all: $(LIBS) doc + .PHONY: doc clean install uninstall check speed_test dep_clean + + $(LIBS): $(OBJS) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) + + $(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++ $(Q)$(LN) $(LIBS) $@ + + abi: $(DEVLIB:%.so=%.abi) + + install: +- mkdir -p $(DESTDIR)$(usrlibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 644 -D \ ++ @mkdir -p $(DESTDIR)$(usrlibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) ++ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ + $(HEADERS) $(DESTDIR)$(includedir)/$(HEADERS) +- $(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 644 -D \ ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ + $(PKGFILE).in $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ ++ $(Q)perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ ++ $(Q)perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ ++ $(Q)perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 ++ $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 + + uninstall: +- $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(includedir)/$(HEADERS) +- $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(includedir)/$(HEADERS) ++ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) + @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ + $(RM) $$file; \ + done +- $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* +- $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* ++ $(Q)$(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) +- $(MAKE) -C test clean ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ @$(MAKE) -C test clean + + include $(wildcard $(OBJS:.o=.d)) + + check: all +- $(MAKE) -C test check ++ @$(MAKE) -C test check + + speed_test: all +- $(MAKE) -C test speed_test ++ @$(MAKE) -C test speed_test + + doc: docs/man/dmmp_strerror.3 + + docs/man/dmmp_strerror.3: $(HEADERS) +- TEMPFILE=$(shell mktemp); \ ++ $(Q)TEMPFILE=$(shell mktemp); \ + cat $^ | perl docs/doc-preclean.pl >$$TEMPFILE; \ + LC_ALL=C \ + KBUILD_BUILD_TIMESTAMP=`git log -n1 --pretty=%cd --date=iso -- $^` \ + perl docs/kernel-doc -man $$TEMPFILE | \ + perl docs/split-man.pl docs/man; \ +- rm -f $$TEMPFILE ++ $(RM) -f $$TEMPFILE + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile +index 93de64a0..9d0817c8 100644 +--- a/libdmmp/test/Makefile ++++ b/libdmmp/test/Makefile +@@ -16,7 +16,7 @@ LDFLAGS += -L$(_libdmmpdir) -ldmmp + all: $(TEST_EXEC) $(SPD_TEST_EXEC) + + check: $(TEST_EXEC) $(SPD_TEST_EXEC) +- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ ++ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ + valgrind --quiet --leak-check=full \ + --show-reachable=no --show-possibly-lost=no \ + --trace-children=yes --error-exitcode=1 \ +@@ -24,15 +24,15 @@ check: $(TEST_EXEC) $(SPD_TEST_EXEC) + $(MAKE) speed_test + + speed_test: $(SPD_TEST_EXEC) +- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ ++ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ + time -p ./$(SPD_TEST_EXEC) + + clean: dep_clean +- rm -f $(TEST_EXEC) $(SPD_TEST_EXEC) ++ $(Q)$(RM) -f $(TEST_EXEC) $(SPD_TEST_EXEC) + + OBJS = $(TEST_EXEC).o $(SPD_TEST_EXEC).o + include $(wildcard $(OBJS:.o=.d)) + + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile +index cfb202b8..be615c2f 100644 +--- a/libmpathcmd/Makefile ++++ b/libmpathcmd/Makefile +@@ -9,22 +9,22 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) +- $(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(RM) $(DESTDIR)$(includedir)/mpath_cmd.h ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_cmd.h + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile +index 94672556..8f9a43f6 100644 +--- a/libmpathpersist/Makefile ++++ b/libmpathpersist/Makefile +@@ -12,28 +12,28 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 +- $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 +- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 +- $(RM) $(DESTDIR)$(includedir)/mpath_persist.h +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 ++ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_persist.h ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile +index 5ab33c09..f059de14 100644 +--- a/libmpathutil/Makefile ++++ b/libmpathutil/Makefile +@@ -20,18 +20,18 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile +index 88034df3..791a0398 100644 +--- a/libmpathvalid/Makefile ++++ b/libmpathvalid/Makefile +@@ -13,21 +13,21 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + install: $(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) +- $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) +- $(RM) $(DESTDIR)$(includedir)/mpath_valid.h ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_valid.h + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 1cc13577..3df851e2 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -31,47 +31,47 @@ all: $(DEVLIB) + include $(TOPDIR)/rules.mk + + nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h +- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< + + # there are lots of "unused parameters" in dict.c + # because not all handler / snprint methods need all parameters + dict.o: dict.c +- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + + make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) + + nvme-ioctl.c: nvme/nvme-ioctl.c +- $(call make_static,$<,$@) ++ $(Q)$(call make_static,$<,$@) + + nvme-ioctl.h: nvme/nvme-ioctl.h +- $(call make_static,$<,$@) ++ $(Q)$(call make_static,$<,$@) + + ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ + -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) +- $(LN) $@ ${@:.so.0=.so} ++ $(Q)$(LN) $@ ${@:.so.0=.so} + + # This rule is invoked from tests/Makefile, overriding configdir and plugindir + %-test.o: %.c + @echo building $@ because of $? +- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + + test-lib: ../tests/$(LIBS) + + install: all +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) +- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) ++ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + uninstall: +- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) +- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) ++ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) + + clean: dep_clean +- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) ++ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index 39ad76e0..b3120611 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -22,16 +22,16 @@ LIBS= \ + all: $(LIBS) + + libcheck%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: + for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean +- $(RM) core *.a *.o *.gz *.so ++ $(Q)$(RM) core *.a *.o *.gz *.so + + OBJS := $(LIBS:libcheck%.so=%.o) + .SECONDARY: $(OBJS) +@@ -39,4 +39,4 @@ OBJS := $(LIBS:libcheck%.so=%.o) + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile +index 8bf9047b..0e245d6f 100644 +--- a/libmultipath/foreign/Makefile ++++ b/libmultipath/foreign/Makefile +@@ -14,16 +14,16 @@ LIBS = libforeign-nvme.so + all: $(LIBS) + + libforeign-%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: + for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean +- $(RM) core *.a *.o *.gz *.so ++ $(Q)$(RM) core *.a *.o *.gz *.so + + OBJS := $(LIBS:libforeign-%.so=%.o) + .SECONDARY: $(OBJS) +@@ -31,4 +31,4 @@ OBJS := $(LIBS:libforeign-%.so=%.o) + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index a699e8a6..e1688163 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -34,16 +34,16 @@ endif + all: $(LIBS) + + libprio%.so: %.o +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) + + install: $(LIBS) +- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) + + uninstall: + for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean +- $(RM) core *.a *.o *.gz *.so ++ $(Q)$(RM) core *.a *.o *.gz *.so + + OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o + .SECONDARY: $(OBJS) +@@ -51,4 +51,4 @@ OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile +index d62537b5..f57c105c 100644 +--- a/mpathpersist/Makefile ++++ b/mpathpersist/Makefile +@@ -14,22 +14,22 @@ OBJS = main.o + all: $(EXEC) + + $(EXEC): $(OBJS) +- $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) ++ $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + clean: dep_clean +- $(RM) core *.o $(EXEC) ++ $(Q)$(RM) core *.o $(EXEC) + + include $(wildcard $(OBJS:.o=.d)) + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/multipath/Makefile b/multipath/Makefile +index 7f7b341d..73db991a 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -16,44 +16,46 @@ OBJS := main.o + all: $(EXEC) multipath.rules tmpfiles.conf + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + + install: +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) +- $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) +- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) +- $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) +- $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 + ifneq ($(SCSI_DH_MODULES_PRELOAD),) +- $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +- for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ ++ $(Q)$(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf ++ $(Q)for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ + >>$(DESTDIR)$(modulesloaddir)/scsi_dh.conf + endif + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) +- $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules +- $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf +- $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 +- $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules ++ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf ++ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + + clean: dep_clean +- $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf ++ $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) + + %: %.in +- sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ ++ @echo creating $@ ++ $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 587bb916..9d531329 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -45,41 +45,43 @@ endif + all : $(EXEC) $(CLI) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +- $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) + + multipathc.o: multipathc.c +- $(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + + $(CLI): $(CLI_OBJS) +- $(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) + + cli_handlers.o: cli_handlers.c +- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + + install: +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +- $(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) ++ $(Q)$(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) + ifdef SYSTEMD +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) + endif +- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 +- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 + + uninstall: +- $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) +- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 +- $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 +- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service +- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket ++ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 ++ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).service ++ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket + + clean: dep_clean +- $(RM) core *.o $(EXEC) $(CLI) ++ $(Q)$(RM) core *.o $(EXEC) $(CLI) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) +diff --git a/rules.mk b/rules.mk +index d8612527..c3a8e7ac 100644 +--- a/rules.mk ++++ b/rules.mk +@@ -2,17 +2,17 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + + $(DEVLIB): $(LIBS) +- $(LN) $(LIBS) $@ ++ $(Q)$(LN) $(LIBS) $@ + + $(LIBS): $(OBJS) $(VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) +- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ ++ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ + -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) + + abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) + + $(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: +- $(MAKE) -C $(TOPDIR) -f create-config.mk ++ $(Q)$(MAKE) -C $(TOPDIR) -f create-config.mk +diff --git a/tests/Makefile b/tests/Makefile +index d9856d17..021da0b0 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -12,7 +12,6 @@ TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ + alias directio valid devt mpathvalid strbuf sysfs features cli + HELPERS := test-lib.o test-log.o + +-.SILENT: $(TESTS:%=%.o) + .PRECIOUS: $(TESTS:%=%-test) + + all: $(TESTS:%=%.out) +@@ -71,11 +70,12 @@ features-test_LIBDEPS := -ludev -lpthread + cli-test_OBJDEPS := $(daemondir)/cli.o + + %.o: %.c +- $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< ++ @echo building $@ because of $? ++ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< + + lib/libchecktur.so: +- mkdir -p lib +- cd lib && ln -s ../$(multipathdir)/*/*.so . ++ @mkdir -p lib ++ $(Q)cd lib && ln -s ../$(multipathdir)/*/*.so . + + %.out: %-test lib/libchecktur.so + @echo == running $< == +@@ -89,34 +89,35 @@ lib/libchecktur.so: + OBJS = $(TESTS:%=%.o) $(HELPERS) + + test_clean: +- $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* ++ $(Q)$(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* + + valgrind_clean: +- $(RM) $(TESTS:%=%.vgr) ++ $(Q)$(RM) $(TESTS:%=%.vgr) + + clean: test_clean valgrind_clean dep_clean +- $(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap +- $(RM) -rf lib conf.d ++ $(Q)$(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap ++ $(Q)$(RM) -rf lib conf.d + + .SECONDARY: $(OBJS) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: +- $(RM) $(OBJS:.o=.d) ++ $(Q)$(RM) $(OBJS:.o=.d) + + %.o.wrap: %.c + @sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \ + sort -u | tr '\n' ' ' >$@ + + libmultipath.so.0: $(multipathdir)/libmultipath.so.0 +- make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib ++ @make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib + + # COLON will get expanded during second expansion below + COLON:=: + .SECONDEXPANSION: + %-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \ + libmultipath.so.0 $(mpathutildir)/libmpathutil.so.0 $(mpathcmddir)/libmpathcmd.so.0 Makefile +- $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ ++ @echo building $@ ++ $(Q)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ + $(LIBDEPS) $($@_LIBDEPS) \ + $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) diff --git a/0021-multipath-tests-add-sysfs-test.patch b/0021-multipath-tests-add-sysfs-test.patch deleted file mode 100644 index b02a055..0000000 --- a/0021-multipath-tests-add-sysfs-test.patch +++ /dev/null @@ -1,538 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 5 Jul 2022 23:19:30 +0200 -Subject: [PATCH] multipath tests: add sysfs test - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 5 +- - tests/sysfs.c | 494 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 498 insertions(+), 1 deletion(-) - create mode 100644 tests/sysfs.c - -diff --git a/tests/Makefile b/tests/Makefile -index d20ef236..95a99908 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -16,7 +16,7 @@ CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) - LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ -- alias directio valid devt mpathvalid strbuf -+ alias directio valid devt mpathvalid strbuf sysfs - HELPERS := test-lib.o test-log.o - - .SILENT: $(TESTS:%=%.o) -@@ -70,6 +70,9 @@ ifneq ($(DIO_TEST_DEV),) - directio-test_LIBDEPS := -laio - endif - strbuf-test_OBJDEPS := ../libmultipath/strbuf.o -+sysfs-test_TESTDEPS := test-log.o -+sysfs-test_OBJDEPS := ../libmultipath/sysfs.o ../libmultipath/util.o -+sysfs-test_LIBDEPS := -ludev -lpthread -ldl - - %.o: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< -diff --git a/tests/sysfs.c b/tests/sysfs.c -new file mode 100644 -index 00000000..0ec135bf ---- /dev/null -+++ b/tests/sysfs.c -@@ -0,0 +1,494 @@ -+/* -+ * Copyright (c) 2021 SUSE LLC -+ * SPDX-License-Identifier: GPL-2.0-only -+ */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "debug.h" -+#include "globals.c" -+#include "test-log.h" -+#include "sysfs.h" -+#include "util.h" -+ -+#define TEST_FD 123 -+ -+char *__wrap_udev_device_get_syspath(struct udev_device *ud) -+{ -+ char *val = mock_ptr_type(char *); -+ -+ return val; -+} -+ -+int __wrap_open(const char *pathname, int flags) -+{ -+ int ret; -+ -+ check_expected(pathname); -+ check_expected(flags); -+ ret = mock_type(int); -+ return ret; -+} -+ -+ssize_t __wrap_read(int fd, void *buf, size_t count) -+{ -+ ssize_t ret; -+ char *val; -+ -+ check_expected(fd); -+ check_expected(count); -+ ret = mock_type(int); -+ val = mock_ptr_type(char *); -+ if (ret >= (ssize_t)count) -+ ret = count; -+ if (ret >= 0 && val) { -+ fprintf(stderr, "%s: '%s' -> %zd\n", __func__, val, ret); -+ memcpy(buf, val, ret); -+ } -+ return ret; -+} -+ -+ssize_t __wrap_write(int fd, void *buf, size_t count) -+{ -+ ssize_t ret; -+ -+ check_expected(fd); -+ check_expected(count); -+ ret = mock_type(int); -+ if (ret >= (ssize_t)count) -+ ret = count; -+ return ret; -+} -+ -+int __real_close(int fd); -+int __wrap_close(int fd) { -+ if (fd != TEST_FD) -+ return __real_close(fd); -+ return mock_type(int); -+} -+ -+static int setup(void **state) -+{ -+ udev = udev_new(); -+ return 0; -+} -+ -+static int teardown(void **state) -+{ -+ udev_unref(udev); -+ return 0; -+} -+ -+static void expect_sagv_invalid(void) -+{ -+ expect_condlog(1, "__sysfs_attr_get_value: invalid parameters"); -+} -+ -+static void test_sagv_invalid(void **state) -+{ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value(NULL, (void *)state, (void *)state, 1), -+ -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value(NULL, (void *)state, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value((void *)state, NULL, (void *)state, 1), -+ -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, NULL, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, NULL, 1), -+ -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, NULL, 1), -+ -EINVAL); -+ -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, -+ (void *)state, 0), -EINVAL); -+ expect_sagv_invalid(); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, -+ (void *)state, 0), -EINVAL); -+} -+ -+static void test_sagv_bad_udev(void **state) -+{ -+ will_return(__wrap_udev_device_get_syspath, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); -+ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, -+ (void *)state, 1), -EINVAL); -+ -+ will_return(__wrap_udev_device_get_syspath, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, -+ (void *)state, 1), -EINVAL); -+} -+ -+static void test_sagv_bad_snprintf(void **state) -+{ -+ char longstr[PATH_MAX + 1]; -+ char buf[1]; -+ -+ memset(longstr, 'a', sizeof(longstr) - 1); -+ longstr[sizeof(longstr) - 1] = '\0'; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); -+ assert_int_equal(sysfs_attr_get_value((void *)state, longstr, -+ buf, sizeof(buf)), -EOVERFLOW); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, longstr, -+ (unsigned char *)buf, sizeof(buf)), -+ -EOVERFLOW); -+} -+ -+static void test_sagv_open_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ errno = ENOENT; -+ will_return(__wrap_open, -1); -+ expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' can not be opened"); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, sizeof(buf)), -ENOENT); -+} -+ -+static void test_sagv_read_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, sizeof(buf)); -+ errno = EISDIR; -+ will_return(__wrap_read, -1); -+ will_return(__wrap_read, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/bar failed:"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, sizeof(buf)), -EISDIR); -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/baz'"); -+ expect_string(__wrap_open, pathname, "/foo/baz"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, sizeof(buf)); -+ errno = EPERM; -+ will_return(__wrap_read, -1); -+ will_return(__wrap_read, NULL); -+ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/baz failed:"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", -+ (unsigned char *)buf, sizeof(buf)), -+ -EPERM); -+ -+} -+ -+static void _test_sagv_read(void **state, unsigned int bufsz) -+{ -+ char buf[16]; -+ char input[] = "01234567"; -+ unsigned int n, trunc; -+ -+ assert_in_range(bufsz, 1, sizeof(buf)); -+ memset(buf, '.', sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, bufsz); -+ will_return(__wrap_read, sizeof(input) - 1); -+ will_return(__wrap_read, input); -+ -+ /* If the buffer is too small, input will be truncated by a 0 byte */ -+ if (bufsz <= sizeof(input) - 1) { -+ n = bufsz; -+ trunc = 1; -+ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); -+ } else { -+ n = sizeof(input) - 1; -+ trunc = 0; -+ } -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, bufsz), n); -+ assert_memory_equal(buf, input, n - trunc); -+ assert_int_equal(buf[n - trunc], '\0'); -+ -+ /* Binary input is not truncated */ -+ memset(buf, '.', sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/baz'"); -+ expect_string(__wrap_open, pathname, "/foo/baz"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, bufsz); -+ will_return(__wrap_read, sizeof(input) - 1); -+ will_return(__wrap_read, input); -+ will_return(__wrap_close, 0); -+ n = bufsz < sizeof(input) - 1 ? bufsz : sizeof(input) - 1; -+ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", -+ (unsigned char *)buf, -+ bufsz), -+ n); -+ assert_memory_equal(buf, input, n); -+} -+ -+static void test_sagv_read_overflow_8(void **state) -+{ -+ _test_sagv_read(state, 8); -+} -+ -+static void test_sagv_read_overflow_4(void **state) -+{ -+ _test_sagv_read(state, 4); -+} -+ -+static void test_sagv_read_overflow_1(void **state) -+{ -+ _test_sagv_read(state, 1); -+} -+ -+static void test_sagv_read_good_9(void **state) -+{ -+ _test_sagv_read(state, 9); -+} -+ -+static void test_sagv_read_good_15(void **state) -+{ -+ _test_sagv_read(state, 15); -+} -+ -+static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) -+{ -+ char buf[16]; -+ char input[] = { '\0','\0','\0','\0','\0','\0','\0','\0' }; -+ unsigned int n; -+ -+ assert_in_range(bufsz, 1, sizeof(buf)); -+ memset(buf, '.', sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_RDONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_read, fd, TEST_FD); -+ expect_value(__wrap_read, count, bufsz); -+ will_return(__wrap_read, sizeof(input) - 1); -+ will_return(__wrap_read, input); -+ -+ if (bufsz <= sizeof(input) - 1) { -+ n = bufsz; -+ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); -+ } else -+ n = 0; -+ -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", -+ buf, bufsz), n); -+ -+ /* -+ * The return value of sysfs_attr_get_value ignores zero bytes, -+ * but the read data should have been copied to the buffer -+ */ -+ assert_memory_equal(buf, input, n == 0 ? bufsz : n); -+} -+ -+static void test_sagv_read_zeroes_4(void **state) -+{ -+ _test_sagv_read_zeroes(state, 4); -+} -+ -+static void expect_sasv_invalid(void) -+{ -+ expect_condlog(1, "sysfs_attr_set_value: invalid parameters"); -+} -+ -+static void test_sasv_invalid(void **state) -+{ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value(NULL, NULL, NULL, 0), -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value(NULL, (void *)state, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value((void *)state, NULL, (void *)state, 1), -+ -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, NULL, 1), -+ -EINVAL); -+ -+ expect_sasv_invalid(); -+ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, -+ (void *)state, 0), -EINVAL); -+} -+ -+static void test_sasv_bad_udev(void **state) -+{ -+ will_return(__wrap_udev_device_get_syspath, NULL); -+ expect_condlog(3, "sysfs_attr_set_value: invalid udevice"); -+ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, -+ (void *)state, 1), -EINVAL); -+} -+ -+static void test_sasv_bad_snprintf(void **state) -+{ -+ char longstr[PATH_MAX + 1]; -+ char buf[1]; -+ -+ memset(longstr, 'a', sizeof(longstr) - 1); -+ longstr[sizeof(longstr) - 1] = '\0'; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(3, "sysfs_attr_set_value: devpath overflow"); -+ assert_int_equal(sysfs_attr_set_value((void *)state, longstr, -+ buf, sizeof(buf)), -EOVERFLOW); -+} -+ -+static void test_sasv_open_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_WRONLY); -+ errno = EPERM; -+ will_return(__wrap_open, -1); -+ expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' can not be opened"); -+ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", -+ buf, sizeof(buf)), -EPERM); -+} -+ -+static void test_sasv_write_fail(void **state) -+{ -+ char buf[1]; -+ -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_WRONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_write, fd, TEST_FD); -+ expect_value(__wrap_write, count, sizeof(buf)); -+ errno = EISDIR; -+ will_return(__wrap_write, -1); -+ expect_condlog(3, "sysfs_attr_set_value: write to /foo/bar failed:"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", -+ buf, sizeof(buf)), -EISDIR); -+ -+} -+ -+static void _test_sasv_write(void **state, unsigned int n_written) -+{ -+ char buf[8]; -+ -+ assert_in_range(n_written, 0, sizeof(buf)); -+ will_return(__wrap_udev_device_get_syspath, "/foo"); -+ expect_condlog(4, "open '/foo/bar'"); -+ expect_string(__wrap_open, pathname, "/foo/bar"); -+ expect_value(__wrap_open, flags, O_WRONLY); -+ will_return(__wrap_open, TEST_FD); -+ expect_value(__wrap_write, fd, TEST_FD); -+ expect_value(__wrap_write, count, sizeof(buf)); -+ will_return(__wrap_write, n_written); -+ -+ if (n_written < sizeof(buf)) -+ expect_condlog(3, "sysfs_attr_set_value: underflow writing"); -+ will_return(__wrap_close, 0); -+ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", -+ buf, sizeof(buf)), -+ n_written); -+} -+ -+static void test_sasv_write_0(void **state) -+{ -+ _test_sasv_write(state, 0); -+} -+ -+static void test_sasv_write_4(void **state) -+{ -+ _test_sasv_write(state, 4); -+} -+ -+static void test_sasv_write_7(void **state) -+{ -+ _test_sasv_write(state, 7); -+} -+ -+static void test_sasv_write_8(void **state) -+{ -+ _test_sasv_write(state, 8); -+} -+ -+static int test_sysfs(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_sagv_invalid), -+ cmocka_unit_test(test_sagv_bad_udev), -+ cmocka_unit_test(test_sagv_bad_snprintf), -+ cmocka_unit_test(test_sagv_open_fail), -+ cmocka_unit_test(test_sagv_read_fail), -+ cmocka_unit_test(test_sagv_read_overflow_1), -+ cmocka_unit_test(test_sagv_read_overflow_4), -+ cmocka_unit_test(test_sagv_read_overflow_8), -+ cmocka_unit_test(test_sagv_read_good_9), -+ cmocka_unit_test(test_sagv_read_good_15), -+ cmocka_unit_test(test_sagv_read_zeroes_4), -+ cmocka_unit_test(test_sasv_invalid), -+ cmocka_unit_test(test_sasv_bad_udev), -+ cmocka_unit_test(test_sasv_bad_snprintf), -+ cmocka_unit_test(test_sasv_open_fail), -+ cmocka_unit_test(test_sasv_write_fail), -+ cmocka_unit_test(test_sasv_write_0), -+ cmocka_unit_test(test_sasv_write_4), -+ cmocka_unit_test(test_sasv_write_7), -+ cmocka_unit_test(test_sasv_write_8), -+ }; -+ -+ return cmocka_run_group_tests(tests, setup, teardown); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ -+ init_test_verbosity(4); -+ ret += test_sysfs(); -+ return ret; -+} diff --git a/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch b/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch new file mode 100644 index 0000000..d45f99f --- /dev/null +++ b/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch @@ -0,0 +1,183 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 14:39:22 +0200 +Subject: [PATCH] multipath-tools: quiet build support for top-level Makefile + +This requires including "Makefile.inc" in the top-level Makefile, +too. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile | 32 ++++++++++++++++++------------ + Makefile.inc | 8 ++++++-- + create-config.mk | 1 - + libmultipath/checkers/Makefile | 2 +- + libmultipath/foreign/Makefile | 2 +- + libmultipath/prioritizers/Makefile | 2 +- + 6 files changed, 28 insertions(+), 19 deletions(-) + +diff --git a/Makefile b/Makefile +index e3ce1a8d..b9e30234 100644 +--- a/Makefile ++++ b/Makefile +@@ -2,6 +2,9 @@ + # Copyright (C) 2003 Christophe Varoqui, + # + ++TOPDIR := . ++include Makefile.inc ++ + LIB_BUILDDIRS := \ + libmpathcmd \ + libmpathutil \ +@@ -32,10 +35,12 @@ all: $(BUILDDIRS) + + config.mk libmultipath/autoconfig.h: + @$(MAKE) -f create-config.mk ++ifeq ($(V),1) + @echo ==== config.mk ==== + @cat config.mk + @echo ==== autoconfig.h ==== + @cat libmultipath/autoconfig.h ++endif + + $(BUILDDIRS): config.mk + @$(MAKE) -C $@ +@@ -48,11 +53,12 @@ $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) + # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) + .PHONY: abi + abi: $(LIB_BUILDDIRS:=.abi) ++ @echo creating abi + @mkdir -p $@ +- ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) ++ $(Q)ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) + + abi.tar.gz: abi +- tar cfz $@ abi ++ $(Q)tar cfz $@ abi + + # Check the ABI against a reference. + # This requires the ABI from a previous run to be present +@@ -77,8 +83,8 @@ abi-test: abi reference-abi $(wildcard abi/*.abi) + # Create compile_commands.json, useful for using clangd with an IDE + # Requires bear (https://github.com/rizsotto/Bear) + compile_commands.json: Makefile Makefile.inc $(BUILDDIRS:=/Makefile) +- $(MAKE) clean +- bear -- $(MAKE) ++ $(Q)$(MAKE) clean ++ $(Q)bear -- $(MAKE) + + libmpathutil libdmmp: libmpathcmd + libmultipath: libmpathutil +@@ -103,24 +109,24 @@ $(BUILDDIRS:=.uninstall): + # build it. Both is undesirable. Avoid it by creating config.mk temporarily. + clean: + @touch config.mk +- $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true +- rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk ++ $(Q)$(MAKE) $(BUILDDIRS:=.clean) tests.clean || true ++ $(Q)$(RM) -r abi abi.tar.gz abi-test compile_commands.json config.mk + + install: $(BUILDDIRS:=.install) + uninstall: $(BUILDDIRS:=.uninstall) + + test-progs: all +- $(MAKE) -C tests progs ++ @$(MAKE) -C tests progs + + test: all +- $(MAKE) -C tests all ++ @$(MAKE) -C tests all + + valgrind-test: all +- $(MAKE) -C tests valgrind ++ @$(MAKE) -C tests valgrind + + .PHONY: TAGS + TAGS: +- etags -a libmultipath/*.c +- etags -a libmultipath/*.h +- etags -a multipathd/*.c +- etags -a multipathd/*.h ++ @etags -a libmultipath/*.c ++ @etags -a libmultipath/*.h ++ @etags -a multipathd/*.c ++ @etags -a multipathd/*.h +diff --git a/Makefile.inc b/Makefile.inc +index 3e14cb8c..866ab274 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -27,7 +27,7 @@ PKGCONFIG ?= pkg-config + ifeq ($(TOPDIR),) + TOPDIR = .. + endif +-ifneq ($(CREATE_CONFIG),1) ++ifneq ($(TOPDIR),.) + include $(TOPDIR)/config.mk + endif + +@@ -60,7 +60,11 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ + libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) + kernel_incdir := /usr/include + +-Q := $(if $(V),,@) ++ifeq ($(V),) ++Q := @ ++# make's "Entering directory" messages are confusing in parallel mode ++#MAKEFLAGS = --no-print-directory ++endif + + GZIP_PROG := gzip -9 -c + RM := rm -f +diff --git a/create-config.mk b/create-config.mk +index 2cc5284f..434dee06 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -2,7 +2,6 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + + TOPDIR := . +-CREATE_CONFIG := 1 + include $(TOPDIR)/Makefile.inc + + # Check whether a function with name $1 has been declared in header file $2. +diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile +index b3120611..6f7cfb95 100644 +--- a/libmultipath/checkers/Makefile ++++ b/libmultipath/checkers/Makefile +@@ -28,7 +28,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done ++ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(Q)$(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile +index 0e245d6f..b83213d6 100644 +--- a/libmultipath/foreign/Makefile ++++ b/libmultipath/foreign/Makefile +@@ -20,7 +20,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done ++ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(Q)$(RM) core *.a *.o *.gz *.so +diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile +index e1688163..fdec36e7 100644 +--- a/libmultipath/prioritizers/Makefile ++++ b/libmultipath/prioritizers/Makefile +@@ -40,7 +40,7 @@ install: $(LIBS) + $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) + + uninstall: +- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done ++ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done + + clean: dep_clean + $(Q)$(RM) core *.a *.o *.gz *.so diff --git a/0022-GitHub-workflows-use-make-j8-Orecurse.patch b/0022-GitHub-workflows-use-make-j8-Orecurse.patch new file mode 100644 index 0000000..33b7dcd --- /dev/null +++ b/0022-GitHub-workflows-use-make-j8-Orecurse.patch @@ -0,0 +1,132 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 15:29:51 +0200 +Subject: [PATCH] GitHub workflows: use make -j8 -Orecurse + +Without -Orecurse, quiet make output is confusing in parallel mode +because make prints "Entering directory" and "Leaving directory" +messages before and after every target. + +Use parallel compilation also in native.yaml and foreign.yaml. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 2 +- + .github/workflows/build-and-unittest.yaml | 18 +++++++++--------- + .github/workflows/coverity.yaml | 2 +- + .github/workflows/foreign.yaml | 4 ++-- + .github/workflows/native.yaml | 6 +++--- + 5 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 89b971cd..644fcb62 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -32,7 +32,7 @@ jobs: + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev + libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: create ABI +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + - name: save ABI + uses: actions/upload-artifact@v1 + with: +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index a5a0717d..8b6bb776 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -32,11 +32,11 @@ jobs: + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev + libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: build +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test + - name: valgrind-test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + - name: valgrind-results + run: cat tests/*.vgr + - name: clean-nonroot-artifacts +@@ -65,11 +65,11 @@ jobs: + - name: set CC + run: echo CC=gcc-10 >> $GITHUB_ENV + - name: build +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test + - name: valgrind-test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + - name: valgrind-results + run: cat tests/*.vgr + - name: clean-nonroot-artifacts +@@ -98,11 +98,11 @@ jobs: + - name: set CC + run: echo CC=clang >> $GITHUB_ENV + - name: build +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test + - name: valgrind-test +- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test ++ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test + - name: valgrind-results + run: cat tests/*.vgr + - name: clean-nonroot-artifacts +diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml +index 3c6b3824..321b94e0 100644 +--- a/.github/workflows/coverity.yaml ++++ b/.github/workflows/coverity.yaml +@@ -32,7 +32,7 @@ jobs: + - name: build with cov-build + run: > + PATH="$PWD/coverity/bin:$PATH" +- cov-build --dir cov-int make -O -j"$(grep -c ^processor /proc/cpuinfo)" ++ cov-build --dir cov-int make -Orecurse -j"$(grep -c ^processor /proc/cpuinfo)" + - name: pack results + run: tar cfz multipath-tools.tgz cov-int + - name: submit results +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 5a19913a..72ac24fb 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -21,11 +21,11 @@ jobs: + uses: actions/checkout@v1 + - name: build and test + if: ${{ matrix.arch == '' || matrix.arch == '-i386' }} +- run: make test ++ run: make -j8 -Orecurse test + - name: build + if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + # The build path is different between builder and runner +- run: make TESTDIR=${{ github.workspace }}/tests test-progs ++ run: make -j8 -Orecurse TESTDIR=${{ github.workspace }}/tests test-progs + - name: archive + if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} + run: > +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 8b599209..68bf0984 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -92,10 +92,10 @@ jobs: + - name: checkout + uses: actions/checkout@v1 + - name: build and test +- run: make test ++ run: make -j8 -Orecurse test + - name: clean +- run: make clean ++ run: make -j8 -Orecurse clean + - name: clang + env: + CC: clang +- run: make test ++ run: make -j8 -Orecurse test diff --git a/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch b/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch deleted file mode 100644 index fdbb113..0000000 --- a/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Jul 2022 12:45:33 +0200 -Subject: [PATCH] libmultipath.version: bump version for sysfs accessors - -Formally, the ABI is still the same, but the semantics of the -return value have changed. - -Signed-off-by: Martin Wilck - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/libmultipath.version | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index b3690ac0..c1d9b156 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -207,7 +207,6 @@ global: - strchop; - strlcpy; - sync_map_state; -- sysfs_attr_set_value; - sysfs_get_size; - sysfs_is_multipathed; - timespeccmp; -@@ -264,8 +263,13 @@ global: - - /* foreign */ - free_scandir_result; -- sysfs_attr_get_value; - - local: - *; - }; -+ -+LIBMULTIPATH_16.0.0 { -+global: -+ sysfs_attr_set_value; -+ sysfs_attr_get_value; -+}; diff --git a/0023-README.md-Move-section-about-libedit-and-libreadline.patch b/0023-README.md-Move-section-about-libedit-and-libreadline.patch new file mode 100644 index 0000000..b860971 --- /dev/null +++ b/0023-README.md-Move-section-about-libedit-and-libreadline.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 15:40:16 +0200 +Subject: [PATCH] README.md: Move section about libedit and libreadline + +This paragraph belongs in the "Customiting build" section. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/README.md b/README.md +index d003e1db..52ab776b 100644 +--- a/README.md ++++ b/README.md +@@ -53,14 +53,9 @@ Building multipath-tools + ======================== + + Prerequisites: development packages of for `libdevmapper`, `libaio`, `libudev`, +-`libjson-c`, `liburcu`, and `libsystemd`. +- +-To enable commandline history and TAB completion in the interactive mode *(which +-is entered with `multipathd -k` or `multipathc`)* you might also set `READLINE` +-make variable to `libedit` or `libreadline`, like `make READLINE=libreadline`. +-That requires a development package for the library you chose. Note that using +-libreadline may [make binary indistributable due to license +-incompatibility](https://github.com/opensvc/multipath-tools/issues/36). ++`libjson-c`, `liburcu`, and `libsystemd`. If commandline editing is enabled ++(see below), the development package for either `libedit` or `libreadline` is ++required as well. + + Then, build and install multipath-tools with: + +@@ -82,6 +77,12 @@ The following variables can be passed to the `make` command line: + * `configdir="/some/path"` : directory to search for configuration files. + This used to be the run-time option `config_dir` in earlier versions. + The default is `/etc/multipath/conf.d`. ++ * `READLINE=libedit` or `READLINE=libreadline`: enable command line history ++ and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. ++ The respective development package will be required for building. ++ By default, command line editing is disabled. ++ Note that using libreadline may ++ [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). + * `ENABLE_LIBDMMP=0`: disable building libdmmp + * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event + polling API. For use with pre-5.0 kernels that don't support dmevent polling diff --git a/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch b/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch deleted file mode 100644 index b69f395..0000000 --- a/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 7 Jun 2022 17:45:01 -0500 -Subject: [PATCH] libmultipath: unset detect_checker for clariion / Unity - arrays - -Dell EMC would like to always use the emc_clariion checker. Currently -detect_checker will switch the checker to TUR for Unity arrays. -This can cause problems on some setups with replicated Unity LUNs, -which are handled correctly the the emc_checker, but not the TUR -checker. - -Cc: vincent.chen1@dell.com -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/hwtable.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index c88fa09a..2085aba5 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -350,6 +350,7 @@ static struct hwentry default_hw[] = { - .no_path_retry = (300 / DEFAULT_CHECKINT), - .checker_name = EMC_CLARIION, - .prio_name = PRIO_EMC, -+ .detect_checker = DETECT_CHECKER_OFF, - }, - { - /* Invista / VPLEX */ diff --git a/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch b/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch new file mode 100644 index 0000000..63b6c2f --- /dev/null +++ b/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 15:42:15 +0200 +Subject: [PATCH] README.md: Fix indentation in paragraph about device handlers + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/README.md b/README.md +index 52ab776b..b1b78fbb 100644 +--- a/README.md ++++ b/README.md +@@ -94,12 +94,12 @@ The following variables can be passed to the `make` command line: + early. This option causes a *modules-load.d(5)* configuration file to be + created, thus it depends on functionality provided by *systemd*. + This variable only matters for `make install`. +- +-Note: The usefulness of the preload list depends on the kernel configuration. +-It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and +-other device handler modules are built as modules. If `scsi_mod` itself is compiled +-as a module, it might make more sense to use a module softdep for the same +-purpose. ++ ++ **Note**: The usefulness of the preload list depends on the kernel configuration. ++ It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and ++ other device handler modules are built as modules. If `scsi_mod` itself is compiled ++ as a module, it might make more sense to use a module softdep for the same ++ purpose. + + See `Makefile.inc` for additional variables to customize paths and compiler + flags. diff --git a/0024-libmultipath-spelling-cplusplus.patch b/0024-libmultipath-spelling-cplusplus.patch deleted file mode 100644 index bf21a11..0000000 --- a/0024-libmultipath-spelling-cplusplus.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:11:15 -0400 -Subject: [PATCH] libmultipath: spelling: cplusplus - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathvalid/mpath_valid.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -index ed06196e..ec2f9392 100644 ---- a/libmpathvalid/mpath_valid.h -+++ b/libmpathvalid/mpath_valid.h -@@ -20,7 +20,7 @@ - #ifndef LIB_MPATH_VALID_H - #define LIB_MPATH_VALID_H - --#ifdef __cpluscplus -+#ifdef __cplusplus - extern "C" { - #endif - diff --git a/0025-README.md-document-options-for-paths-and-optimizatio.patch b/0025-README.md-document-options-for-paths-and-optimizatio.patch new file mode 100644 index 0000000..ca00d85 --- /dev/null +++ b/0025-README.md-document-options-for-paths-and-optimizatio.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 16:01:17 +0200 +Subject: [PATCH] README.md: document options for paths and optimization + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 25 +++++++++++++++++++++++-- + 1 file changed, 23 insertions(+), 2 deletions(-) + +diff --git a/README.md b/README.md +index b1b78fbb..ab7dc3c9 100644 +--- a/README.md ++++ b/README.md +@@ -101,8 +101,29 @@ The following variables can be passed to the `make` command line: + as a module, it might make more sense to use a module softdep for the same + purpose. + +-See `Makefile.inc` for additional variables to customize paths and compiler +-flags. ++### Installation Paths ++ ++ * `prefix`: The directory prefix for (almost) all files to be installed. ++ Distributions may want to set this to `/usr`. ++ **Note**: for multipath-tools, unlike many other packages, `prefix` ++ defaults to the empty string, which resolves to the root directory (`/`). ++ * `usr_prefix`: where to install those parts of the code that aren't necessary ++ for booting. You may want to set this to `/usr` if `prefix` is empty. ++ * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. ++ Some systemd installations use separate `prefix` and `rootprefix`. On such ++ a distribution, set `prefix`, and override `unitdir` to use systemd's ++ `rootprefix`. ++ * `LIB`: the subdirectory under `prefix` where shared libraries will be ++ installed. By default, the makefile uses `/lib64` if this directory is ++ found on the build system, and `/lib` otherwise. ++ ++See also `configdir` and `plugindir` above. See `Makefile.inc` for more ++fine-grained control. ++ ++### Compiler Options ++ ++Use `OPTFLAGS` to change optimization-related compiler options; ++e.g. `OPTFLAGS="-g -O0"` to disable all optimizations. + + Special Makefile targets + ------------------------ diff --git a/0025-libmultipath-spelling-ascii.patch b/0025-libmultipath-spelling-ascii.patch deleted file mode 100644 index 01e22e4..0000000 --- a/0025-libmultipath-spelling-ascii.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:11:12 -0400 -Subject: [PATCH] libmultipath: spelling: ascii - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/prioritizers/alua_spc3.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h -index 08e992bd..e1a6c071 100644 ---- a/libmultipath/prioritizers/alua_spc3.h -+++ b/libmultipath/prioritizers/alua_spc3.h -@@ -143,7 +143,7 @@ inquiry_data_get_tpgs(struct inquiry_data *id) - *----------------------------------------------------------------------------- - */ - #define CODESET_BINARY 0x1 --#define CODESET_ACSII 0x2 -+#define CODESET_ASCII 0x2 - #define CODESET_UTF8 0x3 - - #define ASSOCIATION_UNIT 0x0 diff --git a/0026-README.md-document-how-to-customize-build.patch b/0026-README.md-document-how-to-customize-build.patch new file mode 100644 index 0000000..c3dfedb --- /dev/null +++ b/0026-README.md-document-how-to-customize-build.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 16:01:41 +0200 +Subject: [PATCH] README.md: document how to customize build + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/README.md b/README.md +index ab7dc3c9..bbeb44fe 100644 +--- a/README.md ++++ b/README.md +@@ -66,9 +66,21 @@ To uninstall, type: + + make uninstall + ++By default, the build will run quietly, just printing one-line messages ++about the files being built. To enable more verbose output, run `make V=1`. ++ + Customizing the build + --------------------- + ++**Note**: With very few exceptions, the build process does not read ++configuration from the environment. So using syntax like ++ ++ SOME_VAR=some_value make ++ ++will **not** have the intended effect. Use the following instead: ++ ++ make SOME_VAR=some_value ++ + The following variables can be passed to the `make` command line: + + * `plugindir="/some/path"`: directory where libmultipath plugins (path diff --git a/0026-libmultipath-spelling-progress.patch b/0026-libmultipath-spelling-progress.patch deleted file mode 100644 index 2984f31..0000000 --- a/0026-libmultipath-spelling-progress.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:11:22 -0400 -Subject: [PATCH] libmultipath: spelling: progress - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/nvme/linux/nvme.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/nvme/linux/nvme.h b/libmultipath/nvme/linux/nvme.h -index a6975549..9fc2ae7f 100644 ---- a/libmultipath/nvme/linux/nvme.h -+++ b/libmultipath/nvme/linux/nvme.h -@@ -1035,7 +1035,7 @@ enum { - NVME_SANITIZE_LOG_STATUS_MASK = 0x0007, - NVME_SANITIZE_LOG_NEVER_SANITIZED = 0x0000, - NVME_SANITIZE_LOG_COMPLETED_SUCCESS = 0x0001, -- NVME_SANITIZE_LOG_IN_PROGESS = 0x0002, -+ NVME_SANITIZE_LOG_IN_PROGRESS = 0x0002, - NVME_SANITIZE_LOG_COMPLETED_FAILED = 0x0003, - NVME_SANITIZE_LOG_ND_COMPLETED_SUCCESS = 0x0004, - }; diff --git a/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch b/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch new file mode 100644 index 0000000..1ae51d8 --- /dev/null +++ b/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 28 Oct 2022 21:10:41 +0200 +Subject: [PATCH] libmultipath: avoid -Warray-bounds error with gcc 12 and musl + libc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The following error is observed with gcc 12, strangely only with +MUSL libc: + +In function ‘__uatomic_inc’, + inlined from ‘lock’ at ../libmultipath/lock.h:24:2, + inlined from ‘child’ at main.c:3523:3, + inlined from ‘main’ at main.c:3755:11: +/usr/include/urcu/uatomic/x86.h:439:17: error: array subscript ‘struct __uatomic_dummy[0]’ is partly outside array bounds of ‘unsigned char[72]’ [-Werror=array-bounds] + +The problem is that &(vecs->lock.waiters) is casted to a pointer to +struct { long[10]; } which goes beyond the "struct vectors". +We don't read or write from/to that memory, but the compiler complains either +way. + +latest liburcu has a patch for it: + +http://git.liburcu.org/?p=userspace-rcu.git;a=commitdiff;h=835b9ab3ca3777fe42e37e92096226ebd19ca75b + +For now, just disable the warning in lock.h, using a pragma. + +Signed-off-by: Martin Wilck +Reported-by: Xose Vasquez Perez +Signed-off-by: Benjamin Marzinski +--- + libmultipath/lock.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libmultipath/lock.h b/libmultipath/lock.h +index 20ca77e6..9814be76 100644 +--- a/libmultipath/lock.h ++++ b/libmultipath/lock.h +@@ -13,6 +13,11 @@ struct mutex_lock { + int waiters; /* uatomic access only */ + }; + ++#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Warray-bounds" ++#endif ++ + static inline void init_lock(struct mutex_lock *a) + { + pthread_mutex_init(&a->mutex, NULL); +@@ -46,6 +51,10 @@ static inline bool lock_has_waiters(struct mutex_lock *a) + return (uatomic_read(&a->waiters) > 0); + } + ++#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 ++#pragma GCC diagnostic pop ++#endif ++ + #define lock_cleanup_pop(a) pthread_cleanup_pop(1) + + void cleanup_lock (void * data); diff --git a/0027-multipath-tools-spelling-fixes.patch b/0027-multipath-tools-spelling-fixes.patch deleted file mode 100644 index c1e9468..0000000 --- a/0027-multipath-tools-spelling-fixes.patch +++ /dev/null @@ -1,599 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josh Soref <2119212+jsoref@users.noreply.github.com> -Date: Sun, 31 Jul 2022 13:17:53 -0400 -Subject: [PATCH] multipath-tools: spelling fixes - -Spelling errors detected by the GitHub check-spelling action: -https://github.com/marketplace/actions/check-spelling - -Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/foreign.yaml | 2 +- - kpartx/crc32.c | 2 +- - kpartx/gpt.c | 2 +- - libdmmp/libdmmp_path.c | 2 +- - libmpathcmd/mpath_cmd.h | 2 +- - libmpathpersist/mpath_persist_int.c | 2 +- - libmpathvalid/mpath_valid.h | 4 ++-- - libmultipath/checkers/directio.c | 2 +- - libmultipath/config.h | 2 +- - libmultipath/configure.c | 2 +- - libmultipath/discovery.c | 2 +- - libmultipath/nvme/nvme.h | 2 +- - libmultipath/prioritizers/datacore.c | 4 ++-- - libmultipath/prioritizers/hds.c | 2 +- - libmultipath/prioritizers/path_latency.c | 4 ++-- - libmultipath/strbuf.h | 4 ++-- - libmultipath/structs_vec.c | 2 +- - libmultipath/uevent.c | 2 +- - libmultipath/valid.h | 2 +- - mpathpersist/main.c | 2 +- - multipath/multipath.conf.5 | 14 +++++++------- - multipathd/main.c | 10 +++++----- - tests/directio.c | 2 +- - tests/hwtable.c | 10 +++++----- - tests/mpathvalid.c | 2 +- - tests/pgpolicy.c | 2 +- - tests/valid.c | 4 ++-- - third-party/valgrind/valgrind.h | 8 ++++---- - 28 files changed, 50 insertions(+), 50 deletions(-) - -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index e9ffd3d8..32915186 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -56,7 +56,7 @@ jobs: - - name: enable foreign arch - run: sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset - - name: run tests -- # Github actions doesn't support referencing docker images with -+ # GitHub actions doesn't support referencing docker images with - # context variables. Workaround: use mosteo-actions/docker-run action - # See https://github.community/t/expressions-in-docker-uri/16271 - uses: mosteo-actions/docker-run@v1 -diff --git a/kpartx/crc32.c b/kpartx/crc32.c -index e688f8e9..df6c6878 100644 ---- a/kpartx/crc32.c -+++ b/kpartx/crc32.c -@@ -290,7 +290,7 @@ uint32_t attribute((pure)) crc32_be(uint32_t crc, unsigned char const *p, size_t - * the end, so we have to add 32 extra cycles shifting in zeros at the - * end of every message, - * -- * So the standard trick is to rearrage merging in the next_input_bit() -+ * So the standard trick is to rearrange merging in the next_input_bit() - * until the moment it's needed. Then the first 32 cycles can be precomputed, - * and merging in the final 32 zero bits to make room for the CRC can be - * skipped entirely. -diff --git a/kpartx/gpt.c b/kpartx/gpt.c -index 34a910cf..47d8743e 100644 ---- a/kpartx/gpt.c -+++ b/kpartx/gpt.c -@@ -357,7 +357,7 @@ is_gpt_valid(int fd, uint64_t lba, - __le32_to_cpu((*gpt)->num_partition_entries) * - __le32_to_cpu((*gpt)->sizeof_partition_entry)); - if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) { -- // printf("GUID Partitition Entry Array CRC check failed.\n"); -+ // printf("GUID Partition Entry Array CRC check failed.\n"); - free(*gpt); - *gpt = NULL; - free(*ptes); -diff --git a/libdmmp/libdmmp_path.c b/libdmmp/libdmmp_path.c -index 47a2162c..21714b15 100644 ---- a/libdmmp/libdmmp_path.c -+++ b/libdmmp/libdmmp_path.c -@@ -28,7 +28,7 @@ - #include "libdmmp_private.h" - - #define _DMMP_SHOW_PS_INDEX_BLK_NAME 0 --#define _DMMP_SHOW_PS_INDEX_SATAUS 1 -+#define _DMMP_SHOW_PS_INDEX_STATUS 1 - #define _DMMP_SHOW_PS_INDEX_WWID 2 - #define _DMMP_SHOW_PS_INDEX_PGID 3 - -diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h -index 30838b02..0c293c71 100644 ---- a/libmpathcmd/mpath_cmd.h -+++ b/libmpathcmd/mpath_cmd.h -@@ -65,7 +65,7 @@ int mpath_connect(void); - /* - * DESCRIPTION: - * Disconnect from the multipathd daemon. This function must be -- * run after after processing all the multipath commands. -+ * run after processing all the multipath commands. - * - * RETURNS: - * 0 on success. -1 on failure (with errno set). -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index e34fc32d..6924b379 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -601,7 +601,7 @@ static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - if (get_be64(mpp->reservation_key) && - memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, - &mpp->reservation_key, 8)){ -- /*register with tarnsport id*/ -+ /*register with transport id*/ - memset(pamp, 0, length); - pamp->trnptid_list[0] = pptr; - memset (pamp->trnptid_list[0], 0, sizeof (struct transportid)); -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -index ec2f9392..3e34b1fd 100644 ---- a/libmpathvalid/mpath_valid.h -+++ b/libmpathvalid/mpath_valid.h -@@ -112,7 +112,7 @@ int mpathvalid_exit(void); - * RETURNS: - * MPATH_STRICT, MPATH_SMART, MPATH_GREEDY, or MPATH_MODE_ERROR - * -- * MPATH_STRICT = find_multiapths (yes|on|no|off) -+ * MPATH_STRICT = find_multipaths (yes|on|no|off) - * MPATH_SMART = find_multipaths smart - * MPATH_GREEDY = find_multipaths greedy - * MPATH_MODE_ERROR = multipath configuration not initialized -@@ -126,7 +126,7 @@ unsigned int mpathvalid_get_mode(void); - * potentially claimed (MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, - * or MPATH_IS_MAYBE_VALID) and wwid is not NULL, then *wiid will - * be set to point to the wwid of device. If set, *wwid must be -- * freed by the caller. path_wwids is an obptional parameter that -+ * freed by the caller. path_wwids is an optional parameter that - * points to an array of wwids, that were returned from previous - * calls to mpathvalid_is_path(). These are wwids of existing - * devices that are or potentially are claimed by device-mapper -diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c -index bc7b7be5..a326e37b 100644 ---- a/libmultipath/checkers/directio.c -+++ b/libmultipath/checkers/directio.c -@@ -124,7 +124,7 @@ remove_aio_group(struct aio_group *aio_grp) - - /* If an aio_group is completely full of orphans, then no checkers can - * use it, which means that no checkers can clear out the orphans. To -- * avoid keeping the useless group around, simply remove remove the -+ * avoid keeping the useless group around, simply remove the - * group */ - static void - check_orphaned_group(struct aio_group *aio_grp) -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 36d40157..fdcdff0a 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -248,7 +248,7 @@ struct config { - * libmultipath calls. If an application wants to keep using the - * udev variable after calling libmultipath_exit(), it should have taken - * an additional reference on it beforehand. This is the case e.g. -- * after initiazing udev with udev_new(). -+ * after initializing udev with udev_new(). - */ - extern struct udev *udev; - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 4427f910..8af7cd79 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -397,7 +397,7 @@ int setup_map(struct multipath *mpp, char **params, struct vectors *vecs) - * into a mp->params strings to feed the device-mapper - */ - if (assemble_map(mpp, params)) { -- condlog(0, "%s: problem assembing map", mpp->alias); -+ condlog(0, "%s: problem assembling map", mpp->alias); - return 1; - } - return 0; -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ee290093..15560f8c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1344,7 +1344,7 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, - condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); - return -EINVAL; - } -- if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ -+ if (in[4] <= 3) /* revision must be > 3 to have Volume Name */ - return -ENODATA; - len = get_unaligned_be32(&in[40]); - if (len > out_len || len + 44 > in_len) { -diff --git a/libmultipath/nvme/nvme.h b/libmultipath/nvme/nvme.h -index 7e0278b5..57f82a31 100644 ---- a/libmultipath/nvme/nvme.h -+++ b/libmultipath/nvme/nvme.h -@@ -224,7 +224,7 @@ char *nvme_char_from_block(char *block); - * Notes: This function does not care about transport so that the offset is - * not going to be checked inside of this function for the unsupported fields - * in a specific transport. For example, BPMBL(Boot Partition Memory Buffer -- * Location) register is not supported by fabrics, but it can be chcked here. -+ * Location) register is not supported by fabrics, but it can be checked here. - */ - static inline bool is_64bit_reg(__u32 offset) - { -diff --git a/libmultipath/prioritizers/datacore.c b/libmultipath/prioritizers/datacore.c -index 02dc2e27..d1d473d4 100644 ---- a/libmultipath/prioritizers/datacore.c -+++ b/libmultipath/prioritizers/datacore.c -@@ -1,6 +1,6 @@ - /* - * (C) 2010 Christophe Varoqui -- * (C) 2009 Dembach Goo Infromatik GmbH & Co KG -+ * (C) 2009 Dembach Goo Informatik GmbH & Co KG - * Manon Goo - * - * datacore.c -@@ -10,7 +10,7 @@ - * Matthias Rudolph - * - * This work is made available on the basis of the -- * GPLv2 for detials see . -+ * GPLv2 for details see . - * - * Manon Goo 2009 - * -diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c -index 88cac5f0..d569f2d7 100644 ---- a/libmultipath/prioritizers/hds.c -+++ b/libmultipath/prioritizers/hds.c -@@ -32,7 +32,7 @@ - * Half of the LUNs are accessed via one HBA/storage controller and the other - * half via the other HBA/storage controller. - * -- * In cluster environmemnts (RAC) it also guarantees that all cluster nodes have -+ * In cluster environments (RAC) it also guarantees that all cluster nodes have - * access to the LDEVs via the same controller. - * - * You can run the prioritizer manually in verbose mode: -diff --git a/libmultipath/prioritizers/path_latency.c b/libmultipath/prioritizers/path_latency.c -index e155f6dc..2f5be9b9 100644 ---- a/libmultipath/prioritizers/path_latency.c -+++ b/libmultipath/prioritizers/path_latency.c -@@ -64,7 +64,7 @@ static int prepare_directio_read(int fd, int *blksz, char **pbuf, - long flags; - - if (ioctl(fd, BLKBSZGET, blksz) < 0) { -- pp_pl_log(3,"catnnot get blocksize, set default"); -+ pp_pl_log(3,"cannot get blocksize, set default"); - *blksz = DEF_BLK_SIZE; - } - if (posix_memalign((void **)pbuf, pgsize, *blksz)) -@@ -193,7 +193,7 @@ out: - } - - /* -- * Do not scale the prioriy in a certain range such as [0, 1024] -+ * Do not scale the priority in a certain range such as [0, 1024] - * because scaling will eliminate the effect of base_num. - */ - int calcPrio(double lg_avglatency, double lg_maxavglatency, -diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h -index 41d7d54f..31ab519a 100644 ---- a/libmultipath/strbuf.h -+++ b/libmultipath/strbuf.h -@@ -159,7 +159,7 @@ int fill_strbuf(struct strbuf *buf, char c, int slen); - * - * Appends the given string to @strbuf, with leading and trailing double - * quotes (") added, expanding @strbuf's size as necessary. Any double quote -- * characters (") in the string are transformed to double double quotes (""). -+ * characters (") in the string are transformed to a pair of double quotes (""). - * If the function returns an error, @strbuf is unchanged. - */ - int append_strbuf_quoted(struct strbuf *buf, const char *str); -@@ -171,7 +171,7 @@ int append_strbuf_quoted(struct strbuf *buf, const char *str); - * @returns: number of appended characters if successful, (excluding - * terminating '\0'); negative error code otherwise - * -- * Appends the the arguments following @fmt, formatted as in printf(), to -+ * Appends the arguments following @fmt, formatted as in printf(), to - * @strbuf, expanding @strbuf's size as necessary. The function makes sure that - * the output @strbuf is always 0-terminated. - * If the function returns an error, @strbuf is unchanged. -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index a69f0643..645896c6 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -205,7 +205,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - continue; - - /* -- * At this point, pp->udev is valid and and pp->wwid -+ * At this point, pp->udev is valid and pp->wwid - * is the best we could get - */ - if (*pp->wwid && strcmp(mpp->wwid, pp->wwid)) { -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index 5793af94..57447ca0 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -373,7 +373,7 @@ uevent_filter(struct uevent *later, struct uevent_filter_state *st) - - list_for_some_entry_reverse_safe(earlier, tmp, &later->node, &st->uevq, node) { - /* -- * filter unnessary earlier uevents -+ * filter unnecessary earlier uevents - * by the later uevent - */ - if (!list_empty(&earlier->merge_node)) { -diff --git a/libmultipath/valid.h b/libmultipath/valid.h -index ce1c7cbf..731e6eff 100644 ---- a/libmultipath/valid.h -+++ b/libmultipath/valid.h -@@ -23,7 +23,7 @@ - * already. - * PATH_IS_VALID is returned by is_path_valid, when the path is - * valid only if it hasn't been released to systemd already. -- * PATH_IS_MAYBE_VALID is returned when the the path would be valid -+ * PATH_IS_MAYBE_VALID is returned when the path would be valid - * if other paths with the same wwid existed. It is up to the caller - * to check for these other paths. - */ -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 4bdd55c2..894e8c94 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -480,7 +480,7 @@ static int handle_args(int argc, char * argv[], int nline) - } - if ((verbose > 2) && num_transportids) - { -- fprintf (stderr, "number of tranport-ids decoded from " -+ fprintf (stderr, "number of transport-ids decoded from " - "command line : %d\n", num_transportids); - } - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index c2d34f18..853e0feb 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -455,7 +455,7 @@ precedence. See KNOWN ISSUES. - (Since kernel 2.6.38) Number of msecs before pg_init retry, it must be between 0 and 60000. - .TP - .I queue_mode --(Since kernel 4.8) Select the the queueing mode per multipath device. -+(Since kernel 4.8) Select the queueing mode per multipath device. - can be \fIbio\fR, \fIrq\fR or \fImq\fR, which corresponds to - bio-based, request-based, and block-multiqueue (blk-mq) request-based, - respectively. -@@ -935,7 +935,7 @@ This option is not supported any more. The value is ignored. - .B san_path_err_threshold - If set to a value greater than 0, multipathd will watch paths and check how many - times a path has been failed due to errors.If the number of failures on a particular --path is greater then the san_path_err_threshold, then the path will not reinstate -+path is greater than the san_path_err_threshold, then the path will not reinstate - till san_path_err_recovery_time. These path failures should occur within a - san_path_err_forget_rate checks, if not we will consider the path is good enough - to reinstantate. See "Shaky paths detection" below. -@@ -949,7 +949,7 @@ The default is: \fBno\fR - .B san_path_err_forget_rate - If set to a value greater than 0, multipathd will check whether the path failures - has exceeded the san_path_err_threshold within this many checks i.e --san_path_err_forget_rate . If so we will not reinstante the path till -+san_path_err_forget_rate . If so we will not reinstate the path till - san_path_err_recovery_time. See "Shaky paths detection" below. - .RS - .TP -@@ -962,7 +962,7 @@ The default is: \fBno\fR - If set to a value greater than 0, multipathd will make sure that when path failures - has exceeded the san_path_err_threshold within san_path_err_forget_rate then the path - will be placed in failed state for san_path_err_recovery_time duration.Once san_path_err_recovery_time --has timeout we will reinstante the failed path . -+has timeout we will reinstate the failed path . - san_path_err_recovery_time value should be in secs. - See "Shaky paths detection" below. - .RS -@@ -1000,7 +1000,7 @@ If the rate of IO error on a particular path is greater than the - \fImarginal_path_err_rate_threshold\fR, then the path will not reinstate for - \fImarginal_path_err_recheck_gap_time\fR seconds unless there is only one - active path. After \fImarginal_path_err_recheck_gap_time\fR expires, the path --will be requeueed for rechecking. If checking result is good enough, the -+will be requeued for rechecking. If checking result is good enough, the - path will be reinstated. See "Shaky paths detection" below. - .RS - .TP -@@ -1031,7 +1031,7 @@ value, the failed path of which the IO error rate is larger than - \fImarginal_path_err_rate_threshold\fR will be kept in failed state for - \fImarginal_path_err_recheck_gap_time\fR seconds. When - \fImarginal_path_err_recheck_gap_time\fR seconds expires, the path will be --requeueed for checking. If checking result is good enough, the path will be -+requeued for checking. If checking result is good enough, the path will be - reinstated, or else it will keep failed. See "Shaky paths detection" below. - .RS - .TP -@@ -1379,7 +1379,7 @@ The protocol that a path is using can be viewed by running - \fBmultipathd show paths format "%d %P"\fR - .RE - .LP --For every device, these 5 blacklist criteria are evaluated in the the order -+For every device, these 5 blacklist criteria are evaluated in the order - "property, dev\%node, device, protocol, wwid". If a device turns out to be - blacklisted by any criterion, it's excluded from handling by multipathd, and - the later criteria aren't evaluated any more. For each -diff --git a/multipathd/main.c b/multipathd/main.c -index a160c824..defee10a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -583,7 +583,7 @@ retry: - if (mpp->prflag) { - vector_foreach_slot(mpp->paths, pp, i) { - if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { -- /* persistent reseravtion check*/ -+ /* persistent reservation check*/ - mpath_pr_event_handle(pp); - } - } -@@ -1515,7 +1515,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - condlog(3, "%s: error in change_foreign", __func__); - break; - default: -- condlog(1, "%s: return code %d of change_forein is unsupported", -+ condlog(1, "%s: return code %d of change_foreign is unsupported", - __func__, rc); - break; - } -@@ -1966,7 +1966,7 @@ ghost_delay_tick(struct vectors *vecs) - } - - static void --defered_failback_tick (vector mpvec) -+deferred_failback_tick (vector mpvec) - { - struct multipath * mpp; - unsigned int i; -@@ -2186,7 +2186,7 @@ static int check_path_reinstate_state(struct path * pp) { - get_monotonic_time(&curr_time); - /* when path failures has exceeded the san_path_err_threshold - * place the path in delayed state till san_path_err_recovery_time -- * so that the cutomer can rectify the issue within this time. After -+ * so that the customer can rectify the issue within this time. After - * the completion of san_path_err_recovery_time it should - * automatically reinstate the path - * (note: we know that san_path_err_threshold > 0 here). -@@ -2647,7 +2647,7 @@ checkerloop (void *ap) - pthread_cleanup_push(cleanup_lock, &vecs->lock); - lock(&vecs->lock); - pthread_testcancel(); -- defered_failback_tick(vecs->mpvec); -+ deferred_failback_tick(vecs->mpvec); - retry_count_tick(vecs->mpvec); - missing_uev_wait_tick(vecs); - ghost_delay_tick(vecs); -diff --git a/tests/directio.c b/tests/directio.c -index 20ccc47a..01fdef28 100644 ---- a/tests/directio.c -+++ b/tests/directio.c -@@ -497,7 +497,7 @@ static void test_free_with_pending(void **state) - do_libcheck_reset(1); - } - --/* test removing orpahed aio_group on free */ -+/* test removing orphaned aio_group on free */ - static void test_orphaned_aio_group(void **state) - { - struct checker c[AIO_GROUP_SIZE] = {{.cls = NULL}}; -diff --git a/tests/hwtable.c b/tests/hwtable.c -index bfaf613f..334b75e8 100644 ---- a/tests/hwtable.c -+++ b/tests/hwtable.c -@@ -29,7 +29,7 @@ - - #define N_CONF_FILES 2 - --static const char tmplate[] = "/tmp/hwtable-XXXXXX"; -+static const char template[] = "/tmp/hwtable-XXXXXX"; - - struct key_value { - const char *key; -@@ -136,7 +136,7 @@ static int setup(void **state) - if (hwt == NULL) - return -1; - -- snprintf(buf, sizeof(buf), "%s", tmplate); -+ snprintf(buf, sizeof(buf), "%s", template); - if (mkdtemp(buf) == NULL) { - condlog(0, "mkdtemp: %s", strerror(errno)); - goto err; -@@ -255,7 +255,7 @@ static void write_defaults(const struct hwt_state *hwt) - { "detect_prio", "no" }, - { "detect_checker", "no" }, - }; -- char buf[sizeof(tmplate) + sizeof(bindings_name)]; -+ char buf[sizeof(template) + sizeof(bindings_name)]; - char dirbuf[PATH_MAX]; - - snprintf(buf, sizeof(buf), "%s/%s", hwt->tmpname, bindings_name); -@@ -308,7 +308,7 @@ static void write_device(FILE *ff, int nkv, const struct key_value *kv) - } - - /* -- * Some macros to avoid boilerplace code -+ * Some macros to avoid boilerplate code - */ - - #define CHECK_STATE(state) ({ \ -@@ -448,7 +448,7 @@ static const struct key_value npr_queue = { _no_path_retry, "queue" }; - /***** BEGIN TESTS SECTION *****/ - - /* -- * Dump the configuration, subistitute the dumped configuration -+ * Dump the configuration, substitute the dumped configuration - * for the current one, and verify that the result is identical. - */ - static void replicate_config(const struct hwt_state *hwt, bool local) -diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c -index 0230a88f..df66ed6a 100644 ---- a/tests/mpathvalid.c -+++ b/tests/mpathvalid.c -@@ -399,7 +399,7 @@ static void test_mpathvalid_is_path_good3(void **state) - free(wwid); - } - --/* mabybe valid with no matching paths */ -+/* maybe valid with no matching paths */ - static void test_mpathvalid_is_path_good4(void **state) - { - const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; -diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c -index f116d12c..43be831f 100644 ---- a/tests/pgpolicy.c -+++ b/tests/pgpolicy.c -@@ -191,7 +191,7 @@ verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, - /* Test names instead of pointers to get a more - * useful error message */ - assert_string_equal(pgp_path->dev, pp_path->dev); -- /* This test is just a backkup in case the -+ /* This test is just a backup in case the - * something wenth wrong naming the paths */ - assert_ptr_equal(pgp_path, pp_path); - } -diff --git a/tests/valid.c b/tests/valid.c -index e7393a1c..398b771e 100644 ---- a/tests/valid.c -+++ b/tests/valid.c -@@ -293,7 +293,7 @@ static void test_sysfs_is_multipathed(void **state) - - memset(&pp, 0, sizeof(pp)); - conf.find_multipaths = FIND_MULTIPATHS_STRICT; -- /* test for already existing multiapthed device */ -+ /* test for already existing multipathed device */ - will_return(__wrap_sysfs_is_multipathed, true); - will_return(__wrap_sysfs_is_multipathed, wwid); - assert_int_equal(is_path_valid(name, &conf, &pp, true), -@@ -452,7 +452,7 @@ static void test_greedy(void **state) - assert_string_equal(pp.dev, name); - assert_ptr_equal(pp.udev, &test_udev); - assert_string_equal(pp.wwid, wwid); -- /* test greedy success without checking multiapthd */ -+ /* test greedy success without checking multipathd */ - memset(&pp, 0, sizeof(pp)); - setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); - assert_int_equal(is_path_valid(name, &conf, &pp, false), -diff --git a/third-party/valgrind/valgrind.h b/third-party/valgrind/valgrind.h -index 577c8f05..1633b318 100644 ---- a/third-party/valgrind/valgrind.h -+++ b/third-party/valgrind/valgrind.h -@@ -1075,7 +1075,7 @@ typedef - - /* Use these to write the name of your wrapper. NOTE: duplicates - VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts -- the default behaviour equivalance class tag "0000" into the name. -+ the default behaviour equivalence class tag "0000" into the name. - See pub_tool_redir.h for details -- normally you don't need to - think about this, though. */ - -@@ -1620,11 +1620,11 @@ typedef - and say that %r15 is trashed instead. gcc seems happy to go with - that. - -- Oh .. and this all needs to be conditionalised so that it is -+ Oh .. and this all needs to be conditionalized so that it is - unchanged from before this commit, when compiled with older gccs - that don't support __builtin_dwarf_cfa. Furthermore, since - this header file is freestanding, it has to be independent of -- config.h, and so the following conditionalisation cannot depend on -+ config.h, and so the following conditionalization cannot depend on - configure time checks. - - Although it's not clear from -@@ -1673,7 +1673,7 @@ typedef - /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ - macros. In order not to trash the stack redzone, we need to drop - %rsp by 128 before the hidden call, and restore afterwards. The -- nastyness is that it is only by luck that the stack still appears -+ nastiness is that it is only by luck that the stack still appears - to be unwindable during the hidden call - since then the behaviour - of any routine using this macro does not match what the CFI data - says. Sigh. diff --git a/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch b/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch new file mode 100644 index 0000000..2be93fc --- /dev/null +++ b/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 27 Sep 2022 12:14:09 +0200 +Subject: [PATCH] multipath: avoid NULL string in released_to_systemd() + +Fixes: b28c406 ("multipath -u: don't grab devices already passed to system") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 7b69a3ce..b9f360b4 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -435,7 +435,8 @@ static bool released_to_systemd(void) + bool ret; + + ret = dm_mp_dev_path != NULL && !strcmp(dm_mp_dev_path, "0"); +- condlog(4, "%s: %s=%s -> %d", __func__, dmdp, dm_mp_dev_path, ret); ++ condlog(4, "%s: %s=%s -> %d", __func__, dmdp, ++ dm_mp_dev_path ? dm_mp_dev_path : "", ret); + return ret; + } + diff --git a/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch b/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch deleted file mode 100644 index f2dbfce..0000000 --- a/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Thu, 21 Jul 2022 19:22:04 +0200 -Subject: [PATCH] multipath-tools: remove list of rebranded arrays vendors from - man page - -It does not provide useful info, and it is incomplete. - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 853e0feb..8b7dc511 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -315,12 +315,12 @@ accepts the optional prio_arg \fIexclusive_pref_bit\fR. - .TP - .I ontap - (Hardware-dependent) --Generate the path priority for NetApp ONTAP class and OEM arrays as IBM NSeries. -+Generate the path priority for NetApp ONTAP class, and rebranded arrays. - .TP - .I rdac - (Hardware-dependent) - Generate the path priority for LSI/Engenio/NetApp RDAC class as NetApp SANtricity --E/EF Series, and OEM arrays from IBM DELL SGI STK and SUN. -+E/EF Series, and rebranded arrays. - .TP - .I hp_sw - (Hardware-dependent) -@@ -496,7 +496,7 @@ Active/Standby mode exclusively. - .I rdac - (Hardware-dependent) - Check the path state for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF --Series, and OEM arrays from IBM DELL SGI STK and SUN. -+Series, and rebranded arrays. - .TP - .I directio - Read the first sector with direct I/O. This checker could cause spurious path -@@ -1568,7 +1568,7 @@ families. - .I 1 rdac - (Hardware-dependent) - Hardware handler for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF --Series, and OEM arrays from IBM DELL SGI STK and SUN. -+Series, and rebranded arrays. - .TP - .I 1 hp_sw - (Hardware-dependent) diff --git a/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch b/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch new file mode 100644 index 0000000..e48d44c --- /dev/null +++ b/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 27 Sep 2022 12:28:26 +0200 +Subject: [PATCH] libmultipath: avoid NULL string in is_udev_ready() + +Fixes: 2b25a9e ("libmultipath: select_action(): force udev reload for uninitialized maps") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e5249fc1..e551047a 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -662,7 +662,8 @@ static bool is_udev_ready(struct multipath *cmpp) + env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY"); + rc = (env != NULL && !strcmp(env, "1")); + udev_device_unref(mpp_ud); +- condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc); ++ condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, ++ env ? env : "", rc); + return rc; + } + diff --git a/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch b/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch deleted file mode 100644 index 8777ea1..0000000 --- a/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 23 Jul 2022 00:01:13 +0200 -Subject: [PATCH] multipath-tools: correct CLARiiON info from multipath.conf - man page - -Remove "Unity" from emc prio and hardware_handler, because -Unity does not support PNR mode, just ALUA (page 113 and 153): -https://www.delltechnologies.com/asset/en-us/products/storage/technical-support/docu5128.pdf -And add PNR info. - -Cc: Yanfei Chen -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 8b7dc511..acdd1ae6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -306,7 +306,7 @@ generate the path priority. This prioritizer accepts the optional prio_arg - .I emc - (Hardware-dependent) - Generate the path priority for DGC class arrays as CLARiiON CX/AX and --EMC VNX and Unity families. -+EMC VNX families with Failover Mode 1 (Passive Not Ready(PNR)). - .TP - .I alua - (Hardware-dependent) -@@ -1562,8 +1562,8 @@ The following hardware handler are implemented: - .TP 12 - .I 1 emc - (Hardware-dependent) --Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX and Unity --families. -+Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX families -+with Failover Mode 1 (Passive Not Ready(PNR)). - .TP - .I 1 rdac - (Hardware-dependent) diff --git a/0030-libmultipath-impove-add_feature-variable-names.patch b/0030-libmultipath-impove-add_feature-variable-names.patch new file mode 100644 index 0000000..9cc841d --- /dev/null +++ b/0030-libmultipath-impove-add_feature-variable-names.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 9 Nov 2022 15:49:41 -0600 +Subject: [PATCH] libmultipath: impove add_feature() variable names + +Use descriptive names, instead of single letters. No functional changes. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/structs.c | 63 +++++++++++++++++++++--------------------- + 1 file changed, 32 insertions(+), 31 deletions(-) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 7a2ff589..f90bd0b6 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -604,65 +604,66 @@ first_path (const struct multipath * mpp) + return pgp?VECTOR_SLOT(pgp->paths, 0):NULL; + } + +-int add_feature(char **f, const char *n) ++int add_feature(char **features_p, const char *new_feat) + { +- int c = 0, d, l; +- char *e, *t; +- const char *p; ++ int count = 0, new_count, len; ++ char *tmp, *feats; ++ const char *ptr; + +- if (!f) ++ if (!features_p) + return 1; + + /* Nothing to do */ +- if (!n || *n == '\0') ++ if (!new_feat || *new_feat == '\0') + return 0; + +- l = strlen(n); +- if (isspace(*n) || isspace(*(n + l - 1))) { +- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n); ++ len = strlen(new_feat); ++ if (isspace(*new_feat) || isspace(*(new_feat + len - 1))) { ++ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", ++ new_feat); + return 1; + } + +- p = n; +- d = 1; +- while (*p != '\0') { +- if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0') +- d++; +- p++; ++ ptr = new_feat; ++ new_count = 1; ++ while (*ptr != '\0') { ++ if (isspace(*ptr) && !isspace(*(ptr + 1)) && *(ptr + 1) != '\0') ++ new_count++; ++ ptr++; + } + + /* default feature is null */ +- if(!*f) ++ if(!*features_p) + { +- l = asprintf(&t, "%0d %s", d, n); +- if(l == -1) ++ len = asprintf(&feats, "%0d %s", new_count, new_feat); ++ if(len == -1) + return 1; + +- *f = t; ++ *features_p = feats; + return 0; + } + + /* Check if feature is already present */ +- e = *f; +- while ((e = strstr(e, n)) != NULL) { +- if (isspace(*(e - 1)) && +- (isspace(*(e + l)) || *(e + l) == '\0')) ++ tmp = *features_p; ++ while ((tmp = strstr(tmp, new_feat)) != NULL) { ++ if (isspace(*(tmp - 1)) && ++ (isspace(*(tmp + len)) || *(tmp + len) == '\0')) + return 0; +- e += l; ++ tmp += len; + } + + /* Get feature count */ +- c = strtoul(*f, &e, 10); +- if (*f == e || (!isspace(*e) && *e != '\0')) { +- condlog(0, "parse error in feature string \"%s\"", *f); ++ count = strtoul(*features_p, &tmp, 10); ++ if (*features_p == tmp || (!isspace(*tmp) && *tmp != '\0')) { ++ condlog(0, "parse error in feature string \"%s\"", *features_p); + return 1; + } +- c += d; +- if (asprintf(&t, "%0d%s %s", c, e, n) < 0) ++ count += new_count; ++ if (asprintf(&feats, "%0d%s %s", count, tmp, new_feat) < 0) + return 1; + +- free(*f); +- *f = t; ++ free(*features_p); ++ *features_p = feats; + + return 0; + } diff --git a/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch b/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch deleted file mode 100644 index 592be10..0000000 --- a/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sat, 23 Jul 2022 15:12:04 +0200 -Subject: [PATCH] multipath-tools: add basic info on how to use multipath-tools - with NVMe devices - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/README.md b/README.md -index 2322082c..b05b1332 100644 ---- a/README.md -+++ b/README.md -@@ -174,3 +174,19 @@ To enable ALUA, the following options should be changed: - - - Huawei OceanStor: - "Host Access Mode" should be changed to "Asymmetric". -+ -+ -+NVMe -+==== -+To use Device Mapper/multipath-tools with NVMe devices, -+if the Native NVMe Multipath subsystem is enabled -+( "Y" in `/sys/module/nvme_core/parameters/multipath` ), -+it has to be disabled: -+ -+`echo "options nvme_core multipath=N" > /etc/modprobe.d/01-nvme_core-mp.conf`, -+regenerate the initramfs (`dracut -f` or `update-initramfs`) and reboot. -+ -+Check that it is disabled(N) with: -+`cat /sys/module/nvme_core/parameters/multipath` -+or -+`systool -m nvme_core -A multipath` diff --git a/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch b/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch new file mode 100644 index 0000000..6dc8a0e --- /dev/null +++ b/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 9 Nov 2022 15:49:42 -0600 +Subject: [PATCH] multipathd: don't initialize the field width in show_path() + +It's not used, so don't set it up. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/cli_handlers.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 5f0dd04e..e65fb75c 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -67,12 +67,7 @@ static int + show_path (struct strbuf *reply, struct vectors *vecs, struct path *pp, + char *style) + { +- fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL; +- +- if ((width = alloc_path_layout()) == NULL) +- return 1; +- get_path_layout(vecs->pathvec, 1, width); +- if (snprint_path(reply, style, pp, 0) < 0) ++ if (snprint_path(reply, style, pp, NULL) < 0) + return 1; + return 0; + } diff --git a/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch b/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch deleted file mode 100644 index bb8aa05..0000000 --- a/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:26 -0500 -Subject: [PATCH] multipathd: factor out the code to flush a map with no paths - -The code to flush a multipath device because all of its paths have -been removed will be used by another caller, so factor it out of -ev_remove_path(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 56 ++++++++++++++++++++++++----------------------- - 1 file changed, 29 insertions(+), 27 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index defee10a..53cbdb61 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -561,6 +561,30 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset) - return 0; - } - -+static bool -+flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { -+ char alias[WWID_SIZE]; -+ -+ /* -+ * flush_map will fail if the device is open -+ */ -+ strlcpy(alias, mpp->alias, WWID_SIZE); -+ if (mpp->flush_on_last_del == FLUSH_ENABLED) { -+ condlog(2, "%s Last path deleted, disabling queueing", -+ mpp->alias); -+ mpp->retry_tick = 0; -+ mpp->no_path_retry = NO_PATH_RETRY_FAIL; -+ mpp->disable_queueing = 1; -+ mpp->stat_map_failures++; -+ dm_queue_if_no_path(mpp->alias, 0); -+ } -+ if (!flush_map(mpp, vecs, 1)) { -+ condlog(2, "%s: removed map after removing all paths", alias); -+ return true; -+ } -+ return false; -+} -+ - static int - update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - { -@@ -1363,34 +1387,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - vector_del_slot(mpp->paths, i); - - /* -- * remove the map IF removing the last path -+ * remove the map IF removing the last path. If -+ * flush_map_nopaths succeeds, the path has been removed. - */ -- if (VECTOR_SIZE(mpp->paths) == 0) { -- char alias[WWID_SIZE]; -- -- /* -- * flush_map will fail if the device is open -- */ -- strlcpy(alias, mpp->alias, WWID_SIZE); -- if (mpp->flush_on_last_del == FLUSH_ENABLED) { -- condlog(2, "%s Last path deleted, disabling queueing", mpp->alias); -- mpp->retry_tick = 0; -- mpp->no_path_retry = NO_PATH_RETRY_FAIL; -- mpp->disable_queueing = 1; -- mpp->stat_map_failures++; -- dm_queue_if_no_path(mpp->alias, 0); -- } -- if (!flush_map(mpp, vecs, 1)) { -- condlog(2, "%s: removed map after" -- " removing all paths", -- alias); -- /* flush_map() has freed the path */ -- goto out; -- } -- /* -- * Not an error, continue -- */ -- } -+ if (VECTOR_SIZE(mpp->paths) == 0 && -+ flush_map_nopaths(mpp, vecs)) -+ goto out; - - if (setup_map(mpp, ¶ms, vecs)) { - condlog(0, "%s: failed to setup map for" diff --git a/0032-libmultipath-improve-remove_feature-variable-names.patch b/0032-libmultipath-improve-remove_feature-variable-names.patch new file mode 100644 index 0000000..c1642d4 --- /dev/null +++ b/0032-libmultipath-improve-remove_feature-variable-names.patch @@ -0,0 +1,144 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 9 Nov 2022 15:49:43 -0600 +Subject: [PATCH] libmultipath: improve remove_feature() variable names + +Use descriptive names, instead of single letters. No functional changes. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/structs.c | 80 +++++++++++++++++++++--------------------- + 1 file changed, 40 insertions(+), 40 deletions(-) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index f90bd0b6..87e84d5d 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -668,86 +668,86 @@ int add_feature(char **features_p, const char *new_feat) + return 0; + } + +-int remove_feature(char **f, const char *o) ++int remove_feature(char **features_p, const char *old_feat) + { +- int c = 0, d; +- char *e, *p, *n; +- const char *q; ++ int count = 0, len; ++ char *feats_start, *ptr, *new; + +- if (!f || !*f) ++ if (!features_p || !*features_p) + return 1; + + /* Nothing to do */ +- if (!o || *o == '\0') ++ if (!old_feat || *old_feat == '\0') + return 0; + +- d = strlen(o); +- if (isspace(*o) || isspace(*(o + d - 1))) { +- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", o); ++ len = strlen(old_feat); ++ if (isspace(*old_feat) || isspace(*(old_feat + len - 1))) { ++ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", ++ old_feat); + return 1; + } + + /* Check if present and not part of a larger feature token*/ +- p = *f + 1; /* the size must be at the start of the features string */ +- while ((p = strstr(p, o)) != NULL) { +- if (isspace(*(p - 1)) && +- (isspace(*(p + d)) || *(p + d) == '\0')) ++ ptr = *features_p + 1; ++ while ((ptr = strstr(ptr, old_feat)) != NULL) { ++ if (isspace(*(ptr - 1)) && ++ (isspace(*(ptr + len)) || *(ptr + len) == '\0')) + break; +- p += d; ++ ptr += len; + } +- if (!p) ++ if (!ptr) + return 0; + + /* Get feature count */ +- c = strtoul(*f, &e, 10); +- if (*f == e || !isspace(*e)) { +- condlog(0, "parse error in feature string \"%s\"", *f); ++ count = strtoul(*features_p, &feats_start, 10); ++ if (*features_p == feats_start || !isspace(*feats_start)) { ++ condlog(0, "parse error in feature string \"%s\"", *features_p); + return 1; + } + + /* Update feature count */ +- c--; +- q = o; +- while (*q != '\0') { +- if (isspace(*q) && !isspace(*(q + 1)) && *(q + 1) != '\0') +- c--; +- q++; ++ count--; ++ while (*old_feat != '\0') { ++ if (isspace(*old_feat) && !isspace(*(old_feat + 1)) && ++ *(old_feat + 1) != '\0') ++ count--; ++ old_feat++; + } + + /* Quick exit if all features have been removed */ +- if (c == 0) { +- n = malloc(2); +- if (!n) ++ if (count == 0) { ++ new = malloc(2); ++ if (!new) + return 1; +- strcpy(n, "0"); ++ strcpy(new, "0"); + goto out; + } + + /* Update feature count space */ +- n = malloc(strlen(*f) - d + 1); +- if (!n) ++ new = malloc(strlen(*features_p) - len + 1); ++ if (!new) + return 1; + + /* Copy the feature count */ +- sprintf(n, "%0d", c); ++ sprintf(new, "%0d", count); + /* + * Copy existing features up to the feature + * about to be removed + */ +- strncat(n, e, (size_t)(p - e)); ++ strncat(new, feats_start, (size_t)(ptr - feats_start)); + /* Skip feature to be removed */ +- p += d; ++ ptr += len; + /* Copy remaining features */ +- while (isspace(*p)) +- p++; +- if (*p != '\0') +- strcat(n, p); ++ while (isspace(*ptr)) ++ ptr++; ++ if (*ptr != '\0') ++ strcat(new, ptr); + else +- strchop(n); ++ strchop(new); + + out: +- free(*f); +- *f = n; ++ free(*features_p); ++ *features_p = new; + + return 0; + } diff --git a/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch b/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch deleted file mode 100644 index ab04fd9..0000000 --- a/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:27 -0500 -Subject: [PATCH] libmultipath: return success if we raced to remove a map and - lost - -_dm_flush_map() was returning failure if it failed to remove a map, -even if that was because the map had already been removed. Return -success in this case. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/devmapper.c | 4 ++++ - multipathd/main.c | 4 ---- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 1748d258..a49db3b0 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1111,6 +1111,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - } - condlog(4, "multipath map %s removed", mapname); - return 0; -+ } else if (dm_is_mpath(mapname) != 1) { -+ condlog(4, "multipath map %s removed externally", -+ mapname); -+ return 0; /*we raced with someone else removing it */ - } else { - condlog(2, "failed to remove multipath map %s", - mapname); -diff --git a/multipathd/main.c b/multipathd/main.c -index 53cbdb61..3fcd6bdb 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -758,10 +758,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - * the spurious uevent we may generate with the dm_flush_map call below - */ - if (r) { -- /* -- * May not really be an error -- if the map was already flushed -- * from the device mapper by dmsetup(8) for instance. -- */ - if (r == 1) - condlog(0, "%s: can't flush", mpp->alias); - else { diff --git a/0033-RH-fixup-udev-rules-for-redhat.patch b/0033-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..f0fc0d2 --- /dev/null +++ b/0033-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 13 Apr 2017 07:22:23 -0500 +Subject: [PATCH] RH: fixup udev rules for redhat + +The multipath rules need to run after scsi_id is run. This means moving +them after 60-persistent-storage.rules for redhat. Redhat also uses a +different naming scheme for partitions than SuSE. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 4 ++-- + kpartx/kpartx.rules | 2 +- + multipath/Makefile | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 866ab274..8c5a08a2 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -34,9 +34,9 @@ endif + # Paths. All these can be overridden on the "make" command line. + prefix := + # Prefix for binaries +-exec_prefix := $(prefix) ++exec_prefix := $(prefix)/usr + # Prefix for non-essential libraries (libdmmp) +-usr_prefix := $(prefix) ++usr_prefix := $(prefix)/usr + # Where to install systemd-related files. systemd is usually installed under /usr + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 1969dee0..d2b28233 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" + GOTO="kpartx_end" + + LABEL="run_kpartx" +-RUN+="/sbin/kpartx -un -p -part /dev/$name" ++RUN+="/sbin/kpartx -un /dev/$name" + + LABEL="kpartx_end" +diff --git a/multipath/Makefile b/multipath/Makefile +index 73db991a..b3c2cc81 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -24,7 +24,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) +- $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules ++ $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) + $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) +@@ -44,7 +44,7 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +- $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + diff --git a/0033-multipathd-Handle-losing-all-path-in-update_map.patch b/0033-multipathd-Handle-losing-all-path-in-update_map.patch deleted file mode 100644 index 43358d3..0000000 --- a/0033-multipathd-Handle-losing-all-path-in-update_map.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:28 -0500 -Subject: [PATCH] multipathd: Handle losing all path in update_map - -Its possible that when a multipath device is being updated, it will end -up that all the paths for it are gone. This can happen if paths are -added and then removed again before multipathd processes the uevent for -the newly created multipath device. In this case multipathd wasn't -taking the proper action for the case where all the paths had been -removed. If flush_on_last_del was set, multipathd wasn't disabling -flushing and if deferred_remove was set, it wasn't doing a deferred -remove. Multipathd should call flush_map_nopaths(), just like -ev_remove_path() does when the last path is removed. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 3fcd6bdb..7d127dbe 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -602,6 +602,10 @@ retry: - goto fail; - } - verify_paths(mpp); -+ if (VECTOR_SIZE(mpp->paths) == 0 && -+ flush_map_nopaths(mpp, vecs)) -+ return 1; -+ - mpp->action = ACT_RELOAD; - - if (mpp->prflag) { diff --git a/0044-RH-Remove-the-property-blacklist-exception-builtin.patch b/0034-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0044-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0034-RH-Remove-the-property-blacklist-exception-builtin.patch index ded9aab..feef3f6 100644 --- a/0044-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0034-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,10 +43,10 @@ index 8d15d2ea..eff690fd 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index acdd1ae6..5ab770ba 100644 +index 1fea9d5a..eef3c605 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1348,9 +1348,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1353,9 +1353,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -62,7 +62,7 @@ index acdd1ae6..5ab770ba 100644 . .RS .PP -@@ -1361,10 +1366,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1366,10 +1371,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0034-multipath-fix-systemd-timers-in-the-initramfs.patch b/0034-multipath-fix-systemd-timers-in-the-initramfs.patch deleted file mode 100644 index 91178ea..0000000 --- a/0034-multipath-fix-systemd-timers-in-the-initramfs.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 5 Aug 2022 18:16:03 -0500 -Subject: [PATCH] multipath: fix systemd timers in the initramfs - -The systemd timers created for "find_multipaths smart" conflict with -shutdown.target, but not with initrd-cleanup.service. This can make -these timers trigger after the inirtd has started shutting down, -restarting multipathd (which then stops initrd-cleanup.service, since it -conflicts). To avoid this, make sure the timers and the unit they -trigger conflict with inird-cleanup.service. Also don't make them start -multipathd. "multipath -u" will not return "maybe" if multipathd isn't -running or set to run, and since we no longer wait for udev-settle, -multipathd starts up pretty quickly, so it shouldn't be a problem to -not trigger it here. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipath/multipath.rules | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 9df11a95..f993d996 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules -@@ -71,7 +71,7 @@ ENV{.SAVED_FM_WAIT_UNTIL}=="?*", GOTO="pretend_mpath" - # - # We must trigger an "add" event because LVM2 will only act on those. - --RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Wants=multipathd.service --property After=multipathd.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" -+RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property Conflicts=initrd-cleanup.service --timer-property Before=initrd-cleanup.service --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Conflicts=initrd-cleanup.service --property Before=initrd-cleanup.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" - - LABEL="pretend_mpath" - ENV{DM_MULTIPATH_DEVICE_PATH}="1" diff --git a/0045-RH-don-t-start-without-a-config-file.patch b/0035-RH-don-t-start-without-a-config-file.patch similarity index 83% rename from 0045-RH-don-t-start-without-a-config-file.patch rename to 0035-RH-don-t-start-without-a-config-file.patch index dda921b..c957e2f 100644 --- a/0045-RH-don-t-start-without-a-config-file.patch +++ b/0035-RH-don-t-start-without-a-config-file.patch @@ -14,17 +14,17 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 13 +++++++++++++ libmultipath/config.h | 1 + - multipath/multipath.rules | 1 + + multipath/multipath.rules.in | 1 + multipathd/multipathd.8 | 2 ++ multipathd/multipathd.service | 1 + multipathd/multipathd.socket | 1 + 6 files changed, 19 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index ab8b26e7..f06fcbf9 100644 +index 5c5c0726..183b319d 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -955,6 +955,19 @@ int _init_config (const char *file, struct config *conf) +@@ -966,6 +966,19 @@ int _init_config (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -45,10 +45,10 @@ index ab8b26e7..f06fcbf9 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index fdcdff0a..affba937 100644 +index 87947469..0dc89c16 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h -@@ -9,6 +9,7 @@ +@@ -10,6 +10,7 @@ #define ORIGIN_DEFAULT 0 #define ORIGIN_CONFIG 1 @@ -56,10 +56,10 @@ index fdcdff0a..affba937 100644 enum devtypes { DEV_NONE, -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index f993d996..68c30644 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules +diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in +index 8d3cf33a..5c4447a2 100644 +--- a/multipath/multipath.rules.in ++++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" ENV{nompath}=="?*", GOTO="end_mpath" IMPORT{cmdline}="multipath" @@ -69,13 +69,13 @@ index f993d996..68c30644 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index 1e318bdc..6aab9325 100644 +index bdf102eb..a16a0bd5 100644 --- a/multipathd/multipathd.8 +++ b/multipathd/multipathd.8 -@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. - This daemon executes the external \fBmultipath\fR tool when events occur. - In turn, the multipath tool signals the multipathd daemon when it is done with - devmap reconfiguration, so that it can refresh its failed path list. +@@ -48,6 +48,8 @@ map regains its maximum performance and redundancy. + With the \fB-k\fR option, \fBmultipathd\fR acts as a client utility that + sends commands to a running instance of the multipathd daemon (see + \fBCOMMANDS\fR below). + +In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. . diff --git a/0035-multipathd-Add-missing-ctype-include.patch b/0035-multipathd-Add-missing-ctype-include.patch deleted file mode 100644 index 29ea453..0000000 --- a/0035-multipathd-Add-missing-ctype-include.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Bastian Germann -Date: Thu, 14 Oct 2021 00:34:33 +0200 -Subject: [PATCH] multipathd: Add missing ctype include - -In uxclnt.c, there are isspace calls. Add an explicit include. - -Signed-off-by: Bastian Germann -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/uxclnt.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c -index b1b058bd..bdcc7c3f 100644 ---- a/multipathd/uxclnt.c -+++ b/multipathd/uxclnt.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/0046-RH-Fix-nvme-function-missing-argument.patch b/0036-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0046-RH-Fix-nvme-function-missing-argument.patch rename to 0036-RH-Fix-nvme-function-missing-argument.patch diff --git a/0036-multipathd-replace-libreadline-with-libedit.patch b/0036-multipathd-replace-libreadline-with-libedit.patch deleted file mode 100644 index f376ee7..0000000 --- a/0036-multipathd-replace-libreadline-with-libedit.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 12 Aug 2022 18:58:15 +0200 -Subject: [PATCH] multipathd: replace libreadline with libedit - -Linking multipathd with libreadline may cause a license conflict, -because libreadline is licensed under GPL-3.0-or-later, and -libmultipath contains several files under GPL-2.0. - -See: - https://github.com/opensvc/multipath-tools/issues/36 - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=979095 - https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility - -Replace the readline functionality with libedit, which comes under -a BSD license. The readline library can still be enabled (e.g. for -binaries not intended to be distributed) by running -"make READLINE=libreadline". - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 5 +++++ - multipathd/Makefile | 11 ++++++++++- - multipathd/cli.c | 5 +++++ - multipathd/uxclnt.c | 6 ++++++ - 4 files changed, 26 insertions(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index bcd2212a..ad7afd04 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -8,6 +8,11 @@ - # - # Uncomment to disable dmevents polling support - # ENABLE_DMEVENTS_POLL = 0 -+# -+# Readline library to use, libedit or libreadline -+# Caution: Using libreadline may make the multipathd binary undistributable, -+# see https://github.com/opensvc/multipath-tools/issues/36 -+READLINE = libedit - - # List of scsi device handler modules to load on boot, e.g. - # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac -diff --git a/multipathd/Makefile b/multipathd/Makefile -index c937cd55..95acd887 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -22,7 +22,16 @@ CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ -- -ldevmapper -lreadline -+ -ldevmapper -+ -+ifeq ($(READLINE),libedit) -+CPPFLAGS += -DUSE_LIBEDIT -+LIBDEPS += -ledit -+endif -+ifeq ($(READLINE),libreadline) -+CPPFLAGS += -DUSE_LIBREADLINE -+LIBDEPS += -lreadline -+endif - - ifdef SYSTEMD - CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -diff --git a/multipathd/cli.c b/multipathd/cli.c -index b2ee9a99..fa482a67 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -11,7 +11,12 @@ - #include "parser.h" - #include "util.h" - #include "version.h" -+#ifdef USE_LIBEDIT -+#include -+#endif -+#ifdef USE_LIBREADLINE - #include -+#endif - - #include "mpath_cmd.h" - #include "cli.h" -diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c -index bdcc7c3f..251e7d75 100644 ---- a/multipathd/uxclnt.c -+++ b/multipathd/uxclnt.c -@@ -16,8 +16,14 @@ - #include - #include - #include -+ -+#ifdef USE_LIBEDIT -+#include -+#endif -+#ifdef USE_LIBREADLINE - #include - #include -+#endif - - #include "mpath_cmd.h" - #include "uxsock.h" diff --git a/0047-RH-use-rpm-optflags-if-present.patch b/0037-RH-use-rpm-optflags-if-present.patch similarity index 71% rename from 0047-RH-use-rpm-optflags-if-present.patch rename to 0037-RH-use-rpm-optflags-if-present.patch index bd3b6e1..c844afe 100644 --- a/0047-RH-use-rpm-optflags-if-present.patch +++ b/0037-RH-use-rpm-optflags-if-present.patch @@ -13,19 +13,19 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 03450610..2cf6e85f 100644 +index 8c5a08a2..e6e7f7d7 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -141,18 +141,30 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) +@@ -74,19 +74,31 @@ INSTALL_PROGRAM := install + SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) + SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ +ifndef RPM_OPT_FLAGS -+ OPTFLAGS := -O2 -g -Wall $(FORTIFY_OPT) -fexceptions \ -+ $(STACKPROT) -grecord-gcc-switches \ -+ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 ++ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 \ ++ -Wall $(FORTIFY_OPT) -fexceptions -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables + ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) + OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 + endif @@ -39,17 +39,18 @@ index 03450610..2cf6e85f 100644 -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) -CPPFLAGS := $(FORTIFY_OPT) \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ +- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + $(WNOCLOBBERED) -Werror=cast-qual \ + $(ERROR_DISCARDED_QUALIFIERS) -Wstrict-prototypes -+CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ ++CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" \ -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC - SHARED_FLAGS = -shared + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC + SHARED_FLAGS := -shared -LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs +LDFLAGS := $(LDFLAGS) $(RPM_LD_FLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs - BIN_LDFLAGS = -pie + BIN_LDFLAGS := -pie - # Check whether a function with name $1 has been declared in header file $2. + # Source code directories. Don't modify. diff --git a/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch b/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch deleted file mode 100644 index f8085e8..0000000 --- a/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 12 Aug 2022 21:25:37 +0200 -Subject: [PATCH] libmultipath: convert license of strbuf code to GPL-2.0+ - -This (partly) fixes the license incompatibility reported in -https://github.com/opensvc/multipath-tools/issues/36 - -As I'm the only author (except for a trivial spelling fix), -I see no issue with changing the license. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/strbuf.c | 2 +- - libmultipath/strbuf.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/strbuf.c b/libmultipath/strbuf.c -index f654594d..e23b65e8 100644 ---- a/libmultipath/strbuf.c -+++ b/libmultipath/strbuf.c -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2021 SUSE LLC -- * SPDX-License-Identifier: GPL-2.0-only -+ * SPDX-License-Identifier: GPL-2.0-or-later - */ - #include - #include -diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h -index 31ab519a..ae863417 100644 ---- a/libmultipath/strbuf.h -+++ b/libmultipath/strbuf.h -@@ -1,6 +1,6 @@ - /* - * Copyright (c) 2021 SUSE LLC -- * SPDX-License-Identifier: GPL-2.0-only -+ * SPDX-License-Identifier: GPL-2.0-or-later - */ - #ifndef _STRBUF_H - #define _STRBUF_H diff --git a/0048-RH-add-mpathconf.patch b/0038-RH-add-mpathconf.patch similarity index 94% rename from 0048-RH-add-mpathconf.patch rename to 0038-RH-add-mpathconf.patch index ff2487f..e279822 100644 --- a/0048-RH-add-mpathconf.patch +++ b/0038-RH-add-mpathconf.patch @@ -21,10 +21,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index f06fcbf9..e2840839 100644 +index 183b319d..01f36a4f 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -957,6 +957,8 @@ int _init_config (const char *file, struct config *conf) +@@ -968,6 +968,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -34,36 +34,39 @@ index f06fcbf9..e2840839 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index d2b3fd82..00e46a0d 100644 +index b3c2cc81..413294ef 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -21,6 +21,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +@@ -22,6 +22,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so install: - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -30,6 +31,7 @@ install: - $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) -+ $(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(man8dir) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules +@@ -31,6 +32,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 ifneq ($(SCSI_DH_MODULES_PRELOAD),) - $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ -@@ -42,8 +44,10 @@ uninstall: - $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules -+ $(RM) $(DESTDIR)$(bindir)/mpathconf - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 -+ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8 +@@ -41,11 +43,13 @@ endif + + uninstall: + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/mpathconf.8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 clean: dep_clean - $(RM) core *.o $(EXEC) diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 index 00000000..319664b1 diff --git a/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch b/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch deleted file mode 100644 index 375940f..0000000 --- a/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 14:10:39 +0200 -Subject: [PATCH] github workflows: build-and-unittest.yaml: add libedit-dev - -This is is required after switching from libreadline to libedit. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index 7ff45842..1ab0d36c 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -27,7 +27,7 @@ jobs: - sudo apt-get install --yes gcc - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: build - run: make -O -j$(grep -c ^processor /proc/cpuinfo) - - name: test -@@ -55,7 +55,7 @@ jobs: - sudo apt-get install --yes gcc-10 - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: set CC - run: echo CC=gcc-10 >> $GITHUB_ENV - - name: build -@@ -85,7 +85,7 @@ jobs: - sudo apt-get install --yes clang - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: set CC - run: echo CC=clang >> $GITHUB_ENV - - name: build diff --git a/0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 95% rename from 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index fbf22db..c98543b 100644 --- a/0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 034dd2f4..4c31820b 100644 +index b9f360b4..5eb752ee 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index 034dd2f4..4c31820b 100644 " -c check if a device should be a path in a multipath device\n" " -C check if a multipath device has usable paths\n" " -q allow queue_if_no_path when multipathd is not running\n" -@@ -448,6 +450,50 @@ static void cleanup_vecs(void) +@@ -447,6 +449,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index 034dd2f4..4c31820b 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -841,7 +887,7 @@ main (int argc, char *argv[]) +@@ -840,7 +886,7 @@ main (int argc, char *argv[]) conf->force_sync = 1; if (atexit(cleanup_vecs)) condlog(1, "failed to register cleanup handler for vecs: %m"); @@ -101,7 +101,7 @@ index 034dd2f4..4c31820b 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -912,6 +958,10 @@ main (int argc, char *argv[]) +@@ -911,6 +957,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -113,7 +113,7 @@ index 034dd2f4..4c31820b 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 4c7e9885..1d062664 100644 +index 88149d53..072a03ee 100644 --- a/multipath/multipath.8 +++ b/multipath/multipath.8 @@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. diff --git a/0039-github-workflows-coverity.yaml-add-libedit-dev.patch b/0039-github-workflows-coverity.yaml-add-libedit-dev.patch deleted file mode 100644 index 63ef9dc..0000000 --- a/0039-github-workflows-coverity.yaml-add-libedit-dev.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 14:10:39 +0200 -Subject: [PATCH] github workflows: coverity.yaml: add libedit-dev - -This is is required after switching from libreadline to libedit. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/coverity.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml -index a8b56d43..3c6b3824 100644 ---- a/.github/workflows/coverity.yaml -+++ b/.github/workflows/coverity.yaml -@@ -15,7 +15,7 @@ jobs: - sudo apt-get install --yes - gcc make pkg-config - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: download coverity - run: > - curl -o cov-analysis-linux64.tar.gz diff --git a/0050-RH-reset-default-find_mutipaths-value-to-off.patch b/0040-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 96% rename from 0050-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0040-RH-reset-default-find_mutipaths-value-to-off.patch index 9b6b7bb..ea12464 100644 --- a/0050-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0040-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 7979f208..78b3d938 100644 +index a5e9ea0c..514fd880 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ diff --git a/0040-github-workflows-abi.yaml-add-libedit-dev.patch b/0040-github-workflows-abi.yaml-add-libedit-dev.patch deleted file mode 100644 index 93e2331..0000000 --- a/0040-github-workflows-abi.yaml-add-libedit-dev.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 14:10:39 +0200 -Subject: [PATCH] github workflows: abi.yaml: add libedit-dev - -This is is required after switching from libreadline to libedit. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 0a40104a..89b971cd 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -30,7 +30,7 @@ jobs: - sudo apt-get install --yes gcc - gcc make pkg-config abigail-tools - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: create ABI - run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - - name: save ABI diff --git a/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch b/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch deleted file mode 100644 index 7fc05a6..0000000 --- a/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 16:52:07 +0200 -Subject: [PATCH] GitHub workflows: native.yaml: add libedit-dev, except for - jessie - -This is is required after switching from libreadline to libedit. - -On jessie, we can use libreadline5 (libreadline-gpl2-dev) without -license issues. Trying to compile against libedit results in an -"incompatible pointer type" error on jessie, because libedit -uses a different prototype for rl_completion_entry_function. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index ddfd4a09..8b599209 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -22,13 +22,24 @@ jobs: - - name: checkout - uses: actions/checkout@v1 - - name: build and test -+ if: ${{ matrix.os != 'jessie' }} - run: make test -+ - name: build and test (jessie) -+ # On jessie, we use libreadline 5 (no licensing issue) -+ if: ${{ matrix.os == 'jessie' }} -+ run: make READLINE=libreadline test - - name: clean - run: make clean - - name: clang -+ if: ${{ matrix.os != 'jessie' }} - env: - CC: clang - run: make test -+ - name: clang (jessie) -+ if: ${{ matrix.os == 'jessie' }} -+ env: -+ CC: clang -+ run: make READLINE=libreadline test - - rolling: - runs-on: ubuntu-20.04 -@@ -56,12 +67,13 @@ jobs: - libjson-c-dev - liburcu-dev - libcmocka-dev -+ libedit-dev - - name: dependencies-alpine - if: ${{ matrix.os == 'alpine' }} - run: > - apk add make gcc clang cmocka - musl-dev lvm2-dev libaio-dev readline-dev ncurses-dev eudev-dev -- userspace-rcu-dev json-c-dev cmocka-dev -+ userspace-rcu-dev json-c-dev cmocka-dev libedit-dev - - name: dependencies-fedora - if: ${{ matrix.os == 'fedora:rawhide' }} - run: > -@@ -76,6 +88,7 @@ jobs: - userspace-rcu-devel - json-c-devel - libcmocka-devel -+ libedit-devel - - name: checkout - uses: actions/checkout@v1 - - name: build and test diff --git a/0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch b/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch deleted file mode 100644 index 3af19df..0000000 --- a/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Aug 2022 23:38:18 +0200 -Subject: [PATCH] GitHub workflows: foreign.yaml: switch to Debian 11 - (bullseye) - -Building the containers in the build-multipath project recently -started failing for buster/s390x and buster/ppc64el. That failure -had nothing to do with the switch to libedit. - -It's about time to switch to bullseye anyway. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/foreign.yaml | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 32915186..f6e69709 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -13,7 +13,7 @@ jobs: - runs-on: ubuntu-20.04 - strategy: - matrix: -- os: [buster] -+ os: [bullseye] - arch: ['ppc64le', 'aarch64', 's390x'] - container: mwilck/multipath-build-${{ matrix.os }}-${{ matrix.arch }} - steps: -@@ -44,7 +44,7 @@ jobs: - needs: build - strategy: - matrix: -- os: [buster] -+ os: [bullseye] - arch: ['ppc64le', 'aarch64', 's390x'] - steps: - - name: get binaries diff --git a/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 604ff75..5812a54 100644 --- a/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 15560f8c..2339c9a9 100644 +index f3fccedd..c883fd02 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1175,13 +1175,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1176,13 +1176,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 15560f8c..2339c9a9 100644 good_len = 8; break; default: -@@ -1199,10 +1195,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1200,10 +1196,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 92% rename from 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch index 423f107..72fbfe8 100644 --- a/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,10 +11,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 2cf6e85f..7277cf5f 100644 +index e6e7f7d7..15f0b9f6 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -16,7 +16,7 @@ READLINE = libedit +@@ -16,7 +16,7 @@ READLINE := # List of scsi device handler modules to load on boot, e.g. # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac diff --git a/0043-RH-fixup-udev-rules-for-redhat.patch b/0043-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index 47a1ab2..0000000 --- a/0043-RH-fixup-udev-rules-for-redhat.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 13 Apr 2017 07:22:23 -0500 -Subject: [PATCH] RH: fixup udev rules for redhat - -The multipath rules need to run after scsi_id is run. This means moving -them after 60-persistent-storage.rules for redhat. Redhat also uses a -different naming scheme for partitions than SuSE. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - kpartx/kpartx.rules | 2 +- - multipath/Makefile | 4 ++-- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index ad7afd04..03450610 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -81,7 +81,7 @@ endif - prefix = - exec_prefix = $(prefix) - usr_prefix = $(prefix) --bindir = $(exec_prefix)/sbin -+bindir = $(exec_prefix)/usr/sbin - libudevdir = $(prefix)/$(SYSTEMDPATH)/udev - udevrulesdir = $(libudevdir)/rules.d - modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 1969dee0..d2b28233 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" - GOTO="kpartx_end" - - LABEL="run_kpartx" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" - - LABEL="kpartx_end" -diff --git a/multipath/Makefile b/multipath/Makefile -index bcb04533..d2b3fd82 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -23,7 +23,7 @@ install: - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules - $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) - $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -@@ -41,7 +41,7 @@ uninstall: - $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules - $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 - diff --git a/0044-RH-compile-with-libreadline-support.patch b/0044-RH-compile-with-libreadline-support.patch new file mode 100644 index 0000000..b6d59f5 --- /dev/null +++ b/0044-RH-compile-with-libreadline-support.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 15 Nov 2022 18:03:33 -0600 +Subject: [PATCH] RH: compile with libreadline support + +Since the license issue has been resolved, and there are problems with +the command completion with libedit, use libreadline. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 15f0b9f6..881c1d52 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -12,7 +12,7 @@ + # Readline library to use, libedit, libreadline, or empty + # Caution: Using libreadline may make the multipathd binary undistributable, + # see https://github.com/opensvc/multipath-tools/issues/36 +-READLINE := ++READLINE := libreadline + + # List of scsi device handler modules to load on boot, e.g. + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index f140e00..8a6b8e5 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,75 +1,66 @@ Name: device-mapper-multipath -Version: 0.9.0 -Release: 3%{?dist} +Version: 0.9.3 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.0.tar.gz -o multipath-tools-0.9.0.tgz -Source0: multipath-tools-0.9.0.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.3.tar.gz -o multipath-tools-0.9.3.tgz +Source0: multipath-tools-0.9.3.tgz Source1: multipath.conf -Patch0001: 0001-github-workflows-switch-to-fedora-36.patch -Patch0002: 0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch -Patch0003: 0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch -Patch0004: 0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch -Patch0005: 0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch -Patch0006: 0006-multipath-tools-update-devel-repo-info-in-README.md.patch -Patch0007: 0007-multipath-tools-delete-README.alua.patch -Patch0008: 0008-multipath-tools-add-ALUA-info-to-README.md.patch -Patch0009: 0009-libmultipath-alua-remove-get_sysfs_pg83.patch -Patch0010: 0010-libmultipath-remove-sysfs_get_binary.patch -Patch0011: 0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch -Patch0012: 0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch -Patch0013: 0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch -Patch0014: 0014-libmultipath-get-rid-of-PATH_SIZE.patch -Patch0015: 0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch -Patch0016: 0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch -Patch0017: 0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch -Patch0018: 0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch -Patch0019: 0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch -Patch0020: 0020-multipath-tests-__wrap_dlog-print-log-message.patch -Patch0021: 0021-multipath-tests-add-sysfs-test.patch -Patch0022: 0022-libmultipath.version-bump-version-for-sysfs-accessor.patch -Patch0023: 0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch -Patch0024: 0024-libmultipath-spelling-cplusplus.patch -Patch0025: 0025-libmultipath-spelling-ascii.patch -Patch0026: 0026-libmultipath-spelling-progress.patch -Patch0027: 0027-multipath-tools-spelling-fixes.patch -Patch0028: 0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch -Patch0029: 0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch -Patch0030: 0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch -Patch0031: 0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch -Patch0032: 0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch -Patch0033: 0033-multipathd-Handle-losing-all-path-in-update_map.patch -Patch0034: 0034-multipath-fix-systemd-timers-in-the-initramfs.patch -Patch0035: 0035-multipathd-Add-missing-ctype-include.patch -Patch0036: 0036-multipathd-replace-libreadline-with-libedit.patch -Patch0037: 0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch -Patch0038: 0038-github-workflows-build-and-unittest.yaml-add-libedit.patch -Patch0039: 0039-github-workflows-coverity.yaml-add-libedit-dev.patch -Patch0040: 0040-github-workflows-abi.yaml-add-libedit-dev.patch -Patch0041: 0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch -Patch0042: 0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch -Patch0043: 0043-RH-fixup-udev-rules-for-redhat.patch -Patch0044: 0044-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0045: 0045-RH-don-t-start-without-a-config-file.patch -Patch0046: 0046-RH-Fix-nvme-function-missing-argument.patch -Patch0047: 0047-RH-use-rpm-optflags-if-present.patch -Patch0048: 0048-RH-add-mpathconf.patch -Patch0049: 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0050: 0050-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0051: 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0052: 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0053: 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0001: 0001-libmultipath-fix-show-paths-format-failure.patch +Patch0002: 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch +Patch0003: 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch +Patch0004: 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch +Patch0005: 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch +Patch0006: 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch +Patch0007: 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch +Patch0008: 0008-multipath-tools-Makefiles-use-mandir.patch +Patch0009: 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch +Patch0010: 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch +Patch0011: 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch +Patch0012: 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch +Patch0013: 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch +Patch0014: 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch +Patch0015: 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch +Patch0016: 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch +Patch0017: 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch +Patch0018: 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch +Patch0019: 0019-multipath-tools-Makefiles-create-config.mk.patch +Patch0020: 0020-multipath-tools-Makefiles-enable-quiet-build.patch +Patch0021: 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch +Patch0022: 0022-GitHub-workflows-use-make-j8-Orecurse.patch +Patch0023: 0023-README.md-Move-section-about-libedit-and-libreadline.patch +Patch0024: 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch +Patch0025: 0025-README.md-document-options-for-paths-and-optimizatio.patch +Patch0026: 0026-README.md-document-how-to-customize-build.patch +Patch0027: 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch +Patch0028: 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch +Patch0029: 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch +Patch0030: 0030-libmultipath-impove-add_feature-variable-names.patch +Patch0031: 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch +Patch0032: 0032-libmultipath-improve-remove_feature-variable-names.patch +Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch +Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0035: 0035-RH-don-t-start-without-a-config-file.patch +Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch +Patch0037: 0037-RH-use-rpm-optflags-if-present.patch +Patch0038: 0038-RH-add-mpathconf.patch +Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0044: 0044-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu -Requires: libedit +Requires: readline Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -87,7 +78,7 @@ Conflicts: udisks2 < 2.8.0-2 # build/setup BuildRequires: libaio-devel, device-mapper-devel >= 1.02.89 BuildRequires: libselinux-devel, libsepol-devel -BuildRequires: libedit-devel, ncurses-devel +BuildRequires: readline-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel @@ -147,7 +138,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.0 -p1 +%autosetup -n multipath-tools-0.9.3 -p1 cp %{SOURCE1} . %build @@ -162,11 +153,12 @@ cp %{SOURCE1} . bindir=%{_sbindir} \ syslibdir=%{_libdir} \ usrlibdir=%{_libdir} \ - libdir=%{_libmpathdir} \ - rcdir=%{_initrddir} \ + plugindir=%{_libmpathdir} \ + mandir=%{_mandir} \ unitdir=%{_unitdir} \ includedir=%{_includedir} \ - pkgconfdir=%{_pkgconfdir} + pkgconfdir=%{_pkgconfdir} \ + tmpfilesdir=%{_tmpfilesdir} # tree fix up install -d %{buildroot}/etc/multipath @@ -191,32 +183,37 @@ fi /bin/systemctl --quiet is-enabled multipathd.service >/dev/null 2>&1 && /bin/systemctl reenable multipathd.service ||: %files -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 LICENSES/GPL-3.0 %{_sbindir}/multipath %{_sbindir}/multipathd +%{_sbindir}/multipathc %{_sbindir}/mpathconf %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service %{_unitdir}/multipathd.socket -%{_mandir}/man5/multipath.conf.5.gz -%{_mandir}/man8/multipath.8.gz -%{_mandir}/man8/multipathd.8.gz -%{_mandir}/man8/mpathconf.8.gz -%{_mandir}/man8/mpathpersist.8.gz +%{_mandir}/man5/multipath.conf.5* +%{_mandir}/man8/multipath.8* +%{_mandir}/man8/multipathd.8* +%{_mandir}/man8/multipathc.8* +%{_mandir}/man8/mpathconf.8* +%{_mandir}/man8/mpathpersist.8* %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules %dir /usr/lib/modules-load.d /usr/lib/modules-load.d/multipath.conf /usr/lib/modules-load.d/scsi_dh.conf +%{_tmpfilesdir}/multipath.conf %doc README.md %doc multipath.conf %dir /etc/multipath %files libs -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 LICENSES/LGPL-2.1 %doc README.md %{_libdir}/libmultipath.so %{_libdir}/libmultipath.so.* +%{_libdir}/libmpathutil.so +%{_libdir}/libmpathutil.so.* %{_libdir}/libmpathpersist.so.* %{_libdir}/libmpathcmd.so.* %{_libdir}/libmpathvalid.so.* @@ -233,15 +230,15 @@ fi %{_includedir}/mpath_cmd.h %{_includedir}/mpath_persist.h %{_includedir}/mpath_valid.h -%{_mandir}/man3/mpath_persistent_reserve_in.3.gz -%{_mandir}/man3/mpath_persistent_reserve_out.3.gz +%{_mandir}/man3/mpath_persistent_reserve_in.3* +%{_mandir}/man3/mpath_persistent_reserve_out.3* %files -n kpartx %license LICENSES/GPL-2.0 %doc README.md %{_sbindir}/kpartx /usr/lib/udev/kpartx_id -%{_mandir}/man8/kpartx.8.gz +%{_mandir}/man8/kpartx.8* %config /usr/lib/udev/rules.d/11-dm-parts.rules %config /usr/lib/udev/rules.d/66-kpartx.rules %config /usr/lib/udev/rules.d/68-del-part-nodes.rules @@ -259,10 +256,24 @@ fi %dir %{_includedir}/libdmmp %{_includedir}/libdmmp/* %{_mandir}/man3/dmmp_* -%{_mandir}/man3/libdmmp.h.3.gz +%{_mandir}/man3/libdmmp.h.3* %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 15 2022 Benjamin Marzinski - 0.9.3-1 +- Update to the head of the upstream staging branch + * Previous patches 0001-0042 are included in the source tarball + * Patches 0001-0032 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0043-0053 are now patches 0033-0043 +- Change back to using readline instead of libedit + * The code the uses readline has been isolated from the code that + is licensed gpl v2 only. +- Add libmpathutil libraries to spec file +- Add multipathc program to spec file +- Add multipath.conf systemd tempfile configuration to spec file +- Misc spec file cleanups + * Fri Aug 19 2022 Benjamin Marzinski - 0.9.0-3 - Update to the head of the upstream staging branch * Patches 0005-0042 are from the upstream staging branch diff --git a/sources b/sources index 14c7342..0394f4e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.0.tgz) = 6c417f6d1d116fa43bedb9f77769ece9cbb7b35b78a9b3558c41df2360e52a65a07314b12ab7e4a7bbc867b9755250de9db96a2f7eb4a6a37f0b0b3f0bbc840e +SHA512 (multipath-tools-0.9.3.tgz) = 4faa2ee5a96a9d5d752219931ebc885cb70ed6b022d45ede985ad7919c043a3aee166e6f126d32dffd187c5c32d5cbce91747d87d0b55557e2f7f68b279583da SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From bf5e5e489128385b45b09cbf3d342be46bb56db4 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 01:17:17 +0000 Subject: [PATCH 02/33] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 8a6b8e5..847d6b9 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.3 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -260,6 +260,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Tue Nov 15 2022 Benjamin Marzinski - 0.9.3-1 - Update to the head of the upstream staging branch * Previous patches 0001-0042 are included in the source tarball From 8e8d008d17e0648fd701436f2463651e6d11132d Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 26 Jan 2023 19:02:53 -0600 Subject: [PATCH 03/33] device-mapper-multipath-0.9.4-1 Update to the head of the upstream staging branch * Previous patches 0001-0032 are intlcude in the source tarball * Patches 0001-0010 are from the upstream staging branch Rename redhat patches * Previous patches 0033-0044 are not patches 0011-0022 Add dependency on libmount --- .gitignore | 1 + ...tipath-fix-show-paths-format-failure.patch | 35 - ...athd-make-pr-registration-consistent.patch | 159 ++++ ...kefile.inc-fix-man-and-include-paths.patch | 41 - 0002-libmultipath-make-prflag-an-enum.patch | 166 ++++ ...s-Makefile.inc-Fix-paths-for-systemd.patch | 65 -- ...dle-no-active-paths-in-update_map_pr.patch | 152 +++ ...Makefile.inc-don-t-take-values-from-.patch | 113 --- ...missing-newline-to-cli_del_map-reply.patch | 24 + ...kip-extra-vector-work-in-remove_maps.patch | 33 + ...th-tools-Makefile.inc-get-rid-of-RUN.patch | 63 -- ...han-paths-if-coalesce_paths-frees-ne.patch | 41 + ...Makefile.inc-more-compact-code-for-L.patch | 38 - ...path_valid-check-if-device-is-in-use.patch | 609 ++++++++++++ ...Makefiles-simplify-code-for-include-.patch | 139 --- ...use-conf-timeout-for-updating-persis.patch | 55 ++ ...multipath-tools-Makefiles-use-mandir.patch | 185 ---- ...hinfo-don-t-fail-for-devices-lacking.patch | 77 ++ ...Makefile.inc-simplify-expression-for.patch | 36 - ...multipath-bump-ABI-version-to-18.0.0.patch | 26 + ...Makefile.inc-untangle-paths-and-sour.patch | 68 -- ... 0011-RH-fixup-udev-rules-for-redhat.patch | 2 +- ...Makefiles-replace-libdir-by-plugindi.patch | 110 --- ...property-blacklist-exception-builtin.patch | 6 +- ...Makefile.inc-use-simple-make-variabl.patch | 112 --- ...RH-don-t-start-without-a-config-file.patch | 0 ...tools-Makefile.inc-fix-a-log-message.patch | 24 - ...H-Fix-nvme-function-missing-argument.patch | 0 ...Makefile.inc-set-systemd-specific-fl.patch | 129 --- ... 0015-RH-use-rpm-optflags-if-present.patch | 21 +- ...ile-fix-compilation-flags-for-libedi.patch | 54 -- ...hconf.patch => 0016-RH-add-mpathconf.patch | 0 ...Makefiles-clean-up-executable-Makefi.patch | 136 --- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...Makefiles-use-common-code-for-librar.patch | 261 ------ ...-default-find_mutipaths-value-to-off.patch | 0 ...Makefiles-move-common-code-to-rules..patch | 172 ---- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...ath-tools-Makefiles-create-config.mk.patch | 603 ------------ ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...h-tools-Makefiles-enable-quiet-build.patch | 879 ------------------ ...si-device-handlers-to-modules-load.d.patch | 2 +- ...quiet-build-support-for-top-level-Ma.patch | 183 ---- ...itHub-workflows-use-make-j8-Orecurse.patch | 132 --- ...-RH-compile-with-libreadline-support.patch | 2 +- ...ection-about-libedit-and-libreadline.patch | 48 - ...dentation-in-paragraph-about-device-.patch | 34 - ...nt-options-for-paths-and-optimizatio.patch | 47 - ...E.md-document-how-to-customize-build.patch | 37 - ...id-Warray-bounds-error-with-gcc-12-a.patch | 63 -- ...d-NULL-string-in-released_to_systemd.patch | 26 - ...h-avoid-NULL-string-in-is_udev_ready.patch | 26 - ...th-impove-add_feature-variable-names.patch | 115 --- ...-initialize-the-field-width-in-show_.patch | 31 - ...mprove-remove_feature-variable-names.patch | 144 --- device-mapper-multipath.spec | 86 +- sources | 2 +- 57 files changed, 1400 insertions(+), 4219 deletions(-) delete mode 100644 0001-libmultipath-fix-show-paths-format-failure.patch create mode 100644 0001-multipathd-make-pr-registration-consistent.patch delete mode 100644 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch create mode 100644 0002-libmultipath-make-prflag-an-enum.patch delete mode 100644 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch create mode 100644 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch delete mode 100644 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch create mode 100644 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch create mode 100644 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch delete mode 100644 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch create mode 100644 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch delete mode 100644 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch create mode 100644 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch delete mode 100644 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch create mode 100644 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch delete mode 100644 0008-multipath-tools-Makefiles-use-mandir.patch create mode 100644 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch delete mode 100644 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch create mode 100644 0010-libmultipath-bump-ABI-version-to-18.0.0.patch delete mode 100644 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch rename 0033-RH-fixup-udev-rules-for-redhat.patch => 0011-RH-fixup-udev-rules-for-redhat.patch (98%) delete mode 100644 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch rename 0034-RH-Remove-the-property-blacklist-exception-builtin.patch => 0012-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) delete mode 100644 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch rename 0035-RH-don-t-start-without-a-config-file.patch => 0013-RH-don-t-start-without-a-config-file.patch (100%) delete mode 100644 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch rename 0036-RH-Fix-nvme-function-missing-argument.patch => 0014-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch rename 0037-RH-use-rpm-optflags-if-present.patch => 0015-RH-use-rpm-optflags-if-present.patch (78%) delete mode 100644 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch rename 0038-RH-add-mpathconf.patch => 0016-RH-add-mpathconf.patch (100%) delete mode 100644 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch rename 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) delete mode 100644 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch rename 0040-RH-reset-default-find_mutipaths-value-to-off.patch => 0018-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch rename 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0019-multipath-tools-Makefiles-create-config.mk.patch rename 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) delete mode 100644 0020-multipath-tools-Makefiles-enable-quiet-build.patch rename 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) delete mode 100644 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch delete mode 100644 0022-GitHub-workflows-use-make-j8-Orecurse.patch rename 0044-RH-compile-with-libreadline-support.patch => 0022-RH-compile-with-libreadline-support.patch (96%) delete mode 100644 0023-README.md-Move-section-about-libedit-and-libreadline.patch delete mode 100644 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch delete mode 100644 0025-README.md-document-options-for-paths-and-optimizatio.patch delete mode 100644 0026-README.md-document-how-to-customize-build.patch delete mode 100644 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch delete mode 100644 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch delete mode 100644 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch delete mode 100644 0030-libmultipath-impove-add_feature-variable-names.patch delete mode 100644 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch delete mode 100644 0032-libmultipath-improve-remove_feature-variable-names.patch diff --git a/.gitignore b/.gitignore index c9e44d7..1ca930c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.9.tgz /multipath-tools-0.9.0.tgz /multipath-tools-0.9.3.tgz +/multipath-tools-0.9.4.tgz diff --git a/0001-libmultipath-fix-show-paths-format-failure.patch b/0001-libmultipath-fix-show-paths-format-failure.patch deleted file mode 100644 index 4f56830..0000000 --- a/0001-libmultipath-fix-show-paths-format-failure.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Koetsier -Date: Thu, 27 Oct 2022 19:29:28 +0200 -Subject: [PATCH] libmultipath: fix 'show paths format' failure - -Prevent 'multipathd show paths format "%c"' from failing on orphan paths. -For orphan paths the checker class isn't set, which caused -snprint_path_checker() to fail which in turn caused 'show paths format' to fail -when the format string contained "%c". - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index d7d522c8..3193dbe0 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -734,8 +734,12 @@ snprint_host_adapter (struct strbuf *buff, const struct path * pp) - static int - snprint_path_checker (struct strbuf *buff, const struct path * pp) - { -- const struct checker * c = &pp->checker; -- return snprint_str(buff, checker_name(c)); -+ const char * n = checker_name(&pp->checker); -+ -+ if (n) -+ return snprint_str(buff, n); -+ else -+ return snprint_str(buff, "(null)"); - } - - static int diff --git a/0001-multipathd-make-pr-registration-consistent.patch b/0001-multipathd-make-pr-registration-consistent.patch new file mode 100644 index 0000000..47c380a --- /dev/null +++ b/0001-multipathd-make-pr-registration-consistent.patch @@ -0,0 +1,159 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:10 -0600 +Subject: [PATCH] multipathd: make pr registration consistent + +multipathd was inconsistent on what it did with persistent reservations +when a multipath device was created. If a multipath device with a +configured reservation key was created during configure(), multipathd +would try to read the registered keys using an active path. If it saw a +matching key, it would set the prflag, but not attempt to register the +key on any of the other paths. This means that if a new path had +appeared while multipathd was not running, it wouldn't register the key +on this path. + +If the multipath device was created during ev_add_path(), multipathd +would used the added path to check if there was a matching key and if +there was, register the key only on the added path and then set the +prflag. This could be problematic if the device was created with +multiple paths, for instance because find_mutipaths was set to "yes" and +a second path just appeared. In this case, if the device happened to be +only registered on the second path, it would not get registered on the +first path. + +If the multipath device was added to multipathd during a call to +ev_add_map(), multipathd wouldn't set the prflag or register the key on +any paths. + +After a device was created with the prflag set, if a new path appeared +before the creation uevent, and multipathd was forced to delay adding +it, when it finally updated the multipath device, the key would be +registered on all paths, fixing any paths missed during creation. +However, if a new path appeared after the creation uevent, the key would +only be registered on that new path. Any paths that were missed on +creation would stay missed. + +persistent key registration needs to be handled consistently. This +patch does so by making sure that however a multipath device is added to +multipathd, it will check to see if the configured key is registered. If +it is, multipathd will set the prflag and register the key on all the +currently active paths. + +When a new path is added, multipathd will use it to check for active +keys, as before. But if it finds a matching key and prflag isn't +currently set, it will register the key on all paths. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 43 +++++++++++++++++++++++++++++-------------- + 1 file changed, 29 insertions(+), 14 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 1e1b254f..f7212d7b 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -586,13 +586,26 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { + return false; + } + ++static void ++pr_register_active_paths(struct multipath *mpp) ++{ ++ unsigned int i, j; ++ struct path *pp; ++ struct pathgroup *pgp; ++ ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ vector_foreach_slot (pgp->paths, pp, j) { ++ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) ++ mpath_pr_event_handle(pp); ++ } ++ } ++} ++ + static int + update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { + int retries = 3; + char *params __attribute__((cleanup(cleanup_charp))) = NULL; +- struct path *pp; +- int i; + + retry: + condlog(4, "%s: updating new map", mpp->alias); +@@ -609,15 +622,6 @@ retry: + + mpp->action = ACT_RELOAD; + +- if (mpp->prflag) { +- vector_foreach_slot(mpp->paths, pp, i) { +- if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { +- /* persistent reservation check*/ +- mpath_pr_event_handle(pp); +- } +- } +- } +- + if (setup_map(mpp, ¶ms, vecs)) { + condlog(0, "%s: failed to setup new map in update", mpp->alias); + retries = -1; +@@ -643,6 +647,11 @@ fail: + + sync_map_state(mpp); + ++ if (!mpp->prflag) ++ update_map_pr(mpp); ++ if (mpp->prflag) ++ pr_register_active_paths(mpp); ++ + if (retries < 0) + condlog(0, "%s: failed reload in new map update", mpp->alias); + return 0; +@@ -1191,6 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + int start_waiter = 0; + int ret; + int ro; ++ unsigned char prflag = 0; + + /* + * need path UID to go any further +@@ -1234,6 +1244,8 @@ rescan: + + verify_paths(mpp); + mpp->action = ACT_RELOAD; ++ prflag = mpp->prflag; ++ mpath_pr_event_handle(pp); + } else { + if (!should_multipath(pp, vecs->pathvec, vecs->mpvec)) { + orphan_path(pp, "only one path"); +@@ -1252,9 +1264,6 @@ rescan: + goto fail; /* leave path added to pathvec */ + } + +- /* persistent reservation check*/ +- mpath_pr_event_handle(pp); +- + /* ro check - if new path is ro, force map to be ro as well */ + ro = sysfs_get_ro(pp); + if (ro == 1) +@@ -1319,6 +1328,10 @@ rescan: + sync_map_state(mpp); + + if (retries >= 0) { ++ if (start_waiter) ++ update_map_pr(mpp); ++ if (mpp->prflag && !prflag) ++ pr_register_active_paths(mpp); + condlog(2, "%s [%s]: path added to devmap %s", + pp->dev, pp->dev_t, mpp->alias); + return 0; +@@ -2852,6 +2865,8 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) + if (remember_wwid(mpp->wwid) == 1) + trigger_paths_udev_change(mpp, true); + update_map_pr(mpp); ++ if (mpp->prflag) ++ pr_register_active_paths(mpp); + } + + /* diff --git a/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch b/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch deleted file mode 100644 index 4afae52..0000000 --- a/0002-fixup-Makefile.inc-fix-man-and-include-paths.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 18:22:59 +0200 -Subject: [PATCH] fixup! Makefile.inc: fix man and include paths - -Paths would now be wrong with the default (empty) prefix. -Fix it. - -Fixes: 2b2885c ("Makefile.inc: fix man and include paths") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 4d843ce5..32001434 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -89,9 +89,9 @@ modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d - multipathdir = $(TOPDIR)/libmultipath - daemondir = $(TOPDIR)/multipathd - mpathutildir = $(TOPDIR)/libmpathutil --man8dir = $(prefix)/share/man/man8 --man5dir = $(prefix)/share/man/man5 --man3dir = $(prefix)/share/man/man3 -+man8dir = $(usr_prefix)/share/man/man8 -+man5dir = $(usr_prefix)/share/man/man5 -+man3dir = $(usr_prefix)/share/man/man3 - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath -@@ -102,7 +102,7 @@ mpathvaliddir = $(TOPDIR)/libmpathvalid - thirdpartydir = $(TOPDIR)/third-party - libdmmpdir = $(TOPDIR)/libdmmp - nvmedir = $(TOPDIR)/libmultipath/nvme --includedir = $(prefix)/include -+includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d diff --git a/0002-libmultipath-make-prflag-an-enum.patch b/0002-libmultipath-make-prflag-an-enum.patch new file mode 100644 index 0000000..304f731 --- /dev/null +++ b/0002-libmultipath-make-prflag-an-enum.patch @@ -0,0 +1,166 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:11 -0600 +Subject: [PATCH] libmultipath: make prflag an enum + +In preparation for a future patch, make prflag an enum, and change the +reply of cli_getprstatus() to a string. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist_int.c | 2 +- + libmultipath/structs.h | 8 +++++++- + multipathd/cli_handlers.c | 17 +++++++++-------- + multipathd/main.c | 14 +++++++------- + 4 files changed, 24 insertions(+), 17 deletions(-) + +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index 6924b379..a84d9474 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -783,7 +783,7 @@ int update_map_pr(struct multipath *mpp) + + if (isFound) + { +- mpp->prflag = 1; ++ mpp->prflag = PRFLAG_SET; + condlog(2, "%s: prflag flag set.", mpp->alias ); + } + +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 9e2c1ab0..f2265300 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -375,6 +375,12 @@ struct path { + + typedef int (pgpolicyfn) (struct multipath *, vector); + ++ ++enum prflag_value { ++ PRFLAG_UNSET, ++ PRFLAG_SET, ++}; ++ + struct multipath { + char wwid[WWID_SIZE]; + char alias_old[WWID_SIZE]; +@@ -449,7 +455,7 @@ struct multipath { + int prkey_source; + struct be64 reservation_key; + uint8_t sa_flags; +- unsigned char prflag; ++ int prflag; + int all_tg_pt; + struct gen_multipath generic_mp; + bool fpin_must_reload; +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index e65fb75c..7ee2729f 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -1277,6 +1277,10 @@ cli_shutdown (void * v, struct strbuf *reply, void * data) + static int + cli_getprstatus (void * v, struct strbuf *reply, void * data) + { ++ static const char * const prflag_str[] = { ++ [PRFLAG_UNSET] = "unset\n", ++ [PRFLAG_SET] = "set\n", ++ }; + struct multipath * mpp; + struct vectors * vecs = (struct vectors *)data; + char * param = get_keyparam(v, KEY_MAP); +@@ -1287,10 +1291,7 @@ cli_getprstatus (void * v, struct strbuf *reply, void * data) + if (!mpp) + return 1; + +- condlog(3, "%s: prflag = %u", param, (unsigned int)mpp->prflag); +- +- if (print_strbuf(reply, "%d", mpp->prflag) < 0) +- return 1; ++ append_strbuf_str(reply, prflag_str[mpp->prflag]); + + condlog(3, "%s: reply = %s", param, get_strbuf_str(reply)); + +@@ -1310,8 +1311,8 @@ cli_setprstatus(void * v, struct strbuf *reply, void * data) + if (!mpp) + return 1; + +- if (!mpp->prflag) { +- mpp->prflag = 1; ++ if (mpp->prflag != PRFLAG_SET) { ++ mpp->prflag = PRFLAG_SET; + condlog(2, "%s: prflag set", param); + } + +@@ -1332,8 +1333,8 @@ cli_unsetprstatus(void * v, struct strbuf *reply, void * data) + if (!mpp) + return 1; + +- if (mpp->prflag) { +- mpp->prflag = 0; ++ if (mpp->prflag != PRFLAG_UNSET) { ++ mpp->prflag = PRFLAG_UNSET; + condlog(2, "%s: prflag unset", param); + } + +diff --git a/multipathd/main.c b/multipathd/main.c +index f7212d7b..722235c7 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -647,9 +647,9 @@ fail: + + sync_map_state(mpp); + +- if (!mpp->prflag) ++ if (mpp->prflag == PRFLAG_UNSET) + update_map_pr(mpp); +- if (mpp->prflag) ++ if (mpp->prflag == PRFLAG_SET) + pr_register_active_paths(mpp); + + if (retries < 0) +@@ -1200,7 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + int start_waiter = 0; + int ret; + int ro; +- unsigned char prflag = 0; ++ unsigned char prflag = PRFLAG_UNSET; + + /* + * need path UID to go any further +@@ -1330,7 +1330,7 @@ rescan: + if (retries >= 0) { + if (start_waiter) + update_map_pr(mpp); +- if (mpp->prflag && !prflag) ++ if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) + pr_register_active_paths(mpp); + condlog(2, "%s [%s]: path added to devmap %s", + pp->dev, pp->dev_t, mpp->alias); +@@ -2492,7 +2492,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + } + + if (newstate == PATH_UP || newstate == PATH_GHOST) { +- if (pp->mpp->prflag) { ++ if (pp->mpp->prflag == PRFLAG_SET) { + /* + * Check Persistent Reservation. + */ +@@ -2865,7 +2865,7 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) + if (remember_wwid(mpp->wwid) == 1) + trigger_paths_udev_change(mpp, true); + update_map_pr(mpp); +- if (mpp->prflag) ++ if (mpp->prflag == PRFLAG_SET) + pr_register_active_paths(mpp); + } + +@@ -3840,7 +3840,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) + { + condlog(0,"%s: Reservation registration failed. Error: %d", pp->dev, ret); + } +- mpp->prflag = 1; ++ mpp->prflag = PRFLAG_SET; + + free(param); + out: diff --git a/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch b/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch deleted file mode 100644 index 8a25fe0..0000000 --- a/0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:09:52 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: Fix paths for systemd - -With prefix=/usr, systemd files were installed under /usr/usr/lib, -which is bogus. Clean this up, and document how to handle systemd's -"rootprefix" options. Remove the previous SYSTEMDPATH option. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 32001434..351358a9 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -53,10 +53,6 @@ ifndef SYSTEMD - endif - endif - --ifndef SYSTEMDPATH -- SYSTEMDPATH=usr/lib --endif -- - ifndef DEVMAPPER_INCDIR - ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) - DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) -@@ -78,14 +74,22 @@ ifndef LINUX_HEADERS_INCDIR - LINUX_HEADERS_INCDIR = /usr/include - endif - -+# Paths. All these can be overridden on the "make" command line. - prefix = -+# Prefix for binaries - exec_prefix = $(prefix) -+# Prefix for non-essential libraries (libdmmp) - usr_prefix = $(prefix) -+# Where to install systemd-related files. systemd is usually installed under /usr -+# Note: some systemd installations use separate "prefix" and "rootprefix". -+# In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) -+systemd_prefix := /usr -+unitdir := $(systemd_prefix)/lib/systemd/system -+tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d -+modulesloaddir := $(systemd_prefix)/lib/modules-load.d -+libudevdir := $(systemd_prefix)/lib/udev -+udevrulesdir := $(libudevdir)/rules.d - bindir = $(exec_prefix)/sbin --libudevdir = $(prefix)/$(SYSTEMDPATH)/udev --tmpfilesdir = $(prefix)/$(SYSTEMDPATH)/tmpfiles.d --udevrulesdir = $(libudevdir)/rules.d --modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d - multipathdir = $(TOPDIR)/libmultipath - daemondir = $(TOPDIR)/multipathd - mpathutildir = $(TOPDIR)/libmpathutil -@@ -95,7 +99,6 @@ man3dir = $(usr_prefix)/share/man/man3 - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath --unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system - mpathpersistdir = $(TOPDIR)/libmpathpersist - mpathcmddir = $(TOPDIR)/libmpathcmd - mpathvaliddir = $(TOPDIR)/libmpathvalid diff --git a/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch b/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch new file mode 100644 index 0000000..59dd10f --- /dev/null +++ b/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch @@ -0,0 +1,152 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:12 -0600 +Subject: [PATCH] multipathd: handle no active paths in update_map_pr + +When a multipath device is first created, if it has a reservation key +configured, update_map_pr() will check for a matching key on the active +paths. If there were no active paths to check with, multipathd was +leaving mpp->prflag in PRFLAG_UNSET, as if there were no matching keys. +It's possible that when update_map_pr() is called, all the paths will be +in the PATH_PENDING state because the checkers haven't completed yet. In +this case, multipathd was treating the device as having no registered +keys without ever checking. + +To solve this, multipath devices now start with prflag = PRFLAG_UNKNOWN. +It will remain in this state until multipathd actually tries to get the +registered keys down a path. If the map is in this state, it will check +newly active paths, and if it finds a matching key, it will register +the key down all active paths. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmpathpersist/mpath_persist_int.c | 8 ++++++++ + libmultipath/structs.h | 1 + + multipathd/cli_handlers.c | 1 + + multipathd/main.c | 19 ++++++++++++++----- + 4 files changed, 24 insertions(+), 5 deletions(-) + +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index a84d9474..8b52b746 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -738,6 +738,7 @@ int update_map_pr(struct multipath *mpp) + if (!get_be64(mpp->reservation_key)) + { + /* Nothing to do. Assuming pr mgmt feature is disabled*/ ++ mpp->prflag = PRFLAG_UNSET; + condlog(4, "%s: reservation_key not set in multipath.conf", + mpp->alias); + return MPATH_PR_SUCCESS; +@@ -749,6 +750,13 @@ int update_map_pr(struct multipath *mpp) + condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias); + return MPATH_PR_OTHER; + } ++ if (count_active_paths(mpp) == 0) ++ { ++ condlog(0,"%s: No available paths to check pr status", ++ mpp->alias); ++ return MPATH_PR_OTHER; ++ } ++ mpp->prflag = PRFLAG_UNSET; + ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); + + if (ret != MPATH_PR_SUCCESS ) +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index f2265300..e2294323 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -377,6 +377,7 @@ typedef int (pgpolicyfn) (struct multipath *, vector); + + + enum prflag_value { ++ PRFLAG_UNKNOWN, + PRFLAG_UNSET, + PRFLAG_SET, + }; +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 7ee2729f..ec5db1b8 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -1278,6 +1278,7 @@ static int + cli_getprstatus (void * v, struct strbuf *reply, void * data) + { + static const char * const prflag_str[] = { ++ [PRFLAG_UNKNOWN] = "unknown\n", + [PRFLAG_UNSET] = "unset\n", + [PRFLAG_SET] = "set\n", + }; +diff --git a/multipathd/main.c b/multipathd/main.c +index 722235c7..bdeffe76 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -647,7 +647,7 @@ fail: + + sync_map_state(mpp); + +- if (mpp->prflag == PRFLAG_UNSET) ++ if (mpp->prflag != PRFLAG_SET) + update_map_pr(mpp); + if (mpp->prflag == PRFLAG_SET) + pr_register_active_paths(mpp); +@@ -1330,7 +1330,7 @@ rescan: + if (retries >= 0) { + if (start_waiter) + update_map_pr(mpp); +- if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) ++ if (mpp->prflag == PRFLAG_SET && prflag != PRFLAG_SET) + pr_register_active_paths(mpp); + condlog(2, "%s [%s]: path added to devmap %s", + pp->dev, pp->dev_t, mpp->alias); +@@ -2492,13 +2492,17 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + } + + if (newstate == PATH_UP || newstate == PATH_GHOST) { +- if (pp->mpp->prflag == PRFLAG_SET) { ++ if (pp->mpp->prflag != PRFLAG_UNSET) { ++ int prflag = pp->mpp->prflag; + /* + * Check Persistent Reservation. + */ + condlog(2, "%s: checking persistent " + "reservation registration", pp->dev); + mpath_pr_event_handle(pp); ++ if (pp->mpp->prflag == PRFLAG_SET && ++ prflag != PRFLAG_SET) ++ pr_register_active_paths(pp->mpp); + } + } + +@@ -3788,6 +3792,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) + goto out; + } + ++ mpp->prflag = PRFLAG_UNSET; + ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp, 0); + if (ret != MPATH_PR_SUCCESS ) + { +@@ -3858,12 +3863,12 @@ int mpath_pr_event_handle(struct path *pp) + struct multipath * mpp; + + if (pp->bus != SYSFS_BUS_SCSI) +- return 0; ++ goto no_pr; + + mpp = pp->mpp; + + if (!get_be64(mpp->reservation_key)) +- return -1; ++ goto no_pr; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); +@@ -3876,4 +3881,8 @@ int mpath_pr_event_handle(struct path *pp) + pthread_attr_destroy(&attr); + rc = pthread_join(thread, NULL); + return 0; ++ ++no_pr: ++ pp->mpp->prflag = PRFLAG_UNSET; ++ return 0; + } diff --git a/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch b/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch deleted file mode 100644 index 5c1b7b3..0000000 --- a/0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 13:24:34 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: don't take values from - environment - -Don't use environment variables to initialize LIB, RUN, SYSTEMD, SYSTEMDPATH, -DEVMAPPER_INCDIR, LIBUDEV_INCDIR, and LINUX_HEADERS_INCDIR. Taking -such variables from the environment is generally discouraged -(see https://www.gnu.org/software/make/manual/html_node/Environment.html). - -Overriding variables from the commandline is still possible -(https://www.gnu.org/software/make/manual/html_node/Overriding.html). -So now, when building multipath-tools, rather then running -"RUN=/somedir make", users need to run "make RUN=/somedir". - -This simplifies the Makefile without losing important functionality. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 60 ++++++++++++++++++++++------------------------------ - 1 file changed, 25 insertions(+), 35 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 351358a9..d897ac7a 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -20,59 +20,49 @@ SCSI_DH_MODULES_PRELOAD := - - EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) - -+# PKGCONFIG must be read from the environment to enable compilation -+# in Debian multiarch setups - PKGCONFIG ?= pkg-config - - ifeq ($(TOPDIR),) - TOPDIR = .. - endif - --ifndef LIB -- ifeq ($(shell test -d /lib64 && echo 1),1) -- LIB=lib64 -- else -- LIB=lib -- endif -+ifeq ($(shell test -d /lib64 && echo 1),1) -+ LIB=lib64 -+else -+ LIB=lib - endif - --ifndef RUN -- ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) -- RUN=run -- else -- RUN=var/run -- endif -+ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) -+ RUN=run -+else -+ RUN=var/run - endif - --ifndef SYSTEMD -- ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') -- else -- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ -- sed -n 's/systemd \([0-9]*\).*/\1/p') -- endif -+ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -+ SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') -+else -+ ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) -+ SYSTEMD = $(shell systemctl --version 2> /dev/null | \ -+ sed -n 's/systemd \([0-9]*\).*/\1/p') - endif - endif - --ifndef DEVMAPPER_INCDIR -- ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) -- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) -- else -- DEVMAPPER_INCDIR = /usr/include -- endif -+ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) -+ DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) -+else -+ DEVMAPPER_INCDIR = /usr/include - endif - --ifndef LIBUDEV_INCDIR -- ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) -- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) -- else -- LIBUDEV_INCDIR = /usr/include -- endif -+ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) -+ LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) -+else -+ LIBUDEV_INCDIR = /usr/include - endif - - # Allow user to override default location. --ifndef LINUX_HEADERS_INCDIR -- LINUX_HEADERS_INCDIR = /usr/include --endif -+LINUX_HEADERS_INCDIR = /usr/include - - # Paths. All these can be overridden on the "make" command line. - prefix = diff --git a/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch b/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch new file mode 100644 index 0000000..085fd70 --- /dev/null +++ b/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:13 -0600 +Subject: [PATCH] multipathd: add missing newline to cli_del_map reply + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/cli_handlers.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index ec5db1b8..44bf43df 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -760,7 +760,7 @@ cli_del_map (void * v, struct strbuf *reply, void * data) + } + rc = ev_remove_map(param, alias, minor, vecs); + if (rc == 2) +- append_strbuf_str(reply, "delayed"); ++ append_strbuf_str(reply, "delayed\n"); + + free(alias); + return rc; diff --git a/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch b/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch new file mode 100644 index 0000000..ee08327 --- /dev/null +++ b/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:14 -0600 +Subject: [PATCH] libmultipath: skip extra vector work in remove_maps + +Instead of repeatedly removing the first vector element, and shifting +the rest to fill in, call remove_map() without a vector, so it just +frees the devices. The vector will be completely cleaned up by +vector_free() immediately afterwards. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/structs_vec.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 5a618767..f3fdc5a6 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -392,10 +392,8 @@ remove_maps(struct vectors * vecs) + if (!vecs) + return; + +- vector_foreach_slot (vecs->mpvec, mpp, i) { +- remove_map(mpp, vecs->pathvec, vecs->mpvec); +- i--; +- } ++ vector_foreach_slot (vecs->mpvec, mpp, i) ++ remove_map(mpp, vecs->pathvec, NULL); + + vector_free(vecs->mpvec); + vecs->mpvec = NULL; diff --git a/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch b/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch deleted file mode 100644 index c0543f5..0000000 --- a/0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 15:25:31 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: get rid of RUN - -Just use $(runtimedir). Also, make the code more compact by using -the "if" function instead of a conditional. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 10 ++-------- - libmultipath/defaults.h | 2 +- - 2 files changed, 3 insertions(+), 9 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index d897ac7a..b4ec647c 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -34,12 +34,6 @@ else - LIB=lib - endif - --ifeq ($(shell test -L /var/run -o ! -d /var/run && echo 1),1) -- RUN=run --else -- RUN=var/run --endif -- - ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') - else -@@ -99,7 +93,7 @@ includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d --runtimedir := /$(RUN) -+runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - - GZIP_PROG = gzip -9 -c - RM = rm -f -@@ -143,7 +137,7 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) - CPPFLAGS := $(FORTIFY_OPT) \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ -+ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" \ - -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 3d552b33..a5e9ea0c 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -62,7 +62,7 @@ - - #define DEV_LOSS_TMO_UNSET 0U - #define MAX_DEV_LOSS_TMO UINT_MAX --#define DEFAULT_PIDFILE "/" RUN_DIR "/multipathd.pid" -+#define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" - #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" - #define DEFAULT_CONFIGFILE "/etc/multipath.conf" - #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" diff --git a/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch b/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch new file mode 100644 index 0000000..f545df7 --- /dev/null +++ b/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 20 Dec 2022 17:41:15 -0600 +Subject: [PATCH] libmultipath: orphan paths if coalesce_paths frees newmp + +If coalesce_paths() is called without a mpvec, it will free all the +multipath devices on newmp at the end. This will clear pp->mpp from the +path, but it doesn't completely unitialize them. cli_add_map() can call +coalsce_paths() this way, when adding a device that doesn't currently +exist. cli_add_map() first creates the device in the kernel, and then +calls ev_add_map() to add it to multipathd. If something goes wrong in +ev_add_map(), the paths will still be initialized, even though they're +orphans. + +Fix this by calling remove_map() to orphan the paths that belong to +the multipath devices being deleted by coalesce_paths(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e551047a..e689f8a7 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1273,8 +1273,11 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + ret = CP_OK; + out: + free(size_mismatch_seen); +- if (!mpvec) +- free_multipathvec(newmp, KEEP_PATHS); ++ if (!mpvec) { ++ vector_foreach_slot (newmp, mpp, i) ++ remove_map(mpp, vecs->pathvec, NULL); ++ vector_free(newmp); ++ } + return ret; + } + diff --git a/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch b/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch deleted file mode 100644 index 2a0eda4..0000000 --- a/0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:14:22 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: more compact code for LIB - -Use make's "if" function instead of a conditional. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index b4ec647c..c39cec9b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -28,12 +28,6 @@ ifeq ($(TOPDIR),) - TOPDIR = .. - endif - --ifeq ($(shell test -d /lib64 && echo 1),1) -- LIB=lib64 --else -- LIB=lib --endif -- - ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') - else -@@ -80,6 +74,7 @@ mpathutildir = $(TOPDIR)/libmpathutil - man8dir = $(usr_prefix)/share/man/man8 - man5dir = $(usr_prefix)/share/man/man5 - man3dir = $(usr_prefix)/share/man/man3 -+LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath diff --git a/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch b/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch new file mode 100644 index 0000000..6ffa6fc --- /dev/null +++ b/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch @@ -0,0 +1,609 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 9 Nov 2022 21:20:58 +0100 +Subject: [PATCH] libmultipath: is_path_valid(): check if device is in use + +To check whether we will be able to add a given device can be part +of a multipath map, we have two tests in check_path_valid(): +released_to_systemd() and the O_EXCL test. The former isn't helpful +if "multipath -u" is called for the first time for a given device, +and the latter is only used in the "find_multipaths smart" case, because +actively opening the device with O_EXCL, even for a very short time, is prone +to races with other processes. + +It turns out that this may cause issues in some scenarios. We saw problems in +once case where "find_multipaths greedy" was used with a single +non-multipahted root disk and a very large number of multipath LUNs. +The root disk would first be classified as multipath device. multipathd +would try to create a map, fail (because the disk was mounted) and +trigger another uevent. But because of the very large number of multipath +devices, this event was queued up behind thousands of other events, and +the root device timed out eventually. + +While a simple workaround for the given problem would be proper blacklisting +or using a different find_multipaths mode, I am proposing a different +solution here. An additional test is added in is_path_valid() which +checks whether the given device is currently in use by 1. sysfs holders, +2. mounts (from /proc/self/mountinfo) or 3. swaps (from /proc/swaps). 2. +and 3. are similar to systemd's device detection after switching root. +This must not only be done for the device itself, but also for all its +partitions. For mountinfo and swaps, libmount is utilized. + +With this patch, "multipath -u" will make devices with mounted or otherwise +used partitions available to systemd early, without waiting for multipathd +to fail setting up the map and re-triggering an uevent. This should avoid +the issue described above even without blacklisting. The downside of it +is a longer runtime of "multipath -u" for almost all devices, in particular +for real multipath devices. The runtime required for the new checks was in the +order of 0.1ms-1ms in my tests. Moreover, there is a certain risk that devices may +wrongly classified as non-multipath because of transient mounts or holders +created by other processes. + +To make this code compile on older distributions, we need some additional +checks in create-config.mk. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 +- + create-config.mk | 11 +- + libmpathutil/libmpathutil.version | 6 + + libmpathutil/util.c | 12 + + libmpathutil/util.h | 2 + + libmultipath/Makefile | 2 +- + libmultipath/alias.c | 11 - + libmultipath/valid.c | 270 ++++++++++++++++++++++ + tests/Makefile | 2 +- + tests/valid.c | 48 ++++ + 10 files changed, 351 insertions(+), 15 deletions(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index abf17bf0..9e6c0e89 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -31,7 +31,7 @@ jobs: + sudo apt-get install --yes gcc + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev libmount-dev + - name: build + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} + - name: test +diff --git a/create-config.mk b/create-config.mk +index 2a95ec56..f128375f 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -23,7 +23,7 @@ check_cmd = $(shell \ + + # Check whether a function with name $1 has been declared in header file $2. + check_func = $(shell \ +- if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ ++ if grep -Eq "^(extern[[:blank:]]+)?[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ + found=1; \ + status="yes"; \ + else \ +@@ -104,6 +104,15 @@ ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h + FPIN_SUPPORT = 1 + endif + ++libmount_h := $(shell $(PKGCONFIG) --variable=includedir mount)/libmount/libmount.h ++ifneq ($(call check_func,mnt_unref_cache,$(libmount_h)),0) ++ DEFINES += LIBMOUNT_HAS_MNT_UNREF_CACHE ++endif ++ ++ifneq ($(call check_func,mnt_table_parse_swaps,$(libmount_h)),0) ++ DEFINES += LIBMOUNT_SUPPORTS_SWAP ++endif ++ + ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) + ANA_SUPPORT := 1 + endif +diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version +index 1238fc93..dd007be4 100644 +--- a/libmpathutil/libmpathutil.version ++++ b/libmpathutil/libmpathutil.version +@@ -133,3 +133,9 @@ LIBMPATHUTIL_1.1 { + global: + cleanup_fd_ptr; + } LIBMPATHUTIL_1.0; ++ ++LIBMPATHUTIL_1.2 { ++global: ++ cleanup_vector_free; ++ cleanup_fclose; ++} LIBMPATHUTIL_1.0; +diff --git a/libmpathutil/util.c b/libmpathutil/util.c +index 9662e1ed..92f25a50 100644 +--- a/libmpathutil/util.c ++++ b/libmpathutil/util.c +@@ -386,6 +386,18 @@ void cleanup_mutex(void *arg) + pthread_mutex_unlock(arg); + } + ++void cleanup_vector_free(void *arg) ++{ ++ if (arg) ++ vector_free((vector)arg); ++} ++ ++void cleanup_fclose(void *p) ++{ ++ if (p) ++ fclose(p); ++} ++ + struct bitfield *alloc_bitfield(unsigned int maxbit) + { + unsigned int n; +diff --git a/libmpathutil/util.h b/libmpathutil/util.h +index 75e20fd8..99a471d0 100644 +--- a/libmpathutil/util.h ++++ b/libmpathutil/util.h +@@ -48,6 +48,8 @@ int should_exit(void); + void cleanup_fd_ptr(void *arg); + void cleanup_free_ptr(void *arg); + void cleanup_mutex(void *arg); ++void cleanup_vector_free(void *arg); ++void cleanup_fclose(void *p); + + struct scandir_result { + struct dirent **di; +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 3df851e2..61aa611f 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -7,7 +7,7 @@ DEVLIB := libmultipath.so + CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) + CFLAGS += $(LIB_CFLAGS) + LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ +- -lurcu -laio $(SYSTEMD_LIBDEPS) ++ -lmount -lurcu -laio $(SYSTEMD_LIBDEPS) + + # object files referencing MULTIPATH_DIR or CONFIG_DIR + # they need to be recompiled for unit tests +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 05201224..c0139a2e 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -667,11 +667,6 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + return rc; + } + +-static void cleanup_fclose(void *p) +-{ +- fclose(p); +-} +- + static int alias_compar(const void *p1, const void *p2) + { + const char *alias1 = (*(struct mpentry * const *)p1)->alias; +@@ -684,12 +679,6 @@ static int alias_compar(const void *p1, const void *p2) + return alias1 ? -1 : alias2 ? 1 : 0; + } + +-static void cleanup_vector_free(void *arg) +-{ +- if (arg) +- vector_free((vector)arg); +-} +- + /* + * check_alias_settings(): test for inconsistent alias configuration + * +diff --git a/libmultipath/valid.c b/libmultipath/valid.c +index a6aa9215..d4dae3ed 100644 +--- a/libmultipath/valid.c ++++ b/libmultipath/valid.c +@@ -17,6 +17,8 @@ + #include + #include + #include ++#include ++#include + + #include "vector.h" + #include "config.h" +@@ -30,12 +32,271 @@ + #include "mpath_cmd.h" + #include "valid.h" + ++static int subdir_filter(const struct dirent *ent) ++{ ++ unsigned int j; ++ static char const *const skip[] = { ++ ".", ++ "..", ++ "holders", ++ "integrity", ++ "mq", ++ "power", ++ "queue", ++ "slaves", ++ "trace", ++ }; ++ ++ if (ent->d_type != DT_DIR) ++ return 0; ++ ++ for (j = 0; j < ARRAY_SIZE(skip); j++) ++ if (!strcmp(skip[j], ent->d_name)) ++ return 0; ++ return 1; ++} ++ ++static int read_partitions(const char *syspath, vector parts) ++{ ++ struct scandir_result sr = { .n = 0 }; ++ char path[PATH_MAX], *last; ++ char *prop; ++ int i; ++ ++ strlcpy(path, syspath, sizeof(path)); ++ sr.n = scandir(path, &sr.di, subdir_filter, NULL); ++ if (sr.n == -1) ++ return -errno; ++ ++ pthread_cleanup_push_cast(free_scandir_result, &sr); ++ ++ /* parts[0] is the whole disk */ ++ if ((prop = strdup(strrchr(path, '/') + 1)) != NULL) { ++ if (vector_alloc_slot(parts)) ++ vector_set_slot(parts, prop); ++ else ++ free(prop); ++ } ++ ++ last = path + strlen(path); ++ for (i = 0; i < sr.n; i++) { ++ struct stat st; ++ ++ /* only add dirs that have the "partition" attribute */ ++ snprintf(last, sizeof(path) - (last - path), "/%s/partition", ++ sr.di[i]->d_name); ++ ++ if (stat(path, &st) == 0 && ++ (prop = strdup(sr.di[i]->d_name)) != NULL) { ++ if (vector_alloc_slot(parts)) ++ vector_set_slot(parts, prop); ++ else ++ free(prop); ++ } ++ } ++ ++ pthread_cleanup_pop(1); ++ return 0; ++} ++ ++static int no_dots(const struct dirent *ent) ++{ ++ const char *name = ent->d_name; ++ ++ if (name[0] == '.' && ++ (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) ++ return 0; ++ return 1; ++} ++ ++static int check_holders(const char *syspath) ++{ ++ struct scandir_result __attribute__((cleanup(free_scandir_result))) ++ sr = { .n = 0 }; ++ ++ sr.n = scandir(syspath, &sr.di, no_dots, NULL); ++ if (sr.n > 0) ++ condlog(4, "%s: found holders under %s", __func__, syspath); ++ return sr.n; ++} ++ ++static int check_all_holders(const struct _vector *parts) ++{ ++ char syspath[PATH_MAX]; ++ const char *sysname; ++ unsigned int j; ++ ++ if (VECTOR_SIZE(parts) == 0) ++ return 0; ++ ++ if (safe_sprintf(syspath, "/sys/class/block/%s/holders", ++ (const char *)VECTOR_SLOT(parts, 0))) ++ return -EOVERFLOW; ++ ++ if (check_holders(syspath) > 0) ++ return 1; ++ ++ j = 1; ++ vector_foreach_slot_after(parts, sysname, j) { ++ if (safe_sprintf(syspath, "/sys/class/block/%s/%s/holders", ++ (const char *)VECTOR_SLOT(parts, 0), sysname)) ++ return -EOVERFLOW; ++ if (check_holders(syspath) > 0) ++ return 1; ++ } ++ return 0; ++} ++ ++static void cleanup_table(void *arg) ++{ ++ if (arg) ++ mnt_free_table((struct libmnt_table *)arg); ++} ++ ++static void cleanup_cache(void *arg) ++{ ++ if (arg) ++#ifdef LIBMOUNT_HAS_MNT_UNREF_CACHE ++ mnt_unref_cache((struct libmnt_cache *)arg); ++#else ++ mnt_free_cache((struct libmnt_cache *)arg); ++#endif ++} ++ ++/* ++ * Passed a vector of partitions and a libmount table, ++ * check if any of the partitions in the vector is referenced in the table. ++ * Note that mnt_table_find_srcpath() also resolves mounts by symlinks. ++ */ ++static int check_mnt_table(const struct _vector *parts, ++ struct libmnt_table *tbl, ++ const char *table_name) ++{ ++ unsigned int i; ++ const char *sysname; ++ char devpath[PATH_MAX]; ++ ++ vector_foreach_slot(parts, sysname, i) { ++ if (!safe_sprintf(devpath, "/dev/%s", sysname) && ++ mnt_table_find_srcpath(tbl, devpath, ++ MNT_ITER_FORWARD) != NULL) { ++ condlog(4, "%s: found %s in %s", __func__, ++ sysname, table_name); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++static int check_mountinfo(const struct _vector *parts) ++{ ++ static const char mountinfo[] = "/proc/self/mountinfo"; ++ struct libmnt_table *tbl; ++ struct libmnt_cache *cache; ++ FILE *stream; ++ int used = 0, ret; ++ ++ tbl = mnt_new_table(); ++ if (!tbl ) ++ return -errno; ++ ++ pthread_cleanup_push(cleanup_table, tbl); ++ cache = mnt_new_cache(); ++ if (cache) { ++ pthread_cleanup_push(cleanup_cache, cache); ++ if (mnt_table_set_cache(tbl, cache) == 0) { ++ stream = fopen(mountinfo, "r"); ++ if (stream != NULL) { ++ pthread_cleanup_push(cleanup_fclose, stream); ++ ret = mnt_table_parse_stream(tbl, stream, mountinfo); ++ pthread_cleanup_pop(1); ++ ++ if (ret == 0) ++ used = check_mnt_table(parts, tbl, ++ "mountinfo"); ++ } ++ } ++ pthread_cleanup_pop(1); ++ } ++ pthread_cleanup_pop(1); ++ return used; ++} ++ ++#ifdef LIBMOUNT_SUPPORTS_SWAP ++static int check_swaps(const struct _vector *parts) ++{ ++ struct libmnt_table *tbl; ++ struct libmnt_cache *cache; ++ int used = 0, ret; ++ ++ tbl = mnt_new_table(); ++ if (!tbl ) ++ return -errno; ++ ++ pthread_cleanup_push(cleanup_table, tbl); ++ cache = mnt_new_cache(); ++ if (cache) { ++ pthread_cleanup_push(cleanup_cache, cache); ++ if (mnt_table_set_cache(tbl, cache) == 0) { ++ ret = mnt_table_parse_swaps(tbl, NULL); ++ if (ret == 0) ++ used = check_mnt_table(parts, tbl, "swaps"); ++ } ++ pthread_cleanup_pop(1); ++ } ++ pthread_cleanup_pop(1); ++ return used; ++} ++#else ++static int check_swaps(const struct _vector *parts __attribute__((unused))) ++{ ++ return 0; ++} ++#endif ++ ++ ++/* ++ * Given a block device, check if the device itself or any of its ++ * partitions is in use ++ * - by sysfs holders (e.g. LVM) ++ * - mounted according to /proc/self/mountinfo ++ * - used as swap ++ */ ++static int is_device_in_use(struct udev_device *udevice) ++{ ++ const char *syspath; ++ vector parts; ++ int used = 0, ret; ++ ++ syspath = udev_device_get_syspath(udevice); ++ if (!syspath) ++ return -ENOMEM; ++ ++ parts = vector_alloc(); ++ if (!parts) ++ return -ENOMEM; ++ ++ pthread_cleanup_push_cast(free_strvec, parts); ++ if ((ret = read_partitions(syspath, parts)) == 0) ++ used = check_all_holders(parts) > 0 || ++ check_mountinfo(parts) > 0 || ++ check_swaps(parts) > 0; ++ pthread_cleanup_pop(1); ++ ++ if (ret < 0) ++ return ret; ++ ++ condlog(3, "%s: %s is %sin use", __func__, syspath, used ? "" : "not "); ++ return used; ++} ++ + int + is_path_valid(const char *name, struct config *conf, struct path *pp, + bool check_multipathd) + { + int r; + int fd; ++ const char *prop; + + if (!pp || !name || !conf) + return PATH_IS_ERROR; +@@ -80,6 +341,10 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, + if (!pp->udev) + return PATH_IS_ERROR; + ++ prop = udev_device_get_property_value(pp->udev, "DEVTYPE"); ++ if (prop == NULL || strcmp(prop, "disk")) ++ return PATH_IS_NOT_VALID; ++ + r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); + if (r == PATHINFO_SKIPPED) + return PATH_IS_NOT_VALID; +@@ -96,6 +361,11 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, + return PATH_IS_ERROR; + } + ++ if ((conf->find_multipaths == FIND_MULTIPATHS_GREEDY || ++ conf->find_multipaths == FIND_MULTIPATHS_SMART) && ++ is_device_in_use(pp->udev) > 0) ++ return PATH_IS_NOT_VALID; ++ + if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) + return PATH_IS_VALID; + +diff --git a/tests/Makefile b/tests/Makefile +index 860338b2..1648ab9d 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -55,7 +55,7 @@ vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o + alias-test_LIBDEPS := -lpthread -ldl + valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o +-valid-test_LIBDEPS := -ludev -lpthread -ldl ++valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl + devt-test_LIBDEPS := -ludev + mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl + mpathvalid-test_OBJDEPS := $(mpathvaliddir)/mpath_valid.o +diff --git a/tests/valid.c b/tests/valid.c +index 398b771e..70329324 100644 +--- a/tests/valid.c ++++ b/tests/valid.c +@@ -83,6 +83,13 @@ struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *u + return NULL; + } + ++/* For devtype check */ ++const char *__wrap_udev_device_get_property_value(struct udev_device *udev_device, const char *property) ++{ ++ check_expected(property); ++ return mock_ptr_type(char *); ++} ++ + /* For the "hidden" check in pathinfo() */ + const char *__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, + const char *sysattr) +@@ -97,6 +104,12 @@ int __wrap_add_foreign(struct udev_device *udev_device) + return mock_type(int); + } + ++/* For is_device_used() */ ++const char *__wrap_udev_device_get_sysname(struct udev_device *udev_device) ++{ ++ return mock_ptr_type(char *); ++} ++ + /* called from pathinfo() */ + int __wrap_filter_devnode(struct config *conf, const struct _vector *elist, + const char *vendor, const char * product, const char *dev) +@@ -165,6 +178,11 @@ int __wrap_is_failed_wwid(const char *wwid) + return ret; + } + ++const char *__wrap_udev_device_get_syspath(struct udev_device *udevice) ++{ ++ return mock_ptr_type(char *); ++} ++ + int __wrap_check_wwids_file(char *wwid, int write_wwid) + { + bool passed = mock_type(bool); +@@ -225,6 +243,8 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, + will_return(__wrap_udev_device_new_from_subsystem_sysname, true); + will_return(__wrap_udev_device_new_from_subsystem_sysname, + name); ++ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); ++ will_return(__wrap_udev_device_get_property_value, "disk"); + if (stage == STAGE_GET_UDEV_DEVICE) + return; + if (stage == STAGE_PATHINFO_REAL) { +@@ -250,6 +270,10 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, + return; + will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); + will_return(__wrap_is_failed_wwid, wwid); ++ /* avoid real is_device_in_use() check */ ++ if (conf.find_multipaths == FIND_MULTIPATHS_GREEDY || ++ conf.find_multipaths == FIND_MULTIPATHS_SMART) ++ will_return(__wrap_udev_device_get_syspath, NULL); + if (stage == STAGE_IS_FAILED) + return; + will_return(__wrap_check_wwids_file, false); +@@ -347,6 +371,30 @@ static void test_check_multipathd(void **state) + assert_int_equal(is_path_valid(name, &conf, &pp, true), + PATH_IS_ERROR); + assert_string_equal(pp.dev, name); ++ ++ /* test pass because connect succeeded. succeed getting udev. Wrong DEVTYPE */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); ++ will_return(__wrap_udev_device_get_property_value, "partition"); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); ++ ++ /* test pass because connect succeeded. succeed getting udev. Bad DEVTYPE */ ++ memset(&pp, 0, sizeof(pp)); ++ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); ++ will_return(__wrap_udev_device_new_from_subsystem_sysname, ++ name); ++ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); ++ will_return(__wrap_udev_device_get_property_value, NULL); ++ assert_int_equal(is_path_valid(name, &conf, &pp, true), ++ PATH_IS_NOT_VALID); ++ assert_string_equal(pp.dev, name); + } + + static void test_pathinfo(void **state) diff --git a/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch b/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch deleted file mode 100644 index c6be343..0000000 --- a/0007-multipath-tools-Makefiles-simplify-code-for-include-.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:17:40 +0200 -Subject: [PATCH] multipath-tools: Makefiles: simplify code for include dirs - -Use make's if function, and use lower-case latters for make variable -names that represent directories, such as elsewhere. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 16 +++------------- - kpartx/Makefile | 2 +- - libmultipath/Makefile | 14 +++++++------- - libmultipath/prioritizers/Makefile | 2 +- - multipathd/Makefile | 4 ++-- - 5 files changed, 14 insertions(+), 24 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index c39cec9b..38bd1d80 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -37,20 +37,7 @@ else - endif - endif - --ifeq ($(shell $(PKGCONFIG) --modversion devmapper >/dev/null 2>&1 && echo 1), 1) -- DEVMAPPER_INCDIR = $(shell $(PKGCONFIG) --variable=includedir devmapper) --else -- DEVMAPPER_INCDIR = /usr/include --endif -- --ifeq ($(shell $(PKGCONFIG) --modversion libudev >/dev/null 2>&1 && echo 1), 1) -- LIBUDEV_INCDIR = $(shell $(PKGCONFIG) --variable=includedir libudev) --else -- LIBUDEV_INCDIR = /usr/include --endif -- - # Allow user to override default location. --LINUX_HEADERS_INCDIR = /usr/include - - # Paths. All these can be overridden on the "make" command line. - prefix = -@@ -89,6 +76,9 @@ pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) -+devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/usr/include) -+libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) -+kernel_incdir := /usr/include - - GZIP_PROG = gzip -9 -c - RM = rm -f -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 742d3bcd..bdf2d035 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -9,7 +9,7 @@ LDFLAGS += $(BIN_LDFLAGS) - - LIBDEPS += -ldevmapper - --ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE - endif - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 3b60a525..f0df27c0 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -22,31 +22,31 @@ ifdef SYSTEMD - endif - endif - --ifneq ($(call check_func,dm_task_no_flush,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_FLUSH - endif - --ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO - endif - --ifneq ($(call check_func,dm_task_set_cookie,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE - endif - --ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(LIBUDEV_INCDIR)/libudev.h),0) -+ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) - CPPFLAGS += -DLIBUDEV_API_RECVBUF - endif - --ifneq ($(call check_func,dm_task_deferred_remove,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_DEFERRED - endif - --ifneq ($(call check_func,dm_hold_control_dev,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_HOLD_CONTROL - endif - --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER - endif - -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 400f7735..97155f51 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -26,7 +26,7 @@ LIBS = \ - libpriopath_latency.so \ - libpriosysfs.so - --ifneq ($(call check_file,$(LINUX_HEADERS_INCDIR)/linux/nvme_ioctl.h),0) -+ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) - LIBS += libprioana.so - CPPFLAGS += -I../nvme - endif -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 3ce9465e..c462d7b1 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -1,10 +1,10 @@ - include ../Makefile.inc - --ifneq ($(call check_func,dm_task_get_errno,$(DEVMAPPER_INCDIR)/libdevmapper.h),0) -+ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO - endif - --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(LINUX_HEADERS_INCDIR)/scsi/fc/fc_els.h),0) -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER - FPIN_SUPPORT = 1 - endif diff --git a/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch b/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch new file mode 100644 index 0000000..9f3dcb2 --- /dev/null +++ b/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 2 Jan 2023 12:39:36 +0100 +Subject: [PATCH] libmpathpersist: use conf->timeout for updating persistent + reservations + +On systems with many LUNs, multipathd may fail to respond within the +default timeout to a "setprkey" command because the vecs lock is held +by the path checker. Honor the globally configured uxsock timeout in +libmpathpersist. + +Reported-by: boposki (github.com/opensvc/multipath-tools/pull/58) +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_updatepr.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c +index 4529a82b..36bd777e 100644 +--- a/libmpathpersist/mpath_updatepr.c ++++ b/libmpathpersist/mpath_updatepr.c +@@ -14,6 +14,9 @@ + #include + #include "debug.h" + #include "mpath_cmd.h" ++#include "vector.h" ++#include "globals.h" ++#include "config.h" + #include "uxsock.h" + #include "mpathpr.h" + +@@ -24,6 +27,12 @@ static int do_update_pr(char *alias, char *cmd, char *key) + char str[256]; + char *reply; + int ret = 0; ++ int timeout; ++ struct config *conf; ++ ++ conf = get_multipath_config(); ++ timeout = conf->uxsock_timeout; ++ put_multipath_config(conf); + + fd = mpath_connect(); + if (fd == -1) { +@@ -41,7 +50,7 @@ static int do_update_pr(char *alias, char *cmd, char *key) + mpath_disconnect(fd); + return -1; + } +- ret = recv_packet(fd, &reply, DEFAULT_REPLY_TIMEOUT); ++ ret = recv_packet(fd, &reply, timeout); + if (ret < 0) { + condlog(2, "%s: message=%s recv error=%d", alias, str, errno); + ret = -1; diff --git a/0008-multipath-tools-Makefiles-use-mandir.patch b/0008-multipath-tools-Makefiles-use-mandir.patch deleted file mode 100644 index 10e1ca8..0000000 --- a/0008-multipath-tools-Makefiles-use-mandir.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:25:04 +0200 -Subject: [PATCH] multipath-tools: Makefiles: use $(mandir) - -Simply use $(mandir) rather than 3 different variables. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 4 +--- - kpartx/Makefile | 6 +++--- - libdmmp/Makefile | 8 ++++---- - libmpathpersist/Makefile | 10 +++++----- - mpathpersist/Makefile | 6 +++--- - multipath/Makefile | 12 ++++++------ - multipathd/Makefile | 10 +++++----- - 7 files changed, 27 insertions(+), 29 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 38bd1d80..f3c84771 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -58,9 +58,7 @@ bindir = $(exec_prefix)/sbin - multipathdir = $(TOPDIR)/libmultipath - daemondir = $(TOPDIR)/multipathd - mpathutildir = $(TOPDIR)/libmpathutil --man8dir = $(usr_prefix)/share/man/man8 --man5dir = $(usr_prefix)/share/man/man5 --man3dir = $(usr_prefix)/share/man/man3 -+mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) -diff --git a/kpartx/Makefile b/kpartx/Makefile -index bdf2d035..464925ad 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -32,12 +32,12 @@ install: $(EXEC) $(EXEC).8 - $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules - $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules - $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - $(RM) $(DESTDIR)$(libudevdir)/kpartx_id - $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules - $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index e4589250..985b694b 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -45,17 +45,17 @@ install: - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(man3dir) -- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(man3dir) docs/man/*.3 -+ $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -+ $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 - - uninstall: - $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) - $(RM) $(DESTDIR)$(includedir)/$(HEADERS) - $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -- @for file in $(DESTDIR)$(man3dir)/dmmp_*; do \ -+ @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ - $(RM) $$file; \ - done -- $(RM) $(DESTDIR)$(man3dir)/libdmmp.h* -+ $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* - $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - - clean: dep_clean -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 4e1717ef..479524d4 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -36,17 +36,17 @@ install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(man3dir) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(man3dir) -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(man3dir) -+ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 -+ $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 - $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) - - uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_in.3 -- $(RM) $(DESTDIR)$(man3dir)/mpath_persistent_reserve_out.3 -+ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 -+ $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 - $(RM) $(DESTDIR)$(includedir)/mpath_persist.h - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - -diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile -index 2219c86a..d62537b5 100644 ---- a/mpathpersist/Makefile -+++ b/mpathpersist/Makefile -@@ -19,8 +19,8 @@ $(EXEC): $(OBJS) - install: - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - clean: dep_clean - $(RM) core *.o $(EXEC) -@@ -29,7 +29,7 @@ include $(wildcard $(OBJS:.o=.d)) - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - - dep_clean: - $(RM) $(OBJS:.o=.d) -diff --git a/multipath/Makefile b/multipath/Makefile -index 116348e2..1c4e7a52 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -28,10 +28,10 @@ install: - $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf - $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) - $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(man5dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 - ifneq ($(SCSI_DH_MODULES_PRELOAD),) - $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ -@@ -44,8 +44,8 @@ uninstall: - $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -- $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 - - clean: dep_clean - $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf -diff --git a/multipathd/Makefile b/multipathd/Makefile -index c462d7b1..78aefee0 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -89,14 +89,14 @@ ifdef SYSTEMD - $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) - endif -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(man8dir) -- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(man8dir) -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) -- $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8 -- $(RM) $(DESTDIR)$(man8dir)/$(CLI).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 - $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service - $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket - diff --git a/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch b/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch new file mode 100644 index 0000000..fe7f001 --- /dev/null +++ b/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 30 Nov 2022 21:07:45 +0100 +Subject: [PATCH] libmultipath: pathinfo: don't fail for devices lacking + INQUIRY properties +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some SAS devices (e.g. Seagate factory recertified 'white label' drives) may +come with the Vendor field blank. This causes Multipath to fail to +complete the discovery of those devices. + +Such devices violate the SCSI Spec. From the SPC-6, §6.7.2: +"The T10 VENDOR IDENTIFICATION field contains eight bytes of left-aligned +ASCII data (see 4.3.1) identifying the manufacturer of the logical unit. The +T10 vendor identification shall be one assigned by INCITS.". + +But as we don't identify WWIDs by vendor and product, we don't need to discard +these devices right away. We can go ahead fingers crossed, and hope that the +the other VPD pages for the device are correct. + +We obviously can't look up reasonable device properties for such devices in +our hwtable. It would be up to the user to deal with that. + +Reported by: Allyn Malventano (github.com/opensvc/multipath-tools/issues/56) +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index d9ee2cb9..67ac0e6d 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1472,6 +1472,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + { + struct udev_device *parent; + const char *attr_path = NULL; ++ static const char unknown[] = "UNKNOWN"; + + parent = pp->udev; + while (parent) { +@@ -1492,19 +1493,22 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) + if (!attr_path || pp->sg_id.host_no == -1) + return PATHINFO_FAILED; + +- if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) +- return PATHINFO_FAILED;; +- ++ if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) { ++ condlog(1, "%s: broken device without vendor ID", pp->dev); ++ strlcpy(pp->vendor_id, unknown, SCSI_VENDOR_SIZE); ++ } + condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id); + +- if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) +- return PATHINFO_FAILED;; +- ++ if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) { ++ condlog(1, "%s: broken device without product ID", pp->dev); ++ strlcpy(pp->product_id, unknown, PATH_PRODUCT_SIZE); ++ } + condlog(3, "%s: product = %s", pp->dev, pp->product_id); + +- if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) +- return PATHINFO_FAILED;; +- ++ if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) { ++ condlog(2, "%s: broken device without revision", pp->dev); ++ strlcpy(pp->rev, unknown, PATH_REV_SIZE); ++ } + condlog(3, "%s: rev = %s", pp->dev, pp->rev); + + /* diff --git a/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch b/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch deleted file mode 100644 index 9b0dbc5..0000000 --- a/0009-multipath-tools-Makefile.inc-simplify-expression-for.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:34:34 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: simplify expression for - SYSTEMD - -Use a shell "or" function here. Note the use of "strip" to remove -the whitespace that are caused by the line break. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 10 ++-------- - 1 file changed, 2 insertions(+), 8 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index f3c84771..1a08b8fa 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -28,14 +28,8 @@ ifeq ($(TOPDIR),) - TOPDIR = .. - endif - --ifeq ($(shell $(PKGCONFIG) --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell $(PKGCONFIG) --modversion libsystemd | awk '{print $$1}') --else -- ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell systemctl --version 2> /dev/null | \ -- sed -n 's/systemd \([0-9]*\).*/\1/p') -- endif --endif -+SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ -+ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) - - # Allow user to override default location. - diff --git a/0010-libmultipath-bump-ABI-version-to-18.0.0.patch b/0010-libmultipath-bump-ABI-version-to-18.0.0.patch new file mode 100644 index 0000000..0d9a3c1 --- /dev/null +++ b/0010-libmultipath-bump-ABI-version-to-18.0.0.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 25 Jan 2023 11:35:38 +0100 +Subject: [PATCH] libmultipath: bump ABI version to 18.0.0 + +Commit 6b81153 ("libmultipath: make prflag an enum") changed +the size and member offsets of struct multipath. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index faef2a2d..015623cc 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { + put_multipath_config; + }; + +-LIBMULTIPATH_17.0.0 { ++LIBMULTIPATH_18.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; diff --git a/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch b/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch deleted file mode 100644 index 8591ac4..0000000 --- a/0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:53:04 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: untangle paths and source - directories - -Only the installation paths can be customized. Move the definitions -of $(multipathdir) etc. further down. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 23 ++++++++++++----------- - 1 file changed, 12 insertions(+), 11 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 1a08b8fa..6ec8201b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -31,8 +31,6 @@ endif - SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ - $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) - --# Allow user to override default location. -- - # Paths. All these can be overridden on the "make" command line. - prefix = - # Prefix for binaries -@@ -49,20 +47,11 @@ modulesloaddir := $(systemd_prefix)/lib/modules-load.d - libudevdir := $(systemd_prefix)/lib/udev - udevrulesdir := $(libudevdir)/rules.d - bindir = $(exec_prefix)/sbin --multipathdir = $(TOPDIR)/libmultipath --daemondir = $(TOPDIR)/multipathd --mpathutildir = $(TOPDIR)/libmpathutil - mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) - libdir = $(prefix)/$(LIB)/multipath --mpathpersistdir = $(TOPDIR)/libmpathpersist --mpathcmddir = $(TOPDIR)/libmpathcmd --mpathvaliddir = $(TOPDIR)/libmpathvalid --thirdpartydir = $(TOPDIR)/third-party --libdmmpdir = $(TOPDIR)/libdmmp --nvmedir = $(TOPDIR)/libmultipath/nvme - includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath -@@ -124,6 +113,18 @@ SHARED_FLAGS = -shared - LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs - BIN_LDFLAGS = -pie - -+# Source code directories. Don't modify. -+ -+multipathdir = $(TOPDIR)/libmultipath -+daemondir = $(TOPDIR)/multipathd -+mpathutildir = $(TOPDIR)/libmpathutil -+mpathpersistdir = $(TOPDIR)/libmpathpersist -+mpathcmddir = $(TOPDIR)/libmpathcmd -+mpathvaliddir = $(TOPDIR)/libmpathvalid -+thirdpartydir = $(TOPDIR)/third-party -+libdmmpdir = $(TOPDIR)/libdmmp -+nvmedir = $(TOPDIR)/libmultipath/nvme -+ - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ - if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ diff --git a/0033-RH-fixup-udev-rules-for-redhat.patch b/0011-RH-fixup-udev-rules-for-redhat.patch similarity index 98% rename from 0033-RH-fixup-udev-rules-for-redhat.patch rename to 0011-RH-fixup-udev-rules-for-redhat.patch index f0fc0d2..618603c 100644 --- a/0033-RH-fixup-udev-rules-for-redhat.patch +++ b/0011-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 866ab274..8c5a08a2 100644 +index 2e25d2ea..540e1dfc 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,9 +34,9 @@ endif diff --git a/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch b/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch deleted file mode 100644 index 82c63d1..0000000 --- a/0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:17:00 +0200 -Subject: [PATCH] multipath-tools: Makefiles: replace $(libdir) by $(plugindir) - -The make variables $(libdir) and $(plugindir) are redundant. -I overlooked that in af15832 ("multipath-tools: make multipath_dir a -compiled-in option"). While libdir has existed longer, I think -plugindir describes better what this path is used for, so replace -libdir by plugindir. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 1 - - libmpathutil/Makefile | 1 - - libmultipath/Makefile | 2 +- - libmultipath/checkers/Makefile | 4 ++-- - libmultipath/foreign/Makefile | 4 ++-- - libmultipath/prioritizers/Makefile | 4 ++-- - 6 files changed, 7 insertions(+), 9 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 6ec8201b..17707a3e 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -51,7 +51,6 @@ mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) - syslibdir = $(prefix)/$(LIB) - usrlibdir = $(usr_prefix)/$(LIB) --libdir = $(prefix)/$(LIB)/multipath - includedir = $(usr_prefix)/include - pkgconfdir = $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 68b1c7d6..c913c761 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -54,7 +54,6 @@ abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index f0df27c0..c7d4fc99 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -119,7 +119,7 @@ test-lib: ../tests/$(LIBS) - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) - $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) - $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index c9a2c4ca..39ad76e0 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -25,10 +25,10 @@ libcheck%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done -+ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile -index d0232f20..8bf9047b 100644 ---- a/libmultipath/foreign/Makefile -+++ b/libmultipath/foreign/Makefile -@@ -17,10 +17,10 @@ libforeign-%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done -+ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 97155f51..72eefe49 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -37,10 +37,10 @@ libprio%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: $(LIBS) -- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir) -+ $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(libdir)/$$file; done -+ for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(RM) core *.a *.o *.gz *.so diff --git a/0034-RH-Remove-the-property-blacklist-exception-builtin.patch b/0012-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0034-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0012-RH-Remove-the-property-blacklist-exception-builtin.patch index feef3f6..cbd2480 100644 --- a/0034-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0012-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -43,10 +43,10 @@ index 8d15d2ea..eff690fd 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 1fea9d5a..eef3c605 100644 +index b4dccd1b..284282c6 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1353,9 +1353,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1367,9 +1367,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -62,7 +62,7 @@ index 1fea9d5a..eef3c605 100644 . .RS .PP -@@ -1366,10 +1371,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1380,10 +1385,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch b/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch deleted file mode 100644 index 16cca1e..0000000 --- a/0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:35:48 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: use simple make variables - consistently - -"Simply expanded" make variables are generally preferred over "recursively -expanded" make variables, unless they reference other variables that are -defined over overwritten further down in the Makefile (see -https://www.gnu.org/software/make/manual/html_node/Flavors.html). -Using them makes the code easier to read and even somewhat faster. - -We've been adding simply expanded variables over time, but most older -code still uses recursively expanded ones. Try to be consistent, at least -in Makefile.inc. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 50 +++++++++++++++++++++++++------------------------- - 1 file changed, 25 insertions(+), 25 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 17707a3e..86602e2a 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -32,11 +32,11 @@ SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null - $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) - - # Paths. All these can be overridden on the "make" command line. --prefix = -+prefix := - # Prefix for binaries --exec_prefix = $(prefix) -+exec_prefix := $(prefix) - # Prefix for non-essential libraries (libdmmp) --usr_prefix = $(prefix) -+usr_prefix := $(prefix) - # Where to install systemd-related files. systemd is usually installed under /usr - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) -@@ -46,13 +46,13 @@ tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d - modulesloaddir := $(systemd_prefix)/lib/modules-load.d - libudevdir := $(systemd_prefix)/lib/udev - udevrulesdir := $(libudevdir)/rules.d --bindir = $(exec_prefix)/sbin -+bindir := $(exec_prefix)/sbin - mandir := $(usr_prefix)/share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) --syslibdir = $(prefix)/$(LIB) --usrlibdir = $(usr_prefix)/$(LIB) --includedir = $(usr_prefix)/include --pkgconfdir = $(usrlibdir)/pkgconfig -+syslibdir := $(prefix)/$(LIB) -+usrlibdir := $(usr_prefix)/$(LIB) -+includedir := $(usr_prefix)/include -+pkgconfdir := $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(prefix)/etc/multipath/conf.d - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) -@@ -60,10 +60,10 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ - libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) - kernel_incdir := /usr/include - --GZIP_PROG = gzip -9 -c --RM = rm -f --LN = ln -sf --INSTALL_PROGRAM = install -+GZIP_PROG := gzip -9 -c -+RM := rm -f -+LN := ln -sf -+INSTALL_PROGRAM := install - NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) - - # $(call TEST_CC_OPTION,option,fallback) -@@ -106,23 +106,23 @@ CPPFLAGS := $(FORTIFY_OPT) \ - -DRUNTIME_DIR=\"$(runtimedir)\" \ - -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe --BIN_CFLAGS = -fPIE -DPIE --LIB_CFLAGS = -fPIC --SHARED_FLAGS = -shared -+BIN_CFLAGS := -fPIE -DPIE -+LIB_CFLAGS := -fPIC -+SHARED_FLAGS := -shared - LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs --BIN_LDFLAGS = -pie -+BIN_LDFLAGS := -pie - - # Source code directories. Don't modify. - --multipathdir = $(TOPDIR)/libmultipath --daemondir = $(TOPDIR)/multipathd --mpathutildir = $(TOPDIR)/libmpathutil --mpathpersistdir = $(TOPDIR)/libmpathpersist --mpathcmddir = $(TOPDIR)/libmpathcmd --mpathvaliddir = $(TOPDIR)/libmpathvalid --thirdpartydir = $(TOPDIR)/third-party --libdmmpdir = $(TOPDIR)/libdmmp --nvmedir = $(TOPDIR)/libmultipath/nvme -+multipathdir := $(TOPDIR)/libmultipath -+daemondir := $(TOPDIR)/multipathd -+mpathutildir := $(TOPDIR)/libmpathutil -+mpathpersistdir := $(TOPDIR)/libmpathpersist -+mpathcmddir := $(TOPDIR)/libmpathcmd -+mpathvaliddir := $(TOPDIR)/libmpathvalid -+thirdpartydir := $(TOPDIR)/third-party -+libdmmpdir := $(TOPDIR)/libdmmp -+nvmedir := $(TOPDIR)/libmultipath/nvme - - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ diff --git a/0035-RH-don-t-start-without-a-config-file.patch b/0013-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0035-RH-don-t-start-without-a-config-file.patch rename to 0013-RH-don-t-start-without-a-config-file.patch diff --git a/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch b/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch deleted file mode 100644 index 3e424dc..0000000 --- a/0013-multipath-tools-Makefile.inc-fix-a-log-message.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 17:40:30 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: fix a log message - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 86602e2a..77790ddf 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -159,7 +159,7 @@ check_var = $(shell \ - found=0; \ - status="no"; \ - fi; \ -- echo 1>&2 "Checking for .. $1 in $2 ... $$status"; \ -+ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ - echo "$$found" \ - ) - diff --git a/0036-RH-Fix-nvme-function-missing-argument.patch b/0014-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0036-RH-Fix-nvme-function-missing-argument.patch rename to 0014-RH-Fix-nvme-function-missing-argument.patch diff --git a/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch b/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch deleted file mode 100644 index fa37b7c..0000000 --- a/0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 16:40:27 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: set systemd-specific flags - -Define SYSTEMD_CPPFLAGS and SYSTEMD_LIBDEPS, and use them in Makefiles. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 3 +++ - libmpathutil/Makefile | 13 ++----------- - libmultipath/Makefile | 14 +++----------- - multipathd/Makefile | 25 ++++++++----------------- - 4 files changed, 16 insertions(+), 39 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 77790ddf..2cf25745 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -97,6 +97,9 @@ ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) - -+SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) -+SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) -+ - OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 - WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index c913c761..4be75d2d 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -8,19 +8,10 @@ DEVLIB = libmpathutil.so - LIBS = $(DEVLIB).$(SONAME) - VERSION_SCRIPT := libmpathutil.version - --CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) -+CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE - --LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd -- --ifdef SYSTEMD -- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) -- LIBDEPS += -lsystemd -- else -- LIBDEPS += -lsystemd-daemon -- endif --endif -+LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) - - # object files referencing MULTIPATH_DIR or CONFIG_DIR - # they need to be recompiled for unit tests -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index c7d4fc99..009f26a3 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -8,19 +8,11 @@ DEVLIB = libmultipath.so - LIBS = $(DEVLIB).$(SONAME) - VERSION_SCRIPT := libmultipath.version - --CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE -+CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) - --LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lurcu -laio -- --ifdef SYSTEMD -- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) -- LIBDEPS += -lsystemd -- else -- LIBDEPS += -lsystemd-daemon -- endif --endif -+LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ -+ -lurcu -laio $(SYSTEMD_LIBDEPS) - - ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_FLUSH -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 78aefee0..cdda371b 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -18,14 +18,17 @@ endif - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ - $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ - awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ -- -DBINDIR='"$(bindir)"' -+ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) -+ifeq ($(ENABLE_DMEVENTS_POLL),0) -+ CPPFLAGS += -DNO_DMEVENTS_POLL -+endif - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - --CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread --LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ -- -ldevmapper $(CLI_LIBDEPS) -- -+CLI_LIBDEPS := -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ -+ -ludev -ldl -lurcu -lpthread $(SYSTEMD_LIBDEPS) -+LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ -+ -ldevmapper $(CLI_LIBDEPS) - - ifeq ($(READLINE),libedit) - RL_CPPFLAGS = -DUSE_LIBEDIT -@@ -40,18 +43,6 @@ RL_CPPFLAGS += -DBROKEN_RL_COMPLETION_FUNC - endif - endif - --ifdef SYSTEMD -- CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -- ifeq ($(shell test $(SYSTEMD) -gt 209 && echo 1), 1) -- CLI_LIBDEPS += -lsystemd -- else -- CLI_LIBDEPS += -lsystemd-daemon -- endif --endif --ifeq ($(ENABLE_DMEVENTS_POLL),0) -- CPPFLAGS += -DNO_DMEVENTS_POLL --endif -- - OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ - dmevents.o init_unwinder.o - diff --git a/0037-RH-use-rpm-optflags-if-present.patch b/0015-RH-use-rpm-optflags-if-present.patch similarity index 78% rename from 0037-RH-use-rpm-optflags-if-present.patch rename to 0015-RH-use-rpm-optflags-if-present.patch index c844afe..6a7fdea 100644 --- a/0037-RH-use-rpm-optflags-if-present.patch +++ b/0015-RH-use-rpm-optflags-if-present.patch @@ -9,14 +9,14 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) + Makefile.inc | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 8c5a08a2..e6e7f7d7 100644 +index 540e1dfc..748911e2 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -74,19 +74,31 @@ INSTALL_PROGRAM := install +@@ -78,11 +78,23 @@ ORIG_LDFLAGS := $(LDFLAGS) SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) @@ -37,15 +37,14 @@ index 8c5a08a2..e6e7f7d7 100644 +endif +WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) --CPPFLAGS := $(FORTIFY_OPT) \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -+ $(WNOCLOBBERED) -Werror=cast-qual \ -+ $(ERROR_DISCARDED_QUALIFIERS) -Wstrict-prototypes -+CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ +- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes ++CPPFLAGS := $(CPPFLAGS) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" \ -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +@@ -90,7 +102,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch b/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch deleted file mode 100644 index 0013036..0000000 --- a/0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 18:51:52 +0200 -Subject: [PATCH] multipathd: Makefile: fix compilation flags for libedit - -The workaround for the wrong prototype in older libedit versions -had ended up in the code for libreadline. Fix it, and use simple -make variables. - -Fixes: 2bd80f6 ("multipathd: fix incompatible pointer type error with libedit") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/Makefile | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - -diff --git a/multipathd/Makefile b/multipathd/Makefile -index cdda371b..7221b6af 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -31,17 +31,17 @@ LIBDEPS := -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -ldevmapper $(CLI_LIBDEPS) - - ifeq ($(READLINE),libedit) --RL_CPPFLAGS = -DUSE_LIBEDIT --RL_LIBDEPS += -ledit --endif --ifeq ($(READLINE),libreadline) --RL_CPPFLAGS += -DUSE_LIBREADLINE --RL_LIBDEPS += -lreadline --# See comment in uxclnt.c -+RL_CPPFLAGS := -DUSE_LIBEDIT -+RL_LIBDEPS := -ledit -+# See comment in multipathc.c - ifeq ($(shell sed -En 's/.*\ -Date: Thu, 27 Oct 2022 21:59:36 +0200 -Subject: [PATCH] multipath-tools Makefiles: clean up executable Makefiles - -Move the EXEC definition to the top, and use simple make variables -where possible. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - kpartx/Makefile | 15 +++++++-------- - multipath/Makefile | 6 +++--- - multipathd/Makefile | 30 ++++++++++++++---------------- - 3 files changed, 24 insertions(+), 27 deletions(-) - -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 464925ad..7ceae96b 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -3,20 +3,19 @@ - # - include ../Makefile.inc - --CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 --CFLAGS += $(BIN_CFLAGS) --LDFLAGS += $(BIN_LDFLAGS) -- --LIBDEPS += -ldevmapper -+EXEC := kpartx - -+CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 - ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_COOKIE - endif - --OBJS = bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ -- gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o -+CFLAGS += $(BIN_CFLAGS) -+LDFLAGS += $(BIN_LDFLAGS) -+LIBDEPS += -ldevmapper - --EXEC = kpartx -+OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ -+ gpt.o mac.o ps3.o crc32.o lopart.o xstrncpy.o devmapper.o - - all: $(EXEC) - -diff --git a/multipath/Makefile b/multipath/Makefile -index 1c4e7a52..7f7b341d 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -3,15 +3,15 @@ - # - include ../Makefile.inc - -+EXEC := multipath -+ - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ - -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ldl -ludev - --EXEC = multipath -- --OBJS = main.o -+OBJS := main.o - - all: $(EXEC) multipath.rules tmpfiles.conf - -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 7221b6af..bb8f7770 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -1,27 +1,30 @@ - include ../Makefile.inc - -+EXEC := multipathd -+CLI := multipathc -+ -+CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ -+ $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ -+ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ -+ -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) -+ -+ifeq ($(ENABLE_DMEVENTS_POLL),0) -+ CPPFLAGS += -DNO_DMEVENTS_POLL -+endif - ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) - CPPFLAGS += -DLIBDM_API_GET_ERRNO - endif -- - ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) - CPPFLAGS += -DFPIN_EVENT_HANDLER - FPIN_SUPPORT = 1 - endif -+ - # - # debugging stuff - # - #CPPFLAGS += -DLCKDBG --#CPPFLAGS += -D_DEBUG_ - #CPPFLAGS += -DLOGDBG - --CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ -- $(shell $(PKGCONFIG) --modversion liburcu 2>/dev/null | \ -- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ -- -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) --ifeq ($(ENABLE_DMEVENTS_POLL),0) -- CPPFLAGS += -DNO_DMEVENTS_POLL --endif - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - -@@ -43,18 +46,13 @@ RL_CPPFLAGS := -DUSE_LIBREADLINE - RL_LIBDEPS := -lreadline - endif - --OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ -+CLI_OBJS := multipathc.o cli.o -+OBJS := main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ - dmevents.o init_unwinder.o -- --CLI_OBJS = multipathc.o cli.o -- - ifeq ($(FPIN_SUPPORT),1) - OBJS += fpin_handlers.o - endif - --EXEC = multipathd --CLI = multipathc -- - all : $(EXEC) $(CLI) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so diff --git a/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch b/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch deleted file mode 100644 index 0b45e62..0000000 --- a/0017-multipath-tools-Makefiles-use-common-code-for-librar.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 21:52:06 +0200 -Subject: [PATCH] multipath-tools: Makefiles: use common code for libraries - -Move shared code to Makefile.inc as far as possible. Use simple -make variables where possible. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 15 ++++++++++++++- - libdmmp/Makefile | 17 ++++++++--------- - libmpathcmd/Makefile | 14 ++------------ - libmpathpersist/Makefile | 14 ++------------ - libmpathutil/Makefile | 14 +------------- - libmpathvalid/Makefile | 14 ++------------ - libmultipath/Makefile | 12 +----------- - 7 files changed, 30 insertions(+), 70 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 2cf25745..fe6bc088 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -64,7 +64,6 @@ GZIP_PROG := gzip -9 -c - RM := rm -f - LN := ln -sf - INSTALL_PROGRAM := install --NV_VERSION_SCRIPT = $(VERSION_SCRIPT:%.version=%-nv.version) - - # $(call TEST_CC_OPTION,option,fallback) - # Test if the C compiler supports the option. -@@ -127,6 +126,13 @@ thirdpartydir := $(TOPDIR)/third-party - libdmmpdir := $(TOPDIR)/libdmmp - nvmedir := $(TOPDIR)/libmultipath/nvme - -+# Common code for libraries - library Makefiles just set DEVLIB -+# SONAME defaults to 0 (we use version scripts) -+SONAME := 0 -+LIBS = $(DEVLIB).$(SONAME) -+VERSION_SCRIPT = $(DEVLIB:%.so=%.version) -+NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) -+ - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ - if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ -@@ -175,3 +181,10 @@ check_var = $(shell \ - - %.abi: %.so - abidw $< >$@ -+ -+%-nv.version: %.version -+ @echo creating $@ from $< -+ @printf 'NOVERSION {\nglobal:\n' >$@ -+ @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -+ @printf 'local:\n\t*;\n};\n' >>$@ -+ -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index 985b694b..67b6f86f 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -5,15 +5,14 @@ - # - include ../Makefile.inc - --LIBDMMP_VERSION=0.2.0 --SONAME=$(LIBDMMP_VERSION) --DEVLIB = libdmmp.so --LIBS = $(DEVLIB).$(SONAME) --PKGFILE = libdmmp.pc --EXTRA_MAN_FILES = libdmmp.h.3 --HEADERS = libdmmp/libdmmp.h -- --OBJS = libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o -+LIBDMMP_VERSION := 0.2.0 -+SONAME := $(LIBDMMP_VERSION) -+DEVLIB := libdmmp.so -+PKGFILE := libdmmp.pc -+EXTRA_MAN_FILES := libdmmp.h.3 -+HEADERS := libdmmp/libdmmp.h -+ -+OBJS := libdmmp.o libdmmp_mp.o libdmmp_pg.o libdmmp_path.o libdmmp_misc.o - - CPPFLAGS += -I$(libdmmpdir) -I$(mpathcmddir) $(shell $(PKGCONFIG) --cflags json-c) - CFLAGS += $(LIB_CFLAGS) -fvisibility=hidden -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index 0f83fe7b..f705c7f0 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -1,13 +1,8 @@ - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathcmd.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmpathcmd.version -- -+DEVLIB := libmpathcmd.so - CFLAGS += $(LIB_CFLAGS) -- --OBJS = mpath_cmd.o -+OBJS := mpath_cmd.o - - all: $(DEVLIB) - -@@ -15,11 +10,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 479524d4..6f69168f 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -1,16 +1,11 @@ - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathpersist.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT:= libmpathpersist.version -- -+DEVLIB := libmpathpersist.so - CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) - LDFLAGS += -L$(multipathdir) -L$(mpathutildir) -L$(mpathcmddir) -- - LIBDEPS += -lmultipath -lmpathutil -lmpathcmd -ldevmapper -lpthread -ldl - --OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o -+OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o - - all: $(DEVLIB) - -@@ -18,11 +13,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 4be75d2d..5665af28 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -3,14 +3,9 @@ - # - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathutil.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmpathutil.version -- -+DEVLIB := libmpathutil.so - CPPFLAGS += -I. -I$(multipathdir) -I$(mpathcmddir) $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) -D_GNU_SOURCE -- - LIBDEPS += -lpthread -ldl -ludev -L$(mpathcmddir) -lmpathcmd $(SYSTEMD_LIBDEPS) - - # object files referencing MULTIPATH_DIR or CONFIG_DIR -@@ -22,8 +17,6 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ - - all: $(DEVLIB) - --make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) -- - $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -@@ -31,11 +24,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -index 5dbfb923..bd4ccc0d 100644 ---- a/libmpathvalid/Makefile -+++ b/libmpathvalid/Makefile -@@ -1,17 +1,12 @@ - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmpathvalid.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmpathvalid.version -- -+DEVLIB := libmpathvalid.so - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) - CFLAGS += $(LIB_CFLAGS) -- - LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ - -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -ludev - --OBJS = mpath_valid.o -+OBJS := mpath_valid.o - - all: $(LIBS) - -@@ -20,11 +15,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - -Wl,--version-script=$(VERSION_SCRIPT) - $(LN) $(LIBS) $(DEVLIB) - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 009f26a3..9dc229ae 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -3,14 +3,9 @@ - # - include ../Makefile.inc - --SONAME = 0 --DEVLIB = libmultipath.so --LIBS = $(DEVLIB).$(SONAME) --VERSION_SCRIPT := libmultipath.version -- -+DEVLIB := libmultipath.so - CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) -- - LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ - -lurcu -laio $(SYSTEMD_LIBDEPS) - -@@ -85,11 +80,6 @@ $(LIBS): $(OBJS) $(VERSION_SCRIPT) - $(DEVLIB): $(LIBS) - $(LN) $(LIBS) $@ - --$(NV_VERSION_SCRIPT): $(VERSION_SCRIPT) -- @printf 'NOVERSION {\nglobal:\n' >$@ -- @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ -- @printf 'local:\n\t*;\n};\n' >>$@ -- - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) diff --git a/0040-RH-reset-default-find_mutipaths-value-to-off.patch b/0018-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0040-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0018-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch b/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch deleted file mode 100644 index 1a2069f..0000000 --- a/0018-multipath-tools-Makefiles-move-common-code-to-rules..patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 27 Oct 2022 22:18:22 +0200 -Subject: [PATCH] multipath-tools: Makefiles: move common code to rules.mk - -The library Makefiles contain a lot of similar rules. Just -maintain them in a single file. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathcmd/Makefile | 13 +------------ - libmpathpersist/Makefile | 13 +------------ - libmpathutil/Makefile | 13 +------------ - libmpathvalid/Makefile | 13 ++----------- - libmultipath/Makefile | 16 ++-------------- - rules.mk | 15 +++++++++++++++ - 6 files changed, 22 insertions(+), 61 deletions(-) - create mode 100644 rules.mk - -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index f705c7f0..cfb202b8 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -6,18 +6,7 @@ OBJS := mpath_cmd.o - - all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+include $(TOPDIR)/rules.mk - - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 6f69168f..94672556 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -9,18 +9,7 @@ OBJS := mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o - - all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+include $(TOPDIR)/rules.mk - - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 5665af28..5ab33c09 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -17,18 +17,7 @@ OBJS := parser.o vector.o util.o debug.o time-util.o \ - - all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -+include $(TOPDIR)/rules.mk - - install: all - $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -index bd4ccc0d..88034df3 100644 ---- a/libmpathvalid/Makefile -+++ b/libmpathvalid/Makefile -@@ -8,18 +8,9 @@ LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \ - - OBJS := mpath_valid.o - --all: $(LIBS) -+all: $(DEVLIB) - --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) \ -- -Wl,--version-script=$(VERSION_SCRIPT) -- $(LN) $(LIBS) $(DEVLIB) -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -+include $(TOPDIR)/rules.mk - - install: $(LIBS) - $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 9dc229ae..e24eab8a 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -56,6 +56,8 @@ OBJS := $(OBJS-O) $(OBJS-U) - - all: $(DEVLIB) - -+include $(TOPDIR)/rules.mk -+ - nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h - $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< - -@@ -72,20 +74,6 @@ nvme-ioctl.c: nvme/nvme-ioctl.c - nvme-ioctl.h: nvme/nvme-ioctl.h - $(call make_static,$<,$@) - -- --$(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --$(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -- --$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -- -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -- --abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -- - ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ - -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) -diff --git a/rules.mk b/rules.mk -new file mode 100644 -index 00000000..c1d80820 ---- /dev/null -+++ b/rules.mk -@@ -0,0 +1,15 @@ -+# Copyright (c) SUSE LLC -+# SPDX-License-Identifier: GPL-2.0-or-later -+ -+$(DEVLIB): $(LIBS) -+ $(LN) $(LIBS) $@ -+ -+$(LIBS): $(OBJS) $(VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -+ -+$(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) -+ -+abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) diff --git a/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0019-multipath-tools-Makefiles-create-config.mk.patch b/0019-multipath-tools-Makefiles-create-config.mk.patch deleted file mode 100644 index 4d403d0..0000000 --- a/0019-multipath-tools-Makefiles-create-config.mk.patch +++ /dev/null @@ -1,603 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 00:01:46 +0200 -Subject: [PATCH] multipath-tools Makefiles: create config.mk - -Rather than running the test scripts for certain system features -every time "make" is called, save the configuration in "config.mk" -and "libmultipath/autoconfig.h", and reuse it later. This reduces -build time, especially in subsequent builds, and the build output is -less garbled by compiler options. - -It works by invoking the separate make file "create-config.mk" at -the beginning of the build process. Most of the complex makefile -functions are moved to "create-config.mk". - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/foreign.yaml | 2 +- - .gitignore | 2 + - Makefile | 19 +++- - Makefile.inc | 76 +-------------- - create-config.mk | 144 +++++++++++++++++++++++++++++ - kpartx/Makefile | 4 - - kpartx/devmapper.c | 1 + - kpartx/kpartx.c | 1 + - libdmmp/test/Makefile | 1 + - libmultipath/Makefile | 30 +----- - libmultipath/devmapper.h | 2 +- - libmultipath/dict.c | 1 + - libmultipath/prioritizers/Makefile | 2 +- - libmultipath/propsel.c | 1 + - libmultipath/uevent.c | 1 + - multipathd/Makefile | 11 --- - multipathd/fpin.h | 1 + - multipathd/main.c | 1 + - rules.mk | 3 + - tests/Makefile | 8 -- - 20 files changed, 179 insertions(+), 132 deletions(-) - create mode 100644 create-config.mk - -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index bd4e9c12..5a19913a 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -30,7 +30,7 @@ jobs: - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} - run: > - tar cfv binaries.tar -- Makefile* -+ Makefile* config.mk - libmpathcmd/*.so* libmultipath/*.so* libmpathutil/*.so* - libmultipath/checkers/*.so libmultipath/prioritizers/*.so - libmultipath/foreign/*.so -diff --git a/.gitignore b/.gitignore -index 83f8a552..535353e5 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -8,6 +8,7 @@ - *.gz - *.d - \#* -+config.mk - cscope.files - cscope.out - kpartx/kpartx -@@ -35,5 +36,6 @@ tests/*.out - tests/*.vgr - libmultipath/nvme-ioctl.c - libmultipath/nvme-ioctl.h -+libmultipath/autoconfig.h - */*-nv.version - reference-abi -diff --git a/Makefile b/Makefile -index 27b4641f..1b28db62 100644 ---- a/Makefile -+++ b/Makefile -@@ -30,7 +30,14 @@ BUILDDIRS.clean := $(BUILDDIRS:=.clean) tests.clean - - all: $(BUILDDIRS) - --$(BUILDDIRS): -+config.mk libmultipath/autoconfig.h: -+ @$(MAKE) -f create-config.mk -+ @echo ==== config.mk ==== -+ @cat config.mk -+ @echo ==== autoconfig.h ==== -+ @cat libmultipath/autoconfig.h -+ -+$(BUILDDIRS): config.mk - $(MAKE) -C $@ - - $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) -@@ -83,7 +90,7 @@ libmultipath/checkers.install \ - libmultipath/prioritizers.install \ - libmultipath/foreign.install: libmultipath.install - --$(BUILDDIRS.clean): -+%.clean: - $(MAKE) -C ${@:.clean=} clean - - %.install: % -@@ -92,8 +99,12 @@ $(BUILDDIRS.clean): - $(BUILDDIRS:=.uninstall): - $(MAKE) -C ${@:.uninstall=} uninstall - --clean: $(BUILDDIRS.clean) -- rm -rf abi abi.tar.gz abi-test compile_commands.json -+# If config.mk is missing, "make clean" in subdir either fails, or tries to -+# build it. Both is undesirable. Avoid it by creating config.mk temporarily. -+clean: -+ @touch config.mk -+ $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true -+ rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk - - install: $(BUILDDIRS:=.install) - uninstall: $(BUILDDIRS:=.uninstall) -diff --git a/Makefile.inc b/Makefile.inc -index fe6bc088..415634f5 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -27,9 +27,9 @@ PKGCONFIG ?= pkg-config - ifeq ($(TOPDIR),) - TOPDIR = .. - endif -- --SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ -- $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) -+ifneq ($(CREATE_CONFIG),1) -+include $(TOPDIR)/config.mk -+endif - - # Paths. All these can be overridden on the "make" command line. - prefix := -@@ -65,37 +65,6 @@ RM := rm -f - LN := ln -sf - INSTALL_PROGRAM := install - --# $(call TEST_CC_OPTION,option,fallback) --# Test if the C compiler supports the option. --# Evaluates to "option" if yes, and "fallback" otherwise. --TEST_CC_OPTION = $(shell \ -- if echo 'int main(void){return 0;}' | \ -- $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ -- then \ -- echo "$(1)"; \ -- else \ -- echo "$(2)"; \ -- fi) -- --# "make" on some distros will fail on explicit '#' or '\#' in the program text below --__HASH__ := \# --# Check if _DFORTIFY_SOURCE=3 is supported. --# On some distros (e.g. Debian Buster) it will be falsely reported as supported --# but it doesn't seem to make a difference wrt the compilation result. --FORTIFY_OPT := $(shell \ -- if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ -- $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ -- then \ -- echo "-D_FORTIFY_SOURCE=3"; \ -- else \ -- echo "-D_FORTIFY_SOURCE=2"; \ -- fi) -- --STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) --ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) --WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) --WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) -- - SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) - SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) - -@@ -133,45 +102,6 @@ LIBS = $(DEVLIB).$(SONAME) - VERSION_SCRIPT = $(DEVLIB:%.so=%.version) - NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - --# Check whether a function with name $1 has been declared in header file $2. --check_func = $(shell \ -- if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ -- found=1; \ -- status="yes"; \ -- else \ -- found=0; \ -- status="no"; \ -- fi; \ -- echo 1>&2 "Checking for $1 in $2 ... $$status"; \ -- echo "$$found" \ -- ) -- --# Checker whether a file with name $1 exists --check_file = $(shell \ -- if [ -f "$1" ]; then \ -- found=1; \ -- status="yes"; \ -- else \ -- found=0; \ -- status="no"; \ -- fi; \ -- echo 1>&2 "Checking if $1 exists ... $$status"; \ -- echo "$$found" \ -- ) -- --# Check whether a file contains a variable with name $1 in header file $2 --check_var = $(shell \ -- if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ -- found=1; \ -- status="yes"; \ -- else \ -- found=0; \ -- status="no"; \ -- fi; \ -- echo 1>&2 "Checking for $1 in $2 ... $$status"; \ -- echo "$$found" \ -- ) -- - %.o: %.c - @echo building $@ because of $? - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -diff --git a/create-config.mk b/create-config.mk -new file mode 100644 -index 00000000..2cc5284f ---- /dev/null -+++ b/create-config.mk -@@ -0,0 +1,144 @@ -+# Copyright (c) SUSE LLC -+# SPDX-License-Identifier: GPL-2.0-or-later -+ -+TOPDIR := . -+CREATE_CONFIG := 1 -+include $(TOPDIR)/Makefile.inc -+ -+# Check whether a function with name $1 has been declared in header file $2. -+check_func = $(shell \ -+ if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ -+ found=1; \ -+ status="yes"; \ -+ else \ -+ found=0; \ -+ status="no"; \ -+ fi; \ -+ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ -+ echo "$$found" \ -+ ) -+ -+# Checker whether a file with name $1 exists -+check_file = $(shell \ -+ if [ -f "$1" ]; then \ -+ found=1; \ -+ status="yes"; \ -+ else \ -+ found=0; \ -+ status="no"; \ -+ fi; \ -+ echo 1>&2 "Checking if $1 exists ... $$status"; \ -+ echo "$$found" \ -+ ) -+ -+# Check whether a file contains a variable with name $1 in header file $2 -+check_var = $(shell \ -+ if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ -+ found=1; \ -+ status="yes"; \ -+ else \ -+ found=0; \ -+ status="no"; \ -+ fi; \ -+ echo 1>&2 "Checking for $1 in $2 ... $$status"; \ -+ echo "$$found" \ -+ ) -+ -+# Test special behavior of gcc 4.8 with nested initializers -+# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers -+TEST_MISSING_INITIALIZERS = $(shell \ -+ echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ -+ $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ -+ || echo -Wno-missing-field-initializers) -+ -+DEFINES := -+ -+ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_FLUSH -+endif -+ -+ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_GET_ERRNO -+endif -+ -+ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_COOKIE -+endif -+ -+ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) -+ DEFINES += LIBUDEV_API_RECVBUF -+endif -+ -+ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_DEFERRED -+endif -+ -+ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) -+ DEFINES += LIBDM_API_HOLD_CONTROL -+endif -+ -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) -+ DEFINES += FPIN_EVENT_HANDLER -+ FPIN_SUPPORT = 1 -+endif -+ -+ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) -+ ANA_SUPPORT := 1 -+endif -+ -+ifeq ($(ENABLE_DMEVENTS_POLL),0) -+ DEFINES += -DNO_DMEVENTS_POLL -+endif -+ -+SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \ -+ $(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p'))) -+ -+ -+# $(call TEST_CC_OPTION,option,fallback) -+# Test if the C compiler supports the option. -+# Evaluates to "option" if yes, and "fallback" otherwise. -+TEST_CC_OPTION = $(shell \ -+ if echo 'int main(void){return 0;}' | \ -+ $(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \ -+ then \ -+ echo "$(1)"; \ -+ else \ -+ echo "$(2)"; \ -+ fi) -+ -+# "make" on some distros will fail on explicit '#' or '\#' in the program text below -+__HASH__ := \# -+# Check if _DFORTIFY_SOURCE=3 is supported. -+# On some distros (e.g. Debian Buster) it will be falsely reported as supported -+# but it doesn't seem to make a difference wrt the compilation result. -+FORTIFY_OPT := $(shell \ -+ if /bin/echo -e '$(__HASH__)include \nint main(void) { return 0; }' | \ -+ $(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \ -+ then \ -+ echo "-D_FORTIFY_SOURCE=3"; \ -+ else \ -+ echo "-D_FORTIFY_SOURCE=2"; \ -+ fi) -+ -+STACKPROT := -+ -+all: $(multipathdir)/autoconfig.h $(TOPDIR)/config.mk -+ -+$(multipathdir)/autoconfig.h: -+ @echo creating $@ -+ @echo '#ifndef _AUTOCONFIG_H' >$@ -+ @echo '#define _AUTOCONFIG_H' >>$@ -+ @for x in $(DEFINES); do echo "#define $$x" >>$@; done -+ @echo '#endif' >>$@ -+ -+$(TOPDIR)/config.mk: -+ @echo creating $@ -+ @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ -+ @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ -+ @echo "SYSTEMD := $(SYSTEMD)" >>$@ -+ @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ -+ @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ -+ @echo "ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)" >>$@ -+ @echo "WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)" >>$@ -+ @echo "WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,)" >>$@ -+ @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 7ceae96b..31b1138a 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -6,10 +6,6 @@ include ../Makefile.inc - EXEC := kpartx - - CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 --ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_COOKIE --endif -- - CFLAGS += $(BIN_CFLAGS) - LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -ldevmapper -diff --git a/kpartx/devmapper.c b/kpartx/devmapper.c -index bf14c784..f12762c5 100644 ---- a/kpartx/devmapper.c -+++ b/kpartx/devmapper.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include "autoconfig.h" - #include "devmapper.h" - #include "kpartx.h" - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index 1d568c9e..46cb76ba 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -34,6 +34,7 @@ - #include - #include - -+#include "autoconfig.h" - #include "devmapper.h" - #include "crc32.h" - #include "lopart.h" -diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile -index 76b24d61..93de64a0 100644 ---- a/libdmmp/test/Makefile -+++ b/libdmmp/test/Makefile -@@ -2,6 +2,7 @@ - # - # Copyright (C) 2015-2016 Gris Ge - # -+TOPDIR := ../.. - include ../../Makefile.inc - - _libdmmpdir=../$(libdmmpdir) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index e24eab8a..1cc13577 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -9,34 +9,6 @@ CFLAGS += $(LIB_CFLAGS) - LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ - -lurcu -laio $(SYSTEMD_LIBDEPS) - --ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_FLUSH --endif -- --ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_GET_ERRNO --endif -- --ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_COOKIE --endif -- --ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0) -- CPPFLAGS += -DLIBUDEV_API_RECVBUF --endif -- --ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_DEFERRED --endif -- --ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_HOLD_CONTROL --endif -- --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) -- CPPFLAGS += -DFPIN_EVENT_HANDLER --endif -- - # object files referencing MULTIPATH_DIR or CONFIG_DIR - # they need to be recompiled for unit tests - OBJS-U := prio.o checkers.o foreign.o config.o -@@ -97,7 +69,7 @@ uninstall: - $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) -+ $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 703f3bf8..42f8eccd 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -1,6 +1,6 @@ - #ifndef _DEVMAPPER_H - #define _DEVMAPPER_H -- -+#include "autoconfig.h" - #include "structs.h" - - #define TGT_MPATH "multipath" -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index aa93fe43..6fc77315 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include "autoconfig.h" - #include "mpath_cmd.h" - #include "dict.h" - #include "strbuf.h" -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 72eefe49..a699e8a6 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -26,7 +26,7 @@ LIBS = \ - libpriopath_latency.so \ - libpriosysfs.so - --ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) -+ifneq ($(ANA_SUPPORT),1) - LIBS += libprioana.so - CPPFLAGS += -I../nvme - endif -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d4f19897..d1d5cc25 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -5,6 +5,7 @@ - */ - #include - -+#include "autoconfig.h" - #include "nvme-lib.h" - #include "checkers.h" - #include "vector.h" -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index 57447ca0..bbc8e9e5 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -42,6 +42,7 @@ - #include - #include - -+#include "autoconfig.h" - #include "debug.h" - #include "list.h" - #include "uevent.h" -diff --git a/multipathd/Makefile b/multipathd/Makefile -index bb8f7770..587bb916 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -8,17 +8,6 @@ CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcm - awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ - -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) - --ifeq ($(ENABLE_DMEVENTS_POLL),0) -- CPPFLAGS += -DNO_DMEVENTS_POLL --endif --ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0) -- CPPFLAGS += -DLIBDM_API_GET_ERRNO --endif --ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0) -- CPPFLAGS += -DFPIN_EVENT_HANDLER -- FPIN_SUPPORT = 1 --endif -- - # - # debugging stuff - # -diff --git a/multipathd/fpin.h b/multipathd/fpin.h -index bfcc1ce2..3c374441 100644 ---- a/multipathd/fpin.h -+++ b/multipathd/fpin.h -@@ -1,5 +1,6 @@ - #ifndef __FPIN_H__ - #define __FPIN_H__ -+#include "autoconfig.h" - - #ifdef FPIN_EVENT_HANDLER - void *fpin_fabric_notification_receiver(void *unused); -diff --git a/multipathd/main.c b/multipathd/main.c -index ba52d393..1e1b254f 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -4,6 +4,7 @@ - * Copyright (c) 2005 Benjamin Marzinski, Redhat - * Copyright (c) 2005 Edward Goggin, EMC - */ -+#include "autoconfig.h" - #include - #include - #include -diff --git a/rules.mk b/rules.mk -index c1d80820..d8612527 100644 ---- a/rules.mk -+++ b/rules.mk -@@ -13,3 +13,6 @@ $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) -+ -+$(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: -+ $(MAKE) -C $(TOPDIR) -f create-config.mk -diff --git a/tests/Makefile b/tests/Makefile -index 3a5b161c..d9856d17 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -3,14 +3,6 @@ include ../Makefile.inc - # directory where to run the tests - TESTDIR := $(CURDIR) - --# Test special behavior of gcc 4.8 with nested initializers --# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers --TEST_MISSING_INITIALIZERS = $(shell \ -- echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \ -- $(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \ -- || echo -Wno-missing-field-initializers) --W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) -- - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) -I$(daemondir) \ - -DTESTCONFDIR=\"$(TESTDIR)/conf.d\" - CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) diff --git a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 5812a54..824c747 100644 --- a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f3fccedd..c883fd02 100644 +index 67ac0e6d..7fdbc1c3 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1176,13 +1176,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index f3fccedd..c883fd02 100644 good_len = 8; break; default: -@@ -1200,10 +1196,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1201,10 +1197,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0020-multipath-tools-Makefiles-enable-quiet-build.patch b/0020-multipath-tools-Makefiles-enable-quiet-build.patch deleted file mode 100644 index dbe1129..0000000 --- a/0020-multipath-tools-Makefiles-enable-quiet-build.patch +++ /dev/null @@ -1,879 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 12:39:06 +0200 -Subject: [PATCH] multipath-tools Makefiles: enable quiet build - -Like many other projects, make it possible to print much less -output during build. Verbose output is enabled with "make V=1", as -usual. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile | 12 +++---- - Makefile.inc | 10 +++--- - kpartx/Makefile | 41 ++++++++++++----------- - libdmmp/Makefile | 48 +++++++++++++------------- - libdmmp/test/Makefile | 8 ++--- - libmpathcmd/Makefile | 20 +++++------ - libmpathpersist/Makefile | 32 +++++++++--------- - libmpathutil/Makefile | 14 ++++---- - libmpathvalid/Makefile | 20 +++++------ - libmultipath/Makefile | 30 ++++++++--------- - libmultipath/checkers/Makefile | 8 ++--- - libmultipath/foreign/Makefile | 8 ++--- - libmultipath/prioritizers/Makefile | 8 ++--- - mpathpersist/Makefile | 18 +++++----- - multipath/Makefile | 54 ++++++++++++++++-------------- - multipathd/Makefile | 42 ++++++++++++----------- - rules.mk | 8 ++--- - tests/Makefile | 23 +++++++------ - 18 files changed, 206 insertions(+), 198 deletions(-) - -diff --git a/Makefile b/Makefile -index 1b28db62..e3ce1a8d 100644 ---- a/Makefile -+++ b/Makefile -@@ -38,17 +38,17 @@ config.mk libmultipath/autoconfig.h: - @cat libmultipath/autoconfig.h - - $(BUILDDIRS): config.mk -- $(MAKE) -C $@ -+ @$(MAKE) -C $@ - - $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) -- $(MAKE) -C ${@:.abi=} abi -+ @$(MAKE) -C ${@:.abi=} abi - - # Create formal representation of the ABI - # Useful for verifying ABI compatibility - # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) - .PHONY: abi - abi: $(LIB_BUILDDIRS:=.abi) -- mkdir -p $@ -+ @mkdir -p $@ - ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) - - abi.tar.gz: abi -@@ -91,13 +91,13 @@ libmultipath/checkers.install \ - libmultipath/foreign.install: libmultipath.install - - %.clean: -- $(MAKE) -C ${@:.clean=} clean -+ @$(MAKE) -C ${@:.clean=} clean - - %.install: % -- $(MAKE) -C ${@:.install=} install -+ @$(MAKE) -C ${@:.install=} install - - $(BUILDDIRS:=.uninstall): -- $(MAKE) -C ${@:.uninstall=} uninstall -+ @$(MAKE) -C ${@:.uninstall=} uninstall - - # If config.mk is missing, "make clean" in subdir either fails, or tries to - # build it. Both is undesirable. Avoid it by creating config.mk temporarily. -diff --git a/Makefile.inc b/Makefile.inc -index 415634f5..3e14cb8c 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -1,4 +1,4 @@ --# -+# -*- Makefile -*- - # Copyright (C) 2004 Christophe Varoqui, - # - -@@ -60,6 +60,8 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ - libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) - kernel_incdir := /usr/include - -+Q := $(if $(V),,@) -+ - GZIP_PROG := gzip -9 -c - RM := rm -f - LN := ln -sf -@@ -104,13 +106,13 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - - %.o: %.c - @echo building $@ because of $? -- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< - - %.abi: %.so.0 -- abidw $< >$@ -+ $(Q)abidw $< >$@ - - %.abi: %.so -- abidw $< >$@ -+ $(Q)abidw $< >$@ - - %-nv.version: %.version - @echo creating $@ from $< -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 31b1138a..7720a740 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -16,33 +16,34 @@ OBJS := bsd.o dos.o kpartx.o solaris.o unixware.o dasd.o sun.o \ - all: $(EXEC) - - $(EXEC): $(OBJS) -- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) - - install: $(EXEC) $(EXEC).8 -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) -- $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d -- $(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -- $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -- $(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d -+ $(Q)$(INSTALL_PROGRAM) -m 644 dm-parts.rules $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -+ $(Q)$(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -+ $(Q)$(INSTALL_PROGRAM) -m 644 del-part-nodes.rules $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -- $(RM) $(DESTDIR)$(libudevdir)/kpartx_id -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/kpartx_id -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/11-dm-parts.rules -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/68-del-part-nodes.rules - - clean: dep_clean -- $(RM) core *.o $(EXEC) -+ $(Q)$(RM) core *.o $(EXEC) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index 67b6f86f..7693facb 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -23,62 +23,62 @@ all: $(LIBS) doc - .PHONY: doc clean install uninstall check speed_test dep_clean - - $(LIBS): $(OBJS) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) - - $(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+ $(Q)$(LN) $(LIBS) $@ - - abi: $(DEVLIB:%.so=%.abi) - - install: -- mkdir -p $(DESTDIR)$(usrlibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 644 -D \ -+ @mkdir -p $(DESTDIR)$(usrlibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(usrlibdir)/$(LIBS) -+ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ - $(HEADERS) $(DESTDIR)$(includedir)/$(HEADERS) -- $(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 644 -D \ -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -m 644 -D \ - $(PKGFILE).in $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ -+ $(Q)perl -i -pe 's|__VERSION__|$(LIBDMMP_VERSION)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ -+ $(Q)perl -i -pe 's|__LIBDIR__|$(usrlibdir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ -+ $(Q)perl -i -pe 's|__INCLUDEDIR__|$(includedir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- $(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 -+ $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 - - uninstall: -- $(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(includedir)/$(HEADERS) -- $(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(includedir)/$(HEADERS) -+ $(Q)$(RM) $(DESTDIR)$(usrlibdir)/$(DEVLIB) - @for file in $(DESTDIR)$(mandir)/man3/dmmp_*; do \ - $(RM) $$file; \ - done -- $(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* -- $(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/libdmmp.h* -+ $(Q)$(RM) $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -- $(MAKE) -C test clean -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ @$(MAKE) -C test clean - - include $(wildcard $(OBJS:.o=.d)) - - check: all -- $(MAKE) -C test check -+ @$(MAKE) -C test check - - speed_test: all -- $(MAKE) -C test speed_test -+ @$(MAKE) -C test speed_test - - doc: docs/man/dmmp_strerror.3 - - docs/man/dmmp_strerror.3: $(HEADERS) -- TEMPFILE=$(shell mktemp); \ -+ $(Q)TEMPFILE=$(shell mktemp); \ - cat $^ | perl docs/doc-preclean.pl >$$TEMPFILE; \ - LC_ALL=C \ - KBUILD_BUILD_TIMESTAMP=`git log -n1 --pretty=%cd --date=iso -- $^` \ - perl docs/kernel-doc -man $$TEMPFILE | \ - perl docs/split-man.pl docs/man; \ -- rm -f $$TEMPFILE -+ $(RM) -f $$TEMPFILE - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libdmmp/test/Makefile b/libdmmp/test/Makefile -index 93de64a0..9d0817c8 100644 ---- a/libdmmp/test/Makefile -+++ b/libdmmp/test/Makefile -@@ -16,7 +16,7 @@ LDFLAGS += -L$(_libdmmpdir) -ldmmp - all: $(TEST_EXEC) $(SPD_TEST_EXEC) - - check: $(TEST_EXEC) $(SPD_TEST_EXEC) -- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ -+ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ - valgrind --quiet --leak-check=full \ - --show-reachable=no --show-possibly-lost=no \ - --trace-children=yes --error-exitcode=1 \ -@@ -24,15 +24,15 @@ check: $(TEST_EXEC) $(SPD_TEST_EXEC) - $(MAKE) speed_test - - speed_test: $(SPD_TEST_EXEC) -- sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ -+ $(Q)sudo env LD_LIBRARY_PATH=$(_libdmmpdir):$(_mpathcmddir) \ - time -p ./$(SPD_TEST_EXEC) - - clean: dep_clean -- rm -f $(TEST_EXEC) $(SPD_TEST_EXEC) -+ $(Q)$(RM) -f $(TEST_EXEC) $(SPD_TEST_EXEC) - - OBJS = $(TEST_EXEC).o $(SPD_TEST_EXEC).o - include $(wildcard $(OBJS:.o=.d)) - - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile -index cfb202b8..be615c2f 100644 ---- a/libmpathcmd/Makefile -+++ b/libmpathcmd/Makefile -@@ -9,22 +9,22 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) -- $(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_cmd.h $(DESTDIR)$(includedir) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(RM) $(DESTDIR)$(includedir)/mpath_cmd.h -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_cmd.h - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile -index 94672556..8f9a43f6 100644 ---- a/libmpathpersist/Makefile -+++ b/libmpathpersist/Makefile -@@ -12,28 +12,28 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 -- $(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_in.3 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persistent_reserve_out.3 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_persist.h $(DESTDIR)$(includedir) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 -- $(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 -- $(RM) $(DESTDIR)$(includedir)/mpath_persist.h -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_in.3 -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man3/mpath_persistent_reserve_out.3 -+ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_persist.h -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathutil/Makefile b/libmpathutil/Makefile -index 5ab33c09..f059de14 100644 ---- a/libmpathutil/Makefile -+++ b/libmpathutil/Makefile -@@ -20,18 +20,18 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -index 88034df3..791a0398 100644 ---- a/libmpathvalid/Makefile -+++ b/libmpathvalid/Makefile -@@ -13,21 +13,21 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - install: $(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -- $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -- $(RM) $(DESTDIR)$(includedir)/mpath_valid.h -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(includedir)/mpath_valid.h - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 1cc13577..3df851e2 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -31,47 +31,47 @@ all: $(DEVLIB) - include $(TOPDIR)/rules.mk - - nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h -- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-function -c -o $@ $< - - # there are lots of "unused parameters" in dict.c - # because not all handler / snprint methods need all parameters - dict.o: dict.c -- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - - make_static = $(shell sed '/^static/!s/^\([a-z]\{1,\} \)/static \1/' <$1 >$2) - - nvme-ioctl.c: nvme/nvme-ioctl.c -- $(call make_static,$<,$@) -+ $(Q)$(call make_static,$<,$@) - - nvme-ioctl.h: nvme/nvme-ioctl.h -- $(call make_static,$<,$@) -+ $(Q)$(call make_static,$<,$@) - - ../tests/$(LIBS): $(OBJS-O) $(OBJS-T) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \ - -o $@ $(OBJS-O) $(OBJS-T) $(LIBDEPS) -- $(LN) $@ ${@:.so.0=.so} -+ $(Q)$(LN) $@ ${@:.so.0=.so} - - # This rule is invoked from tests/Makefile, overriding configdir and plugindir - %-test.o: %.c - @echo building $@ because of $? -- $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< - - test-lib: ../tests/$(LIBS) - - install: all -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) -- $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(plugindir) -+ $(Q)$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - uninstall: -- $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -- $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(Q)$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) - - clean: dep_clean -- $(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) -+ $(Q)$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index 39ad76e0..b3120611 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -22,16 +22,16 @@ LIBS= \ - all: $(LIBS) - - libcheck%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean -- $(RM) core *.a *.o *.gz *.so -+ $(Q)$(RM) core *.a *.o *.gz *.so - - OBJS := $(LIBS:libcheck%.so=%.o) - .SECONDARY: $(OBJS) -@@ -39,4 +39,4 @@ OBJS := $(LIBS:libcheck%.so=%.o) - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile -index 8bf9047b..0e245d6f 100644 ---- a/libmultipath/foreign/Makefile -+++ b/libmultipath/foreign/Makefile -@@ -14,16 +14,16 @@ LIBS = libforeign-nvme.so - all: $(LIBS) - - libforeign-%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean -- $(RM) core *.a *.o *.gz *.so -+ $(Q)$(RM) core *.a *.o *.gz *.so - - OBJS := $(LIBS:libforeign-%.so=%.o) - .SECONDARY: $(OBJS) -@@ -31,4 +31,4 @@ OBJS := $(LIBS:libforeign-%.so=%.o) - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index a699e8a6..e1688163 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -34,16 +34,16 @@ endif - all: $(LIBS) - - libprio%.so: %.o -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ $(LIBDEPS) - - install: $(LIBS) -- $(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) - - uninstall: - for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean -- $(RM) core *.a *.o *.gz *.so -+ $(Q)$(RM) core *.a *.o *.gz *.so - - OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o - .SECONDARY: $(OBJS) -@@ -51,4 +51,4 @@ OBJS = $(LIBS:libprio%.so=%.o) alua_rtpg.o - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile -index d62537b5..f57c105c 100644 ---- a/mpathpersist/Makefile -+++ b/mpathpersist/Makefile -@@ -14,22 +14,22 @@ OBJS = main.o - all: $(EXEC) - - $(EXEC): $(OBJS) -- $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) -+ $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - clean: dep_clean -- $(RM) core *.o $(EXEC) -+ $(Q)$(RM) core *.o $(EXEC) - - include $(wildcard $(OBJS:.o=.d)) - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/multipath/Makefile b/multipath/Makefile -index 7f7b341d..73db991a 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -16,44 +16,46 @@ OBJS := main.o - all: $(EXEC) multipath.rules tmpfiles.conf - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so -- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) - - install: -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) -- $(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -- $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 - ifneq ($(SCSI_DH_MODULES_PRELOAD),) -- $(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -- for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ -+ $(Q)$(INSTALL_PROGRAM) -m 644 scsi_dh.conf $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -+ $(Q)for _x in $(SCSI_DH_MODULES_PRELOAD); do echo "$$_x"; done \ - >>$(DESTDIR)$(modulesloaddir)/scsi_dh.conf - endif - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) -- $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules -- $(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf -- $(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -- $(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) -+ $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules -+ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf -+ $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf -+ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 - - clean: dep_clean -- $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf -+ $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) - - %: %.in -- sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ -+ @echo creating $@ -+ $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 587bb916..9d531329 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -45,41 +45,43 @@ endif - all : $(EXEC) $(CLI) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so -- $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC) $(LIBDEPS) - - multipathc.o: multipathc.c -- $(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(RL_CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - - $(CLI): $(CLI_OBJS) -- $(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CFLAGS) $(CLI_OBJS) $(LDFLAGS) -o $@ $(CLI_LIBDEPS) $(RL_LIBDEPS) - - cli_handlers.o: cli_handlers.c -- $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - - install: -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -+ $(Q)$(INSTALL_PROGRAM) -m 755 $(CLI) $(DESTDIR)$(bindir) - ifdef SYSTEMD -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).socket $(DESTDIR)$(unitdir) - endif -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -- $(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 -+ $(Q)$(INSTALL_PROGRAM) -m 644 $(CLI).8 $(DESTDIR)$(mandir)/man8 - - uninstall: -- $(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) -- $(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -- $(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 -- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).service -- $(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket -+ $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(DESTDIR)$(bindir)/$(CLI) -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 -+ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(CLI).8 -+ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).service -+ $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket - - clean: dep_clean -- $(RM) core *.o $(EXEC) $(CLI) -+ $(Q)$(RM) core *.o $(EXEC) $(CLI) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) -diff --git a/rules.mk b/rules.mk -index d8612527..c3a8e7ac 100644 ---- a/rules.mk -+++ b/rules.mk -@@ -2,17 +2,17 @@ - # SPDX-License-Identifier: GPL-2.0-or-later - - $(DEVLIB): $(LIBS) -- $(LN) $(LIBS) $@ -+ $(Q)$(LN) $(LIBS) $@ - - $(LIBS): $(OBJS) $(VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - $(LIBS:%.so.$(SONAME)=%-nv.so): $(OBJS) $(NV_VERSION_SCRIPT) -- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ -+ $(Q)$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \ - -Wl,--version-script=$(NV_VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS) - - abi: $(LIBS:%.so.$(SONAME)=%-nv.abi) - - $(TOPDIR)/config.mk $(multipathdir)/autoconfig.h: -- $(MAKE) -C $(TOPDIR) -f create-config.mk -+ $(Q)$(MAKE) -C $(TOPDIR) -f create-config.mk -diff --git a/tests/Makefile b/tests/Makefile -index d9856d17..021da0b0 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -12,7 +12,6 @@ TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ - alias directio valid devt mpathvalid strbuf sysfs features cli - HELPERS := test-lib.o test-log.o - --.SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) - - all: $(TESTS:%=%.out) -@@ -71,11 +70,12 @@ features-test_LIBDEPS := -ludev -lpthread - cli-test_OBJDEPS := $(daemondir)/cli.o - - %.o: %.c -- $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< -+ @echo building $@ because of $? -+ $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< - - lib/libchecktur.so: -- mkdir -p lib -- cd lib && ln -s ../$(multipathdir)/*/*.so . -+ @mkdir -p lib -+ $(Q)cd lib && ln -s ../$(multipathdir)/*/*.so . - - %.out: %-test lib/libchecktur.so - @echo == running $< == -@@ -89,34 +89,35 @@ lib/libchecktur.so: - OBJS = $(TESTS:%=%.o) $(HELPERS) - - test_clean: -- $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* -+ $(Q)$(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so* - - valgrind_clean: -- $(RM) $(TESTS:%=%.vgr) -+ $(Q)$(RM) $(TESTS:%=%.vgr) - - clean: test_clean valgrind_clean dep_clean -- $(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap -- $(RM) -rf lib conf.d -+ $(Q)$(RM) $(TESTS:%=%-test) $(OBJS) *.o.wrap -+ $(Q)$(RM) -rf lib conf.d - - .SECONDARY: $(OBJS) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: -- $(RM) $(OBJS:.o=.d) -+ $(Q)$(RM) $(OBJS:.o=.d) - - %.o.wrap: %.c - @sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \ - sort -u | tr '\n' ' ' >$@ - - libmultipath.so.0: $(multipathdir)/libmultipath.so.0 -- make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib -+ @make -C $(multipathdir) configdir=$(TESTDIR)/conf.d plugindir=$(TESTDIR)/lib test-lib - - # COLON will get expanded during second expansion below - COLON:=: - .SECONDEXPANSION: - %-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \ - libmultipath.so.0 $(mpathutildir)/libmpathutil.so.0 $(mpathcmddir)/libmpathcmd.so.0 Makefile -- $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ -+ @echo building $@ -+ $(Q)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ - $(LIBDEPS) $($@_LIBDEPS) \ - $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) diff --git a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0021-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch index 72fbfe8..26b0d06 100644 --- a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0021-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index e6e7f7d7..15f0b9f6 100644 +index 748911e2..c07bcb0c 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch b/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch deleted file mode 100644 index d45f99f..0000000 --- a/0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 14:39:22 +0200 -Subject: [PATCH] multipath-tools: quiet build support for top-level Makefile - -This requires including "Makefile.inc" in the top-level Makefile, -too. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile | 32 ++++++++++++++++++------------ - Makefile.inc | 8 ++++++-- - create-config.mk | 1 - - libmultipath/checkers/Makefile | 2 +- - libmultipath/foreign/Makefile | 2 +- - libmultipath/prioritizers/Makefile | 2 +- - 6 files changed, 28 insertions(+), 19 deletions(-) - -diff --git a/Makefile b/Makefile -index e3ce1a8d..b9e30234 100644 ---- a/Makefile -+++ b/Makefile -@@ -2,6 +2,9 @@ - # Copyright (C) 2003 Christophe Varoqui, - # - -+TOPDIR := . -+include Makefile.inc -+ - LIB_BUILDDIRS := \ - libmpathcmd \ - libmpathutil \ -@@ -32,10 +35,12 @@ all: $(BUILDDIRS) - - config.mk libmultipath/autoconfig.h: - @$(MAKE) -f create-config.mk -+ifeq ($(V),1) - @echo ==== config.mk ==== - @cat config.mk - @echo ==== autoconfig.h ==== - @cat libmultipath/autoconfig.h -+endif - - $(BUILDDIRS): config.mk - @$(MAKE) -C $@ -@@ -48,11 +53,12 @@ $(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS) - # Requires abidw from the abigail suite (https://sourceware.org/libabigail/) - .PHONY: abi - abi: $(LIB_BUILDDIRS:=.abi) -+ @echo creating abi - @mkdir -p $@ -- ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) -+ $(Q)ln -ft $@ $(LIB_BUILDDIRS:=/*.abi) - - abi.tar.gz: abi -- tar cfz $@ abi -+ $(Q)tar cfz $@ abi - - # Check the ABI against a reference. - # This requires the ABI from a previous run to be present -@@ -77,8 +83,8 @@ abi-test: abi reference-abi $(wildcard abi/*.abi) - # Create compile_commands.json, useful for using clangd with an IDE - # Requires bear (https://github.com/rizsotto/Bear) - compile_commands.json: Makefile Makefile.inc $(BUILDDIRS:=/Makefile) -- $(MAKE) clean -- bear -- $(MAKE) -+ $(Q)$(MAKE) clean -+ $(Q)bear -- $(MAKE) - - libmpathutil libdmmp: libmpathcmd - libmultipath: libmpathutil -@@ -103,24 +109,24 @@ $(BUILDDIRS:=.uninstall): - # build it. Both is undesirable. Avoid it by creating config.mk temporarily. - clean: - @touch config.mk -- $(MAKE) $(BUILDDIRS:=.clean) tests.clean || true -- rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk -+ $(Q)$(MAKE) $(BUILDDIRS:=.clean) tests.clean || true -+ $(Q)$(RM) -r abi abi.tar.gz abi-test compile_commands.json config.mk - - install: $(BUILDDIRS:=.install) - uninstall: $(BUILDDIRS:=.uninstall) - - test-progs: all -- $(MAKE) -C tests progs -+ @$(MAKE) -C tests progs - - test: all -- $(MAKE) -C tests all -+ @$(MAKE) -C tests all - - valgrind-test: all -- $(MAKE) -C tests valgrind -+ @$(MAKE) -C tests valgrind - - .PHONY: TAGS - TAGS: -- etags -a libmultipath/*.c -- etags -a libmultipath/*.h -- etags -a multipathd/*.c -- etags -a multipathd/*.h -+ @etags -a libmultipath/*.c -+ @etags -a libmultipath/*.h -+ @etags -a multipathd/*.c -+ @etags -a multipathd/*.h -diff --git a/Makefile.inc b/Makefile.inc -index 3e14cb8c..866ab274 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -27,7 +27,7 @@ PKGCONFIG ?= pkg-config - ifeq ($(TOPDIR),) - TOPDIR = .. - endif --ifneq ($(CREATE_CONFIG),1) -+ifneq ($(TOPDIR),.) - include $(TOPDIR)/config.mk - endif - -@@ -60,7 +60,11 @@ devmapper_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir devmapper),/ - libudev_incdir := $(or $(shell $(PKGCONFIG) --variable=includedir libudev),/usr/include) - kernel_incdir := /usr/include - --Q := $(if $(V),,@) -+ifeq ($(V),) -+Q := @ -+# make's "Entering directory" messages are confusing in parallel mode -+#MAKEFLAGS = --no-print-directory -+endif - - GZIP_PROG := gzip -9 -c - RM := rm -f -diff --git a/create-config.mk b/create-config.mk -index 2cc5284f..434dee06 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -2,7 +2,6 @@ - # SPDX-License-Identifier: GPL-2.0-or-later - - TOPDIR := . --CREATE_CONFIG := 1 - include $(TOPDIR)/Makefile.inc - - # Check whether a function with name $1 has been declared in header file $2. -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index b3120611..6f7cfb95 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -28,7 +28,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done -+ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(Q)$(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/foreign/Makefile b/libmultipath/foreign/Makefile -index 0e245d6f..b83213d6 100644 ---- a/libmultipath/foreign/Makefile -+++ b/libmultipath/foreign/Makefile -@@ -20,7 +20,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done -+ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(Q)$(RM) core *.a *.o *.gz *.so -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index e1688163..fdec36e7 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -40,7 +40,7 @@ install: $(LIBS) - $(Q)$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(plugindir) - - uninstall: -- for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done -+ $(Q)for file in $(LIBS); do $(RM) $(DESTDIR)$(plugindir)/$$file; done - - clean: dep_clean - $(Q)$(RM) core *.a *.o *.gz *.so diff --git a/0022-GitHub-workflows-use-make-j8-Orecurse.patch b/0022-GitHub-workflows-use-make-j8-Orecurse.patch deleted file mode 100644 index 33b7dcd..0000000 --- a/0022-GitHub-workflows-use-make-j8-Orecurse.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 15:29:51 +0200 -Subject: [PATCH] GitHub workflows: use make -j8 -Orecurse - -Without -Orecurse, quiet make output is confusing in parallel mode -because make prints "Entering directory" and "Leaving directory" -messages before and after every target. - -Use parallel compilation also in native.yaml and foreign.yaml. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 2 +- - .github/workflows/build-and-unittest.yaml | 18 +++++++++--------- - .github/workflows/coverity.yaml | 2 +- - .github/workflows/foreign.yaml | 4 ++-- - .github/workflows/native.yaml | 6 +++--- - 5 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 89b971cd..644fcb62 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -32,7 +32,7 @@ jobs: - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev - libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: create ABI -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - - name: save ABI - uses: actions/upload-artifact@v1 - with: -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index a5a0717d..8b6bb776 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -32,11 +32,11 @@ jobs: - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev - libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev - - name: build -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - - name: valgrind-test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - - name: valgrind-results - run: cat tests/*.vgr - - name: clean-nonroot-artifacts -@@ -65,11 +65,11 @@ jobs: - - name: set CC - run: echo CC=gcc-10 >> $GITHUB_ENV - - name: build -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - - name: valgrind-test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - - name: valgrind-results - run: cat tests/*.vgr - - name: clean-nonroot-artifacts -@@ -98,11 +98,11 @@ jobs: - - name: set CC - run: echo CC=clang >> $GITHUB_ENV - - name: build -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) test - - name: valgrind-test -- run: make -O -j$(grep -c ^processor /proc/cpuinfo) valgrind-test -+ run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) valgrind-test - - name: valgrind-results - run: cat tests/*.vgr - - name: clean-nonroot-artifacts -diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml -index 3c6b3824..321b94e0 100644 ---- a/.github/workflows/coverity.yaml -+++ b/.github/workflows/coverity.yaml -@@ -32,7 +32,7 @@ jobs: - - name: build with cov-build - run: > - PATH="$PWD/coverity/bin:$PATH" -- cov-build --dir cov-int make -O -j"$(grep -c ^processor /proc/cpuinfo)" -+ cov-build --dir cov-int make -Orecurse -j"$(grep -c ^processor /proc/cpuinfo)" - - name: pack results - run: tar cfz multipath-tools.tgz cov-int - - name: submit results -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 5a19913a..72ac24fb 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -21,11 +21,11 @@ jobs: - uses: actions/checkout@v1 - - name: build and test - if: ${{ matrix.arch == '' || matrix.arch == '-i386' }} -- run: make test -+ run: make -j8 -Orecurse test - - name: build - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} - # The build path is different between builder and runner -- run: make TESTDIR=${{ github.workspace }}/tests test-progs -+ run: make -j8 -Orecurse TESTDIR=${{ github.workspace }}/tests test-progs - - name: archive - if: ${{ matrix.arch != '' && matrix.arch != '-i386' }} - run: > -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 8b599209..68bf0984 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -92,10 +92,10 @@ jobs: - - name: checkout - uses: actions/checkout@v1 - - name: build and test -- run: make test -+ run: make -j8 -Orecurse test - - name: clean -- run: make clean -+ run: make -j8 -Orecurse clean - - name: clang - env: - CC: clang -- run: make test -+ run: make -j8 -Orecurse test diff --git a/0044-RH-compile-with-libreadline-support.patch b/0022-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0044-RH-compile-with-libreadline-support.patch rename to 0022-RH-compile-with-libreadline-support.patch index b6d59f5..df99295 100644 --- a/0044-RH-compile-with-libreadline-support.patch +++ b/0022-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 15f0b9f6..881c1d52 100644 +index c07bcb0c..e59313c6 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0023-README.md-Move-section-about-libedit-and-libreadline.patch b/0023-README.md-Move-section-about-libedit-and-libreadline.patch deleted file mode 100644 index b860971..0000000 --- a/0023-README.md-Move-section-about-libedit-and-libreadline.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 15:40:16 +0200 -Subject: [PATCH] README.md: Move section about libedit and libreadline - -This paragraph belongs in the "Customiting build" section. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/README.md b/README.md -index d003e1db..52ab776b 100644 ---- a/README.md -+++ b/README.md -@@ -53,14 +53,9 @@ Building multipath-tools - ======================== - - Prerequisites: development packages of for `libdevmapper`, `libaio`, `libudev`, --`libjson-c`, `liburcu`, and `libsystemd`. -- --To enable commandline history and TAB completion in the interactive mode *(which --is entered with `multipathd -k` or `multipathc`)* you might also set `READLINE` --make variable to `libedit` or `libreadline`, like `make READLINE=libreadline`. --That requires a development package for the library you chose. Note that using --libreadline may [make binary indistributable due to license --incompatibility](https://github.com/opensvc/multipath-tools/issues/36). -+`libjson-c`, `liburcu`, and `libsystemd`. If commandline editing is enabled -+(see below), the development package for either `libedit` or `libreadline` is -+required as well. - - Then, build and install multipath-tools with: - -@@ -82,6 +77,12 @@ The following variables can be passed to the `make` command line: - * `configdir="/some/path"` : directory to search for configuration files. - This used to be the run-time option `config_dir` in earlier versions. - The default is `/etc/multipath/conf.d`. -+ * `READLINE=libedit` or `READLINE=libreadline`: enable command line history -+ and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. -+ The respective development package will be required for building. -+ By default, command line editing is disabled. -+ Note that using libreadline may -+ [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). - * `ENABLE_LIBDMMP=0`: disable building libdmmp - * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event - polling API. For use with pre-5.0 kernels that don't support dmevent polling diff --git a/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch b/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch deleted file mode 100644 index 63b6c2f..0000000 --- a/0024-README.md-Fix-indentation-in-paragraph-about-device-.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 15:42:15 +0200 -Subject: [PATCH] README.md: Fix indentation in paragraph about device handlers - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/README.md b/README.md -index 52ab776b..b1b78fbb 100644 ---- a/README.md -+++ b/README.md -@@ -94,12 +94,12 @@ The following variables can be passed to the `make` command line: - early. This option causes a *modules-load.d(5)* configuration file to be - created, thus it depends on functionality provided by *systemd*. - This variable only matters for `make install`. -- --Note: The usefulness of the preload list depends on the kernel configuration. --It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and --other device handler modules are built as modules. If `scsi_mod` itself is compiled --as a module, it might make more sense to use a module softdep for the same --purpose. -+ -+ **Note**: The usefulness of the preload list depends on the kernel configuration. -+ It's especially useful if `scsi_mod` is builtin but `scsi_dh_alua` and -+ other device handler modules are built as modules. If `scsi_mod` itself is compiled -+ as a module, it might make more sense to use a module softdep for the same -+ purpose. - - See `Makefile.inc` for additional variables to customize paths and compiler - flags. diff --git a/0025-README.md-document-options-for-paths-and-optimizatio.patch b/0025-README.md-document-options-for-paths-and-optimizatio.patch deleted file mode 100644 index ca00d85..0000000 --- a/0025-README.md-document-options-for-paths-and-optimizatio.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 16:01:17 +0200 -Subject: [PATCH] README.md: document options for paths and optimization - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 25 +++++++++++++++++++++++-- - 1 file changed, 23 insertions(+), 2 deletions(-) - -diff --git a/README.md b/README.md -index b1b78fbb..ab7dc3c9 100644 ---- a/README.md -+++ b/README.md -@@ -101,8 +101,29 @@ The following variables can be passed to the `make` command line: - as a module, it might make more sense to use a module softdep for the same - purpose. - --See `Makefile.inc` for additional variables to customize paths and compiler --flags. -+### Installation Paths -+ -+ * `prefix`: The directory prefix for (almost) all files to be installed. -+ Distributions may want to set this to `/usr`. -+ **Note**: for multipath-tools, unlike many other packages, `prefix` -+ defaults to the empty string, which resolves to the root directory (`/`). -+ * `usr_prefix`: where to install those parts of the code that aren't necessary -+ for booting. You may want to set this to `/usr` if `prefix` is empty. -+ * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. -+ Some systemd installations use separate `prefix` and `rootprefix`. On such -+ a distribution, set `prefix`, and override `unitdir` to use systemd's -+ `rootprefix`. -+ * `LIB`: the subdirectory under `prefix` where shared libraries will be -+ installed. By default, the makefile uses `/lib64` if this directory is -+ found on the build system, and `/lib` otherwise. -+ -+See also `configdir` and `plugindir` above. See `Makefile.inc` for more -+fine-grained control. -+ -+### Compiler Options -+ -+Use `OPTFLAGS` to change optimization-related compiler options; -+e.g. `OPTFLAGS="-g -O0"` to disable all optimizations. - - Special Makefile targets - ------------------------ diff --git a/0026-README.md-document-how-to-customize-build.patch b/0026-README.md-document-how-to-customize-build.patch deleted file mode 100644 index c3dfedb..0000000 --- a/0026-README.md-document-how-to-customize-build.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 16:01:41 +0200 -Subject: [PATCH] README.md: document how to customize build - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/README.md b/README.md -index ab7dc3c9..bbeb44fe 100644 ---- a/README.md -+++ b/README.md -@@ -66,9 +66,21 @@ To uninstall, type: - - make uninstall - -+By default, the build will run quietly, just printing one-line messages -+about the files being built. To enable more verbose output, run `make V=1`. -+ - Customizing the build - --------------------- - -+**Note**: With very few exceptions, the build process does not read -+configuration from the environment. So using syntax like -+ -+ SOME_VAR=some_value make -+ -+will **not** have the intended effect. Use the following instead: -+ -+ make SOME_VAR=some_value -+ - The following variables can be passed to the `make` command line: - - * `plugindir="/some/path"`: directory where libmultipath plugins (path diff --git a/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch b/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch deleted file mode 100644 index 1ae51d8..0000000 --- a/0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 28 Oct 2022 21:10:41 +0200 -Subject: [PATCH] libmultipath: avoid -Warray-bounds error with gcc 12 and musl - libc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The following error is observed with gcc 12, strangely only with -MUSL libc: - -In function ‘__uatomic_inc’, - inlined from ‘lock’ at ../libmultipath/lock.h:24:2, - inlined from ‘child’ at main.c:3523:3, - inlined from ‘main’ at main.c:3755:11: -/usr/include/urcu/uatomic/x86.h:439:17: error: array subscript ‘struct __uatomic_dummy[0]’ is partly outside array bounds of ‘unsigned char[72]’ [-Werror=array-bounds] - -The problem is that &(vecs->lock.waiters) is casted to a pointer to -struct { long[10]; } which goes beyond the "struct vectors". -We don't read or write from/to that memory, but the compiler complains either -way. - -latest liburcu has a patch for it: - -http://git.liburcu.org/?p=userspace-rcu.git;a=commitdiff;h=835b9ab3ca3777fe42e37e92096226ebd19ca75b - -For now, just disable the warning in lock.h, using a pragma. - -Signed-off-by: Martin Wilck -Reported-by: Xose Vasquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/lock.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/libmultipath/lock.h b/libmultipath/lock.h -index 20ca77e6..9814be76 100644 ---- a/libmultipath/lock.h -+++ b/libmultipath/lock.h -@@ -13,6 +13,11 @@ struct mutex_lock { - int waiters; /* uatomic access only */ - }; - -+#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Warray-bounds" -+#endif -+ - static inline void init_lock(struct mutex_lock *a) - { - pthread_mutex_init(&a->mutex, NULL); -@@ -46,6 +51,10 @@ static inline bool lock_has_waiters(struct mutex_lock *a) - return (uatomic_read(&a->waiters) > 0); - } - -+#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 -+#pragma GCC diagnostic pop -+#endif -+ - #define lock_cleanup_pop(a) pthread_cleanup_pop(1) - - void cleanup_lock (void * data); diff --git a/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch b/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch deleted file mode 100644 index 2be93fc..0000000 --- a/0028-multipath-avoid-NULL-string-in-released_to_systemd.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 27 Sep 2022 12:14:09 +0200 -Subject: [PATCH] multipath: avoid NULL string in released_to_systemd() - -Fixes: b28c406 ("multipath -u: don't grab devices already passed to system") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 7b69a3ce..b9f360b4 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -435,7 +435,8 @@ static bool released_to_systemd(void) - bool ret; - - ret = dm_mp_dev_path != NULL && !strcmp(dm_mp_dev_path, "0"); -- condlog(4, "%s: %s=%s -> %d", __func__, dmdp, dm_mp_dev_path, ret); -+ condlog(4, "%s: %s=%s -> %d", __func__, dmdp, -+ dm_mp_dev_path ? dm_mp_dev_path : "", ret); - return ret; - } - diff --git a/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch b/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch deleted file mode 100644 index e48d44c..0000000 --- a/0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 27 Sep 2022 12:28:26 +0200 -Subject: [PATCH] libmultipath: avoid NULL string in is_udev_ready() - -Fixes: 2b25a9e ("libmultipath: select_action(): force udev reload for uninitialized maps") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e5249fc1..e551047a 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -662,7 +662,8 @@ static bool is_udev_ready(struct multipath *cmpp) - env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY"); - rc = (env != NULL && !strcmp(env, "1")); - udev_device_unref(mpp_ud); -- condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc); -+ condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, -+ env ? env : "", rc); - return rc; - } - diff --git a/0030-libmultipath-impove-add_feature-variable-names.patch b/0030-libmultipath-impove-add_feature-variable-names.patch deleted file mode 100644 index 9cc841d..0000000 --- a/0030-libmultipath-impove-add_feature-variable-names.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 9 Nov 2022 15:49:41 -0600 -Subject: [PATCH] libmultipath: impove add_feature() variable names - -Use descriptive names, instead of single letters. No functional changes. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs.c | 63 +++++++++++++++++++++--------------------- - 1 file changed, 32 insertions(+), 31 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 7a2ff589..f90bd0b6 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -604,65 +604,66 @@ first_path (const struct multipath * mpp) - return pgp?VECTOR_SLOT(pgp->paths, 0):NULL; - } - --int add_feature(char **f, const char *n) -+int add_feature(char **features_p, const char *new_feat) - { -- int c = 0, d, l; -- char *e, *t; -- const char *p; -+ int count = 0, new_count, len; -+ char *tmp, *feats; -+ const char *ptr; - -- if (!f) -+ if (!features_p) - return 1; - - /* Nothing to do */ -- if (!n || *n == '\0') -+ if (!new_feat || *new_feat == '\0') - return 0; - -- l = strlen(n); -- if (isspace(*n) || isspace(*(n + l - 1))) { -- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n); -+ len = strlen(new_feat); -+ if (isspace(*new_feat) || isspace(*(new_feat + len - 1))) { -+ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", -+ new_feat); - return 1; - } - -- p = n; -- d = 1; -- while (*p != '\0') { -- if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0') -- d++; -- p++; -+ ptr = new_feat; -+ new_count = 1; -+ while (*ptr != '\0') { -+ if (isspace(*ptr) && !isspace(*(ptr + 1)) && *(ptr + 1) != '\0') -+ new_count++; -+ ptr++; - } - - /* default feature is null */ -- if(!*f) -+ if(!*features_p) - { -- l = asprintf(&t, "%0d %s", d, n); -- if(l == -1) -+ len = asprintf(&feats, "%0d %s", new_count, new_feat); -+ if(len == -1) - return 1; - -- *f = t; -+ *features_p = feats; - return 0; - } - - /* Check if feature is already present */ -- e = *f; -- while ((e = strstr(e, n)) != NULL) { -- if (isspace(*(e - 1)) && -- (isspace(*(e + l)) || *(e + l) == '\0')) -+ tmp = *features_p; -+ while ((tmp = strstr(tmp, new_feat)) != NULL) { -+ if (isspace(*(tmp - 1)) && -+ (isspace(*(tmp + len)) || *(tmp + len) == '\0')) - return 0; -- e += l; -+ tmp += len; - } - - /* Get feature count */ -- c = strtoul(*f, &e, 10); -- if (*f == e || (!isspace(*e) && *e != '\0')) { -- condlog(0, "parse error in feature string \"%s\"", *f); -+ count = strtoul(*features_p, &tmp, 10); -+ if (*features_p == tmp || (!isspace(*tmp) && *tmp != '\0')) { -+ condlog(0, "parse error in feature string \"%s\"", *features_p); - return 1; - } -- c += d; -- if (asprintf(&t, "%0d%s %s", c, e, n) < 0) -+ count += new_count; -+ if (asprintf(&feats, "%0d%s %s", count, tmp, new_feat) < 0) - return 1; - -- free(*f); -- *f = t; -+ free(*features_p); -+ *features_p = feats; - - return 0; - } diff --git a/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch b/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch deleted file mode 100644 index 6dc8a0e..0000000 --- a/0031-multipathd-don-t-initialize-the-field-width-in-show_.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 9 Nov 2022 15:49:42 -0600 -Subject: [PATCH] multipathd: don't initialize the field width in show_path() - -It's not used, so don't set it up. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/cli_handlers.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 5f0dd04e..e65fb75c 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -67,12 +67,7 @@ static int - show_path (struct strbuf *reply, struct vectors *vecs, struct path *pp, - char *style) - { -- fieldwidth_t *width __attribute__((cleanup(cleanup_ucharp))) = NULL; -- -- if ((width = alloc_path_layout()) == NULL) -- return 1; -- get_path_layout(vecs->pathvec, 1, width); -- if (snprint_path(reply, style, pp, 0) < 0) -+ if (snprint_path(reply, style, pp, NULL) < 0) - return 1; - return 0; - } diff --git a/0032-libmultipath-improve-remove_feature-variable-names.patch b/0032-libmultipath-improve-remove_feature-variable-names.patch deleted file mode 100644 index c1642d4..0000000 --- a/0032-libmultipath-improve-remove_feature-variable-names.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 9 Nov 2022 15:49:43 -0600 -Subject: [PATCH] libmultipath: improve remove_feature() variable names - -Use descriptive names, instead of single letters. No functional changes. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs.c | 80 +++++++++++++++++++++--------------------- - 1 file changed, 40 insertions(+), 40 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index f90bd0b6..87e84d5d 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -668,86 +668,86 @@ int add_feature(char **features_p, const char *new_feat) - return 0; - } - --int remove_feature(char **f, const char *o) -+int remove_feature(char **features_p, const char *old_feat) - { -- int c = 0, d; -- char *e, *p, *n; -- const char *q; -+ int count = 0, len; -+ char *feats_start, *ptr, *new; - -- if (!f || !*f) -+ if (!features_p || !*features_p) - return 1; - - /* Nothing to do */ -- if (!o || *o == '\0') -+ if (!old_feat || *old_feat == '\0') - return 0; - -- d = strlen(o); -- if (isspace(*o) || isspace(*(o + d - 1))) { -- condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", o); -+ len = strlen(old_feat); -+ if (isspace(*old_feat) || isspace(*(old_feat + len - 1))) { -+ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", -+ old_feat); - return 1; - } - - /* Check if present and not part of a larger feature token*/ -- p = *f + 1; /* the size must be at the start of the features string */ -- while ((p = strstr(p, o)) != NULL) { -- if (isspace(*(p - 1)) && -- (isspace(*(p + d)) || *(p + d) == '\0')) -+ ptr = *features_p + 1; -+ while ((ptr = strstr(ptr, old_feat)) != NULL) { -+ if (isspace(*(ptr - 1)) && -+ (isspace(*(ptr + len)) || *(ptr + len) == '\0')) - break; -- p += d; -+ ptr += len; - } -- if (!p) -+ if (!ptr) - return 0; - - /* Get feature count */ -- c = strtoul(*f, &e, 10); -- if (*f == e || !isspace(*e)) { -- condlog(0, "parse error in feature string \"%s\"", *f); -+ count = strtoul(*features_p, &feats_start, 10); -+ if (*features_p == feats_start || !isspace(*feats_start)) { -+ condlog(0, "parse error in feature string \"%s\"", *features_p); - return 1; - } - - /* Update feature count */ -- c--; -- q = o; -- while (*q != '\0') { -- if (isspace(*q) && !isspace(*(q + 1)) && *(q + 1) != '\0') -- c--; -- q++; -+ count--; -+ while (*old_feat != '\0') { -+ if (isspace(*old_feat) && !isspace(*(old_feat + 1)) && -+ *(old_feat + 1) != '\0') -+ count--; -+ old_feat++; - } - - /* Quick exit if all features have been removed */ -- if (c == 0) { -- n = malloc(2); -- if (!n) -+ if (count == 0) { -+ new = malloc(2); -+ if (!new) - return 1; -- strcpy(n, "0"); -+ strcpy(new, "0"); - goto out; - } - - /* Update feature count space */ -- n = malloc(strlen(*f) - d + 1); -- if (!n) -+ new = malloc(strlen(*features_p) - len + 1); -+ if (!new) - return 1; - - /* Copy the feature count */ -- sprintf(n, "%0d", c); -+ sprintf(new, "%0d", count); - /* - * Copy existing features up to the feature - * about to be removed - */ -- strncat(n, e, (size_t)(p - e)); -+ strncat(new, feats_start, (size_t)(ptr - feats_start)); - /* Skip feature to be removed */ -- p += d; -+ ptr += len; - /* Copy remaining features */ -- while (isspace(*p)) -- p++; -- if (*p != '\0') -- strcat(n, p); -+ while (isspace(*ptr)) -+ ptr++; -+ if (*ptr != '\0') -+ strcat(new, ptr); - else -- strchop(n); -+ strchop(new); - - out: -- free(*f); -- *f = n; -+ free(*features_p); -+ *features_p = new; - - return 0; - } diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 847d6b9..2933cbd 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,59 +1,37 @@ Name: device-mapper-multipath -Version: 0.9.3 -Release: 2%{?dist} +Version: 0.9.4 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.3.tar.gz -o multipath-tools-0.9.3.tgz -Source0: multipath-tools-0.9.3.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.4.tar.gz -o multipath-tools-0.9.4.tgz +Source0: multipath-tools-0.9.4.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-fix-show-paths-format-failure.patch -Patch0002: 0002-fixup-Makefile.inc-fix-man-and-include-paths.patch -Patch0003: 0003-multipath-tools-Makefile.inc-Fix-paths-for-systemd.patch -Patch0004: 0004-multipath-tools-Makefile.inc-don-t-take-values-from-.patch -Patch0005: 0005-multipath-tools-Makefile.inc-get-rid-of-RUN.patch -Patch0006: 0006-multipath-tools-Makefile.inc-more-compact-code-for-L.patch -Patch0007: 0007-multipath-tools-Makefiles-simplify-code-for-include-.patch -Patch0008: 0008-multipath-tools-Makefiles-use-mandir.patch -Patch0009: 0009-multipath-tools-Makefile.inc-simplify-expression-for.patch -Patch0010: 0010-multipath-tools-Makefile.inc-untangle-paths-and-sour.patch -Patch0011: 0011-multipath-tools-Makefiles-replace-libdir-by-plugindi.patch -Patch0012: 0012-multipath-tools-Makefile.inc-use-simple-make-variabl.patch -Patch0013: 0013-multipath-tools-Makefile.inc-fix-a-log-message.patch -Patch0014: 0014-multipath-tools-Makefile.inc-set-systemd-specific-fl.patch -Patch0015: 0015-multipathd-Makefile-fix-compilation-flags-for-libedi.patch -Patch0016: 0016-multipath-tools-Makefiles-clean-up-executable-Makefi.patch -Patch0017: 0017-multipath-tools-Makefiles-use-common-code-for-librar.patch -Patch0018: 0018-multipath-tools-Makefiles-move-common-code-to-rules..patch -Patch0019: 0019-multipath-tools-Makefiles-create-config.mk.patch -Patch0020: 0020-multipath-tools-Makefiles-enable-quiet-build.patch -Patch0021: 0021-multipath-tools-quiet-build-support-for-top-level-Ma.patch -Patch0022: 0022-GitHub-workflows-use-make-j8-Orecurse.patch -Patch0023: 0023-README.md-Move-section-about-libedit-and-libreadline.patch -Patch0024: 0024-README.md-Fix-indentation-in-paragraph-about-device-.patch -Patch0025: 0025-README.md-document-options-for-paths-and-optimizatio.patch -Patch0026: 0026-README.md-document-how-to-customize-build.patch -Patch0027: 0027-libmultipath-avoid-Warray-bounds-error-with-gcc-12-a.patch -Patch0028: 0028-multipath-avoid-NULL-string-in-released_to_systemd.patch -Patch0029: 0029-libmultipath-avoid-NULL-string-in-is_udev_ready.patch -Patch0030: 0030-libmultipath-impove-add_feature-variable-names.patch -Patch0031: 0031-multipathd-don-t-initialize-the-field-width-in-show_.patch -Patch0032: 0032-libmultipath-improve-remove_feature-variable-names.patch -Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch -Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0035: 0035-RH-don-t-start-without-a-config-file.patch -Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch -Patch0037: 0037-RH-use-rpm-optflags-if-present.patch -Patch0038: 0038-RH-add-mpathconf.patch -Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0044: 0044-RH-compile-with-libreadline-support.patch +Patch0001: 0001-multipathd-make-pr-registration-consistent.patch +Patch0002: 0002-libmultipath-make-prflag-an-enum.patch +Patch0003: 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch +Patch0004: 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch +Patch0005: 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch +Patch0006: 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch +Patch0007: 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch +Patch0008: 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch +Patch0009: 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch +Patch0010: 0010-libmultipath-bump-ABI-version-to-18.0.0.patch +Patch0011: 0011-RH-fixup-udev-rules-for-redhat.patch +Patch0012: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0013: 0013-RH-don-t-start-without-a-config-file.patch +Patch0014: 0014-RH-Fix-nvme-function-missing-argument.patch +Patch0015: 0015-RH-use-rpm-optflags-if-present.patch +Patch0016: 0016-RH-add-mpathconf.patch +Patch0017: 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0018: 0018-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0020: 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0021: 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0022: 0022-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -61,6 +39,7 @@ Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu Requires: readline +Requires: libmount Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -82,6 +61,7 @@ BuildRequires: readline-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel +BuildRequires: libmount-devel BuildRequires: make %description @@ -138,7 +118,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.3 -p1 +%autosetup -n multipath-tools-0.9.4 -p1 cp %{SOURCE1} . %build @@ -260,6 +240,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 26 2023 Benjamin Marzinski - 0.9.4-1 +- Update to the head of the upstream staging branch + * Previous patches 0001-0032 are intlcude in the source tarball + * Patches 0001-0010 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0033-0044 are not patches 0011-0022 +- Add dependency on libmount + * Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/sources b/sources index 0394f4e..462cab6 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.3.tgz) = 4faa2ee5a96a9d5d752219931ebc885cb70ed6b022d45ede985ad7919c043a3aee166e6f126d32dffd187c5c32d5cbce91747d87d0b55557e2f7f68b279583da +SHA512 (multipath-tools-0.9.4.tgz) = 5e0dcea610fc215e345444c04453a38f39c73e493c2bc53f6b3a90cd701266aabdf7c4693dfc321099af836d0019bf27355e265ad5db5deff48f8bb94ed4719d SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From bbfe9b12298331b52b0d1de1f1087bc8eac1374a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 2 Feb 2023 14:07:38 -0600 Subject: [PATCH 04/33] device-mapper-multipath-0.9.4-2 Update to the head of the upstream staging branch * Patches 0011-0015 are from the upstream staging branch Rename redhat patches * Previous patches 0011-0022 are now patches 0016-0027 --- ...-select_reload_action-in-select_acti.patch | 39 ++++ ...ect-resize-action-even-if-reload-is-.patch | 46 +++++ ...anup-ACT_CREATE-code-in-select_actio.patch | 68 +++++++ ...p-renames-from-stopping-other-multip.patch | 186 ++++++++++++++++++ ...t-fix-resource-leak-in-update_map_pr.patch | 68 +++++++ ... 0016-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 0 ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0020-RH-use-rpm-optflags-if-present.patch | 0 ...hconf.patch => 0021-RH-add-mpathconf.patch | 0 ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 0 ...si-device-handlers-to-modules-load.d.patch | 0 ...-RH-compile-with-libreadline-support.patch | 0 device-mapper-multipath.spec | 41 ++-- 18 files changed, 433 insertions(+), 15 deletions(-) create mode 100644 0011-libmultipath-use-select_reload_action-in-select_acti.patch create mode 100644 0012-libmultipath-select-resize-action-even-if-reload-is-.patch create mode 100644 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch create mode 100644 0014-libmultipath-keep-renames-from-stopping-other-multip.patch create mode 100644 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch rename 0011-RH-fixup-udev-rules-for-redhat.patch => 0016-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0012-RH-Remove-the-property-blacklist-exception-builtin.patch => 0017-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0013-RH-don-t-start-without-a-config-file.patch => 0018-RH-don-t-start-without-a-config-file.patch (100%) rename 0014-RH-Fix-nvme-function-missing-argument.patch => 0019-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0015-RH-use-rpm-optflags-if-present.patch => 0020-RH-use-rpm-optflags-if-present.patch (100%) rename 0016-RH-add-mpathconf.patch => 0021-RH-add-mpathconf.patch (100%) rename 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) rename 0018-RH-reset-default-find_mutipaths-value-to-off.patch => 0023-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (100%) rename 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch (100%) rename 0022-RH-compile-with-libreadline-support.patch => 0027-RH-compile-with-libreadline-support.patch (100%) diff --git a/0011-libmultipath-use-select_reload_action-in-select_acti.patch b/0011-libmultipath-use-select_reload_action-in-select_acti.patch new file mode 100644 index 0000000..05cc2ce --- /dev/null +++ b/0011-libmultipath-use-select_reload_action-in-select_acti.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:18 -0600 +Subject: [PATCH] libmultipath: use select_reload_action in select_action + +Since we have a function to set the action to reload, use it. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e689f8a7..050b984a 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -729,9 +729,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + + if (force_reload) { + mpp->force_udev_reload = 1; +- mpp->action = ACT_RELOAD; +- condlog(3, "%s: set ACT_RELOAD (forced by user)", +- mpp->alias); ++ select_reload_action(mpp, "forced by user"); + return; + } + if (cmpp->size != mpp->size) { +@@ -744,9 +742,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + + if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { + mpp->force_udev_reload = 1; +- mpp->action = ACT_RELOAD; +- condlog(3, "%s: set ACT_RELOAD (udev incomplete)", +- mpp->alias); ++ select_reload_action(mpp, "udev incomplete"); + return; + } + diff --git a/0012-libmultipath-select-resize-action-even-if-reload-is-.patch b/0012-libmultipath-select-resize-action-even-if-reload-is-.patch new file mode 100644 index 0000000..39518c4 --- /dev/null +++ b/0012-libmultipath-select-resize-action-even-if-reload-is-.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:19 -0600 +Subject: [PATCH] libmultipath: select resize action even if reload is forced + +The ACT_RESIZE action is the same as the ACT_RELOAD action, except that +it flushes outstanding IO because the device size is changing and +the new size might be too small for some of the outstanding IO. If we've +detected a size change, and a forced reload is requested, we still need +to flush the IO because the reload will change the device size. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 050b984a..6811e661 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -727,11 +727,6 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + return; + } + +- if (force_reload) { +- mpp->force_udev_reload = 1; +- select_reload_action(mpp, "forced by user"); +- return; +- } + if (cmpp->size != mpp->size) { + mpp->force_udev_reload = 1; + mpp->action = ACT_RESIZE; +@@ -740,6 +735,12 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + return; + } + ++ if (force_reload) { ++ mpp->force_udev_reload = 1; ++ select_reload_action(mpp, "forced by user"); ++ return; ++ } ++ + if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { + mpp->force_udev_reload = 1; + select_reload_action(mpp, "udev incomplete"); diff --git a/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch b/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch new file mode 100644 index 0000000..3574bac --- /dev/null +++ b/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:20 -0600 +Subject: [PATCH] libmultipath: cleanup ACT_CREATE code in select_action + +Combine the two separate blocks that set ACT_CREATE into one. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 38 +++++++++++++++++--------------------- + 1 file changed, 17 insertions(+), 21 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 6811e661..e870e0f6 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -686,33 +686,29 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + if (mpp->need_reload || (cmpp && cmpp->need_reload)) + force_reload = 1; + +- if (!cmpp_by_name) { +- if (cmpp) { +- condlog(2, "%s: rename %s to %s", mpp->wwid, +- cmpp->alias, mpp->alias); +- strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); +- mpp->action = ACT_RENAME; +- if (force_reload) { +- mpp->force_udev_reload = 1; +- mpp->action = ACT_FORCERENAME; +- } +- return; ++ if (!cmpp) { ++ if (cmpp_by_name) { ++ condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", ++ mpp->wwid, mpp->alias, cmpp_by_name->wwid); ++ /* We can do this because wwid wasn't found */ ++ free(mpp->alias); ++ mpp->alias = strdup(mpp->wwid); + } + mpp->action = ACT_CREATE; +- condlog(3, "%s: set ACT_CREATE (map does not exist)", +- mpp->alias); ++ condlog(3, "%s: set ACT_CREATE (map does not exist%s)", ++ mpp->alias, cmpp_by_name ? ", name changed" : ""); + return; + } + +- if (!cmpp) { +- condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", +- mpp->wwid, mpp->alias, cmpp_by_name->wwid); +- /* We can do this because wwid wasn't found */ +- free(mpp->alias); +- mpp->alias = strdup(mpp->wwid); +- mpp->action = ACT_CREATE; +- condlog(3, "%s: set ACT_CREATE (map does not exist, name changed)", ++ if (!cmpp_by_name) { ++ condlog(2, "%s: rename %s to %s", mpp->wwid, cmpp->alias, + mpp->alias); ++ strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); ++ mpp->action = ACT_RENAME; ++ if (force_reload) { ++ mpp->force_udev_reload = 1; ++ mpp->action = ACT_FORCERENAME; ++ } + return; + } + diff --git a/0014-libmultipath-keep-renames-from-stopping-other-multip.patch b/0014-libmultipath-keep-renames-from-stopping-other-multip.patch new file mode 100644 index 0000000..f597e61 --- /dev/null +++ b/0014-libmultipath-keep-renames-from-stopping-other-multip.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jan 2023 13:34:21 -0600 +Subject: [PATCH] libmultipath: keep renames from stopping other multipath + actions + +If select_action() is called and a multipath device needs to be renamed, +the code currently checks if force_reload is set, and if so, does the +reload after the rename. But if force_reload isn't set, only the rename +happens, regardless of what other actions are needed. This can happen if +multipathd starts up and a device needs both a reload and a rename. + +Make multipath check for resize, reload, and switch pathgroup along with +rename, and do both if necessary. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/configure.c | 62 +++++++++++++++++----------------------- + libmultipath/configure.h | 4 ++- + 2 files changed, 30 insertions(+), 36 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e870e0f6..4a1c28bb 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -670,7 +670,8 @@ static bool is_udev_ready(struct multipath *cmpp) + static void + select_reload_action(struct multipath *mpp, const char *reason) + { +- mpp->action = ACT_RELOAD; ++ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : ++ ACT_RELOAD; + condlog(3, "%s: set ACT_RELOAD (%s)", mpp->alias, reason); + } + +@@ -681,6 +682,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + struct multipath * cmpp_by_name; + char * mpp_feat, * cmpp_feat; + ++ mpp->action = ACT_NOTHING; + cmpp = find_mp_by_wwid(curmp, mpp->wwid); + cmpp_by_name = find_mp_by_alias(curmp, mpp->alias); + if (mpp->need_reload || (cmpp && cmpp->need_reload)) +@@ -705,14 +707,8 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + mpp->alias); + strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); + mpp->action = ACT_RENAME; +- if (force_reload) { +- mpp->force_udev_reload = 1; +- mpp->action = ACT_FORCERENAME; +- } +- return; +- } +- +- if (cmpp != cmpp_by_name) { ++ /* don't return here. Check for other needed actions */ ++ } else if (cmpp != cmpp_by_name) { + condlog(2, "%s: unable to rename %s to %s (%s is used by %s)", + mpp->wwid, cmpp->alias, mpp->alias, + mpp->alias, cmpp_by_name->wwid); +@@ -720,12 +716,13 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + free(mpp->alias); + mpp->alias = strdup(cmpp->alias); + mpp->action = ACT_IMPOSSIBLE; +- return; ++ /* don't return here. Check for other needed actions */ + } + + if (cmpp->size != mpp->size) { + mpp->force_udev_reload = 1; +- mpp->action = ACT_RESIZE; ++ mpp->action = mpp->action == ACT_RENAME ? ACT_RESIZE_RENAME : ++ ACT_RESIZE; + condlog(3, "%s: set ACT_RESIZE (size change)", + mpp->alias); + return; +@@ -801,14 +798,14 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, + return; + } + if (cmpp->nextpg != mpp->bestpg) { +- mpp->action = ACT_SWITCHPG; ++ mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME : ++ ACT_SWITCHPG; + condlog(3, "%s: set ACT_SWITCHPG (next path group change)", + mpp->alias); + return; + } +- mpp->action = ACT_NOTHING; +- condlog(3, "%s: set ACT_NOTHING (map unchanged)", +- mpp->alias); ++ if (mpp->action == ACT_NOTHING) ++ condlog(3, "%s: set ACT_NOTHING (map unchanged)", mpp->alias); + return; + } + +@@ -909,6 +906,17 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + } + } + ++ if (mpp->action == ACT_RENAME || mpp->action == ACT_SWITCHPG_RENAME || ++ mpp->action == ACT_RELOAD_RENAME || ++ mpp->action == ACT_RESIZE_RENAME) { ++ conf = get_multipath_config(); ++ pthread_cleanup_push(put_multipath_config, conf); ++ r = dm_rename(mpp->alias_old, mpp->alias, ++ conf->partition_delim, mpp->skip_kpartx); ++ pthread_cleanup_pop(1); ++ if (r == DOMAP_FAIL) ++ return r; ++ } + switch (mpp->action) { + case ACT_REJECT: + case ACT_NOTHING: +@@ -916,6 +924,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + return DOMAP_EXIST; + + case ACT_SWITCHPG: ++ case ACT_SWITCHPG_RENAME: + dm_switchgroup(mpp->alias, mpp->bestpg); + /* + * we may have avoided reinstating paths because there where in +@@ -942,6 +951,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + break; + + case ACT_RELOAD: ++ case ACT_RELOAD_RENAME: + sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; +@@ -949,6 +959,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + break; + + case ACT_RESIZE: ++ case ACT_RESIZE_RENAME: + sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; +@@ -956,29 +967,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + break; + + case ACT_RENAME: +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- r = dm_rename(mpp->alias_old, mpp->alias, +- conf->partition_delim, mpp->skip_kpartx); +- pthread_cleanup_pop(1); +- break; +- +- case ACT_FORCERENAME: +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- r = dm_rename(mpp->alias_old, mpp->alias, +- conf->partition_delim, mpp->skip_kpartx); +- pthread_cleanup_pop(1); +- if (r) { +- sysfs_set_max_sectors_kb(mpp, 1); +- if (mpp->ghost_delay_tick > 0 && +- pathcount(mpp, PATH_UP)) +- mpp->ghost_delay_tick = 0; +- r = dm_addmap_reload(mpp, params, 0); +- } + break; + + default: ++ r = DOMAP_FAIL; + break; + } + +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index 2bf73e65..9d935db3 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -18,9 +18,11 @@ enum actions { + ACT_RENAME, + ACT_CREATE, + ACT_RESIZE, +- ACT_FORCERENAME, ++ ACT_RELOAD_RENAME, + ACT_DRY_RUN, + ACT_IMPOSSIBLE, ++ ACT_RESIZE_RENAME, ++ ACT_SWITCHPG_RENAME, + }; + + /* diff --git a/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch b/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch new file mode 100644 index 0000000..866080f --- /dev/null +++ b/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 Feb 2023 09:20:35 +0100 +Subject: [PATCH] libmpathpersist: fix resource leak in update_map_pr() + +The "no available paths" case would leak the memory resp points to. +Found by coverity. + +Fixes: 50e2c16 ("multipathd: handle no active paths in update_map_pr") + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist_int.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index 8b52b746..178c2f54 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -733,7 +733,7 @@ int update_map_pr(struct multipath *mpp) + int noisy=0; + struct prin_resp *resp; + unsigned int i; +- int ret, isFound; ++ int ret = MPATH_PR_OTHER, isFound; + + if (!get_be64(mpp->reservation_key)) + { +@@ -754,7 +754,7 @@ int update_map_pr(struct multipath *mpp) + { + condlog(0,"%s: No available paths to check pr status", + mpp->alias); +- return MPATH_PR_OTHER; ++ goto out; + } + mpp->prflag = PRFLAG_UNSET; + ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); +@@ -762,15 +762,15 @@ int update_map_pr(struct multipath *mpp) + if (ret != MPATH_PR_SUCCESS ) + { + condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret); +- free(resp); +- return ret; ++ goto out; + } + ++ ret = MPATH_PR_SUCCESS; ++ + if (resp->prin_descriptor.prin_readkeys.additional_length == 0 ) + { + condlog(3,"%s: No key found. Device may not be registered. ", mpp->alias); +- free(resp); +- return MPATH_PR_SUCCESS; ++ goto out; + } + + condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, +@@ -795,6 +795,7 @@ int update_map_pr(struct multipath *mpp) + condlog(2, "%s: prflag flag set.", mpp->alias ); + } + ++out: + free(resp); +- return MPATH_PR_SUCCESS; ++ return ret; + } diff --git a/0011-RH-fixup-udev-rules-for-redhat.patch b/0016-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0011-RH-fixup-udev-rules-for-redhat.patch rename to 0016-RH-fixup-udev-rules-for-redhat.patch diff --git a/0012-RH-Remove-the-property-blacklist-exception-builtin.patch b/0017-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0012-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0017-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0013-RH-don-t-start-without-a-config-file.patch b/0018-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0013-RH-don-t-start-without-a-config-file.patch rename to 0018-RH-don-t-start-without-a-config-file.patch diff --git a/0014-RH-Fix-nvme-function-missing-argument.patch b/0019-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0014-RH-Fix-nvme-function-missing-argument.patch rename to 0019-RH-Fix-nvme-function-missing-argument.patch diff --git a/0015-RH-use-rpm-optflags-if-present.patch b/0020-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0015-RH-use-rpm-optflags-if-present.patch rename to 0020-RH-use-rpm-optflags-if-present.patch diff --git a/0016-RH-add-mpathconf.patch b/0021-RH-add-mpathconf.patch similarity index 100% rename from 0016-RH-add-mpathconf.patch rename to 0021-RH-add-mpathconf.patch diff --git a/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0018-RH-reset-default-find_mutipaths-value-to-off.patch b/0023-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0018-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0023-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 100% rename from 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch diff --git a/0021-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0026-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 100% rename from 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch diff --git a/0022-RH-compile-with-libreadline-support.patch b/0027-RH-compile-with-libreadline-support.patch similarity index 100% rename from 0022-RH-compile-with-libreadline-support.patch rename to 0027-RH-compile-with-libreadline-support.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2933cbd..a6fe03c 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.4 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -20,18 +20,23 @@ Patch0007: 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch Patch0008: 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch Patch0009: 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch Patch0010: 0010-libmultipath-bump-ABI-version-to-18.0.0.patch -Patch0011: 0011-RH-fixup-udev-rules-for-redhat.patch -Patch0012: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0013: 0013-RH-don-t-start-without-a-config-file.patch -Patch0014: 0014-RH-Fix-nvme-function-missing-argument.patch -Patch0015: 0015-RH-use-rpm-optflags-if-present.patch -Patch0016: 0016-RH-add-mpathconf.patch -Patch0017: 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0018: 0018-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0020: 0020-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0021: 0021-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0022: 0022-RH-compile-with-libreadline-support.patch +Patch0011: 0011-libmultipath-use-select_reload_action-in-select_acti.patch +Patch0012: 0012-libmultipath-select-resize-action-even-if-reload-is-.patch +Patch0013: 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch +Patch0014: 0014-libmultipath-keep-renames-from-stopping-other-multip.patch +Patch0015: 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch +Patch0016: 0016-RH-fixup-udev-rules-for-redhat.patch +Patch0017: 0017-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0018: 0018-RH-don-t-start-without-a-config-file.patch +Patch0019: 0019-RH-Fix-nvme-function-missing-argument.patch +Patch0020: 0020-RH-use-rpm-optflags-if-present.patch +Patch0021: 0021-RH-add-mpathconf.patch +Patch0022: 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0023: 0023-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0024: 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0025: 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0026: 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0027: 0027-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -240,12 +245,18 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Feb 2 2023 Benjamin Marzinski - 0.9.4-2 +- Update to the head of the upstream staging branch + * Patches 0011-0015 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0011-0022 are now patches 0016-0027 + * Thu Jan 26 2023 Benjamin Marzinski - 0.9.4-1 - Update to the head of the upstream staging branch - * Previous patches 0001-0032 are intlcude in the source tarball + * Previous patches 0001-0032 are included in the source tarball * Patches 0001-0010 are from the upstream staging branch - Rename redhat patches - * Previous patches 0033-0044 are not patches 0011-0022 + * Previous patches 0033-0044 are now patches 0011-0022 - Add dependency on libmount * Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 From 0761930b9e78736f3fe8d59b79f35a5754ea2929 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 16 May 2023 17:02:58 -0500 Subject: [PATCH 05/33] device-mapper-multipath-0.9.5-1 Update to the latest upstream release * Previous patches 0001-0015 are included in the source tarball Rename redhat patches * Previous patches 0016-0027 are now patches 0001-0012 --- .gitignore | 1 + ... 0001-RH-fixup-udev-rules-for-redhat.patch | 0 ...athd-make-pr-registration-consistent.patch | 159 ----- ...property-blacklist-exception-builtin.patch | 0 0002-libmultipath-make-prflag-an-enum.patch | 166 ----- ...RH-don-t-start-without-a-config-file.patch | 4 +- ...dle-no-active-paths-in-update_map_pr.patch | 152 ----- ...H-Fix-nvme-function-missing-argument.patch | 0 ...missing-newline-to-cli_del_map-reply.patch | 24 - ... 0005-RH-use-rpm-optflags-if-present.patch | 0 ...kip-extra-vector-work-in-remove_maps.patch | 33 - ...hconf.patch => 0006-RH-add-mpathconf.patch | 0 ...han-paths-if-coalesce_paths-frees-ne.patch | 41 -- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 8 +- ...path_valid-check-if-device-is-in-use.patch | 609 ------------------ ...-default-find_mutipaths-value-to-off.patch | 0 ...use-conf-timeout-for-updating-persis.patch | 55 -- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...hinfo-don-t-fail-for-devices-lacking.patch | 77 --- ...-parse_vpd_pg83-match-scsi_id-output.patch | 4 +- ...multipath-bump-ABI-version-to-18.0.0.patch | 26 - ...si-device-handlers-to-modules-load.d.patch | 0 ...-select_reload_action-in-select_acti.patch | 39 -- ...-RH-compile-with-libreadline-support.patch | 0 ...ect-resize-action-even-if-reload-is-.patch | 46 -- ...anup-ACT_CREATE-code-in-select_actio.patch | 68 -- ...p-renames-from-stopping-other-multip.patch | 186 ------ ...t-fix-resource-leak-in-update_map_pr.patch | 68 -- device-mapper-multipath.spec | 55 +- sources | 2 +- 30 files changed, 33 insertions(+), 1790 deletions(-) rename 0016-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (100%) delete mode 100644 0001-multipathd-make-pr-registration-consistent.patch rename 0017-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) delete mode 100644 0002-libmultipath-make-prflag-an-enum.patch rename 0018-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (98%) delete mode 100644 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch rename 0019-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch rename 0020-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (100%) delete mode 100644 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch rename 0021-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (100%) delete mode 100644 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch rename 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (96%) delete mode 100644 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch rename 0023-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch rename 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch rename 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (97%) delete mode 100644 0010-libmultipath-bump-ABI-version-to-18.0.0.patch rename 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (100%) delete mode 100644 0011-libmultipath-use-select_reload_action-in-select_acti.patch rename 0027-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (100%) delete mode 100644 0012-libmultipath-select-resize-action-even-if-reload-is-.patch delete mode 100644 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch delete mode 100644 0014-libmultipath-keep-renames-from-stopping-other-multip.patch delete mode 100644 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch diff --git a/.gitignore b/.gitignore index 1ca930c..18226b9 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.0.tgz /multipath-tools-0.9.3.tgz /multipath-tools-0.9.4.tgz +/multipath-tools-0.9.5.tgz diff --git a/0016-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0016-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch diff --git a/0001-multipathd-make-pr-registration-consistent.patch b/0001-multipathd-make-pr-registration-consistent.patch deleted file mode 100644 index 47c380a..0000000 --- a/0001-multipathd-make-pr-registration-consistent.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:10 -0600 -Subject: [PATCH] multipathd: make pr registration consistent - -multipathd was inconsistent on what it did with persistent reservations -when a multipath device was created. If a multipath device with a -configured reservation key was created during configure(), multipathd -would try to read the registered keys using an active path. If it saw a -matching key, it would set the prflag, but not attempt to register the -key on any of the other paths. This means that if a new path had -appeared while multipathd was not running, it wouldn't register the key -on this path. - -If the multipath device was created during ev_add_path(), multipathd -would used the added path to check if there was a matching key and if -there was, register the key only on the added path and then set the -prflag. This could be problematic if the device was created with -multiple paths, for instance because find_mutipaths was set to "yes" and -a second path just appeared. In this case, if the device happened to be -only registered on the second path, it would not get registered on the -first path. - -If the multipath device was added to multipathd during a call to -ev_add_map(), multipathd wouldn't set the prflag or register the key on -any paths. - -After a device was created with the prflag set, if a new path appeared -before the creation uevent, and multipathd was forced to delay adding -it, when it finally updated the multipath device, the key would be -registered on all paths, fixing any paths missed during creation. -However, if a new path appeared after the creation uevent, the key would -only be registered on that new path. Any paths that were missed on -creation would stay missed. - -persistent key registration needs to be handled consistently. This -patch does so by making sure that however a multipath device is added to -multipathd, it will check to see if the configured key is registered. If -it is, multipathd will set the prflag and register the key on all the -currently active paths. - -When a new path is added, multipathd will use it to check for active -keys, as before. But if it finds a matching key and prflag isn't -currently set, it will register the key on all paths. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 43 +++++++++++++++++++++++++++++-------------- - 1 file changed, 29 insertions(+), 14 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 1e1b254f..f7212d7b 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -586,13 +586,26 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { - return false; - } - -+static void -+pr_register_active_paths(struct multipath *mpp) -+{ -+ unsigned int i, j; -+ struct path *pp; -+ struct pathgroup *pgp; -+ -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) -+ mpath_pr_event_handle(pp); -+ } -+ } -+} -+ - static int - update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - { - int retries = 3; - char *params __attribute__((cleanup(cleanup_charp))) = NULL; -- struct path *pp; -- int i; - - retry: - condlog(4, "%s: updating new map", mpp->alias); -@@ -609,15 +622,6 @@ retry: - - mpp->action = ACT_RELOAD; - -- if (mpp->prflag) { -- vector_foreach_slot(mpp->paths, pp, i) { -- if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { -- /* persistent reservation check*/ -- mpath_pr_event_handle(pp); -- } -- } -- } -- - if (setup_map(mpp, ¶ms, vecs)) { - condlog(0, "%s: failed to setup new map in update", mpp->alias); - retries = -1; -@@ -643,6 +647,11 @@ fail: - - sync_map_state(mpp); - -+ if (!mpp->prflag) -+ update_map_pr(mpp); -+ if (mpp->prflag) -+ pr_register_active_paths(mpp); -+ - if (retries < 0) - condlog(0, "%s: failed reload in new map update", mpp->alias); - return 0; -@@ -1191,6 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int start_waiter = 0; - int ret; - int ro; -+ unsigned char prflag = 0; - - /* - * need path UID to go any further -@@ -1234,6 +1244,8 @@ rescan: - - verify_paths(mpp); - mpp->action = ACT_RELOAD; -+ prflag = mpp->prflag; -+ mpath_pr_event_handle(pp); - } else { - if (!should_multipath(pp, vecs->pathvec, vecs->mpvec)) { - orphan_path(pp, "only one path"); -@@ -1252,9 +1264,6 @@ rescan: - goto fail; /* leave path added to pathvec */ - } - -- /* persistent reservation check*/ -- mpath_pr_event_handle(pp); -- - /* ro check - if new path is ro, force map to be ro as well */ - ro = sysfs_get_ro(pp); - if (ro == 1) -@@ -1319,6 +1328,10 @@ rescan: - sync_map_state(mpp); - - if (retries >= 0) { -+ if (start_waiter) -+ update_map_pr(mpp); -+ if (mpp->prflag && !prflag) -+ pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); - return 0; -@@ -2852,6 +2865,8 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) - if (remember_wwid(mpp->wwid) == 1) - trigger_paths_udev_change(mpp, true); - update_map_pr(mpp); -+ if (mpp->prflag) -+ pr_register_active_paths(mpp); - } - - /* diff --git a/0017-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0017-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0002-libmultipath-make-prflag-an-enum.patch b/0002-libmultipath-make-prflag-an-enum.patch deleted file mode 100644 index 304f731..0000000 --- a/0002-libmultipath-make-prflag-an-enum.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:11 -0600 -Subject: [PATCH] libmultipath: make prflag an enum - -In preparation for a future patch, make prflag an enum, and change the -reply of cli_getprstatus() to a string. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist_int.c | 2 +- - libmultipath/structs.h | 8 +++++++- - multipathd/cli_handlers.c | 17 +++++++++-------- - multipathd/main.c | 14 +++++++------- - 4 files changed, 24 insertions(+), 17 deletions(-) - -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index 6924b379..a84d9474 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -783,7 +783,7 @@ int update_map_pr(struct multipath *mpp) - - if (isFound) - { -- mpp->prflag = 1; -+ mpp->prflag = PRFLAG_SET; - condlog(2, "%s: prflag flag set.", mpp->alias ); - } - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 9e2c1ab0..f2265300 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -375,6 +375,12 @@ struct path { - - typedef int (pgpolicyfn) (struct multipath *, vector); - -+ -+enum prflag_value { -+ PRFLAG_UNSET, -+ PRFLAG_SET, -+}; -+ - struct multipath { - char wwid[WWID_SIZE]; - char alias_old[WWID_SIZE]; -@@ -449,7 +455,7 @@ struct multipath { - int prkey_source; - struct be64 reservation_key; - uint8_t sa_flags; -- unsigned char prflag; -+ int prflag; - int all_tg_pt; - struct gen_multipath generic_mp; - bool fpin_must_reload; -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index e65fb75c..7ee2729f 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1277,6 +1277,10 @@ cli_shutdown (void * v, struct strbuf *reply, void * data) - static int - cli_getprstatus (void * v, struct strbuf *reply, void * data) - { -+ static const char * const prflag_str[] = { -+ [PRFLAG_UNSET] = "unset\n", -+ [PRFLAG_SET] = "set\n", -+ }; - struct multipath * mpp; - struct vectors * vecs = (struct vectors *)data; - char * param = get_keyparam(v, KEY_MAP); -@@ -1287,10 +1291,7 @@ cli_getprstatus (void * v, struct strbuf *reply, void * data) - if (!mpp) - return 1; - -- condlog(3, "%s: prflag = %u", param, (unsigned int)mpp->prflag); -- -- if (print_strbuf(reply, "%d", mpp->prflag) < 0) -- return 1; -+ append_strbuf_str(reply, prflag_str[mpp->prflag]); - - condlog(3, "%s: reply = %s", param, get_strbuf_str(reply)); - -@@ -1310,8 +1311,8 @@ cli_setprstatus(void * v, struct strbuf *reply, void * data) - if (!mpp) - return 1; - -- if (!mpp->prflag) { -- mpp->prflag = 1; -+ if (mpp->prflag != PRFLAG_SET) { -+ mpp->prflag = PRFLAG_SET; - condlog(2, "%s: prflag set", param); - } - -@@ -1332,8 +1333,8 @@ cli_unsetprstatus(void * v, struct strbuf *reply, void * data) - if (!mpp) - return 1; - -- if (mpp->prflag) { -- mpp->prflag = 0; -+ if (mpp->prflag != PRFLAG_UNSET) { -+ mpp->prflag = PRFLAG_UNSET; - condlog(2, "%s: prflag unset", param); - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index f7212d7b..722235c7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -647,9 +647,9 @@ fail: - - sync_map_state(mpp); - -- if (!mpp->prflag) -+ if (mpp->prflag == PRFLAG_UNSET) - update_map_pr(mpp); -- if (mpp->prflag) -+ if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); - - if (retries < 0) -@@ -1200,7 +1200,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int start_waiter = 0; - int ret; - int ro; -- unsigned char prflag = 0; -+ unsigned char prflag = PRFLAG_UNSET; - - /* - * need path UID to go any further -@@ -1330,7 +1330,7 @@ rescan: - if (retries >= 0) { - if (start_waiter) - update_map_pr(mpp); -- if (mpp->prflag && !prflag) -+ if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) - pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); -@@ -2492,7 +2492,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - } - - if (newstate == PATH_UP || newstate == PATH_GHOST) { -- if (pp->mpp->prflag) { -+ if (pp->mpp->prflag == PRFLAG_SET) { - /* - * Check Persistent Reservation. - */ -@@ -2865,7 +2865,7 @@ configure (struct vectors * vecs, enum force_reload_types reload_type) - if (remember_wwid(mpp->wwid) == 1) - trigger_paths_udev_change(mpp, true); - update_map_pr(mpp); -- if (mpp->prflag) -+ if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); - } - -@@ -3840,7 +3840,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) - { - condlog(0,"%s: Reservation registration failed. Error: %d", pp->dev, ret); - } -- mpp->prflag = 1; -+ mpp->prflag = PRFLAG_SET; - - free(param); - out: diff --git a/0018-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 98% rename from 0018-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index c957e2f..e6e03b4 100644 --- a/0018-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -57,7 +57,7 @@ index 87947469..0dc89c16 100644 enum devtypes { DEV_NONE, diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in -index 8d3cf33a..5c4447a2 100644 +index 6f123760..70b69a06 100644 --- a/multipath/multipath.rules.in +++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" @@ -82,7 +82,7 @@ index bdf102eb..a16a0bd5 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index aec62dbb..d76f94f9 100644 +index 5a9cde12..311f49c7 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket diff --git a/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch b/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch deleted file mode 100644 index 59dd10f..0000000 --- a/0003-multipathd-handle-no-active-paths-in-update_map_pr.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:12 -0600 -Subject: [PATCH] multipathd: handle no active paths in update_map_pr - -When a multipath device is first created, if it has a reservation key -configured, update_map_pr() will check for a matching key on the active -paths. If there were no active paths to check with, multipathd was -leaving mpp->prflag in PRFLAG_UNSET, as if there were no matching keys. -It's possible that when update_map_pr() is called, all the paths will be -in the PATH_PENDING state because the checkers haven't completed yet. In -this case, multipathd was treating the device as having no registered -keys without ever checking. - -To solve this, multipath devices now start with prflag = PRFLAG_UNKNOWN. -It will remain in this state until multipathd actually tries to get the -registered keys down a path. If the map is in this state, it will check -newly active paths, and if it finds a matching key, it will register -the key down all active paths. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist_int.c | 8 ++++++++ - libmultipath/structs.h | 1 + - multipathd/cli_handlers.c | 1 + - multipathd/main.c | 19 ++++++++++++++----- - 4 files changed, 24 insertions(+), 5 deletions(-) - -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index a84d9474..8b52b746 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -738,6 +738,7 @@ int update_map_pr(struct multipath *mpp) - if (!get_be64(mpp->reservation_key)) - { - /* Nothing to do. Assuming pr mgmt feature is disabled*/ -+ mpp->prflag = PRFLAG_UNSET; - condlog(4, "%s: reservation_key not set in multipath.conf", - mpp->alias); - return MPATH_PR_SUCCESS; -@@ -749,6 +750,13 @@ int update_map_pr(struct multipath *mpp) - condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias); - return MPATH_PR_OTHER; - } -+ if (count_active_paths(mpp) == 0) -+ { -+ condlog(0,"%s: No available paths to check pr status", -+ mpp->alias); -+ return MPATH_PR_OTHER; -+ } -+ mpp->prflag = PRFLAG_UNSET; - ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); - - if (ret != MPATH_PR_SUCCESS ) -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index f2265300..e2294323 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -377,6 +377,7 @@ typedef int (pgpolicyfn) (struct multipath *, vector); - - - enum prflag_value { -+ PRFLAG_UNKNOWN, - PRFLAG_UNSET, - PRFLAG_SET, - }; -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 7ee2729f..ec5db1b8 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1278,6 +1278,7 @@ static int - cli_getprstatus (void * v, struct strbuf *reply, void * data) - { - static const char * const prflag_str[] = { -+ [PRFLAG_UNKNOWN] = "unknown\n", - [PRFLAG_UNSET] = "unset\n", - [PRFLAG_SET] = "set\n", - }; -diff --git a/multipathd/main.c b/multipathd/main.c -index 722235c7..bdeffe76 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -647,7 +647,7 @@ fail: - - sync_map_state(mpp); - -- if (mpp->prflag == PRFLAG_UNSET) -+ if (mpp->prflag != PRFLAG_SET) - update_map_pr(mpp); - if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); -@@ -1330,7 +1330,7 @@ rescan: - if (retries >= 0) { - if (start_waiter) - update_map_pr(mpp); -- if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) -+ if (mpp->prflag == PRFLAG_SET && prflag != PRFLAG_SET) - pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); -@@ -2492,13 +2492,17 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - } - - if (newstate == PATH_UP || newstate == PATH_GHOST) { -- if (pp->mpp->prflag == PRFLAG_SET) { -+ if (pp->mpp->prflag != PRFLAG_UNSET) { -+ int prflag = pp->mpp->prflag; - /* - * Check Persistent Reservation. - */ - condlog(2, "%s: checking persistent " - "reservation registration", pp->dev); - mpath_pr_event_handle(pp); -+ if (pp->mpp->prflag == PRFLAG_SET && -+ prflag != PRFLAG_SET) -+ pr_register_active_paths(pp->mpp); - } - } - -@@ -3788,6 +3792,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) - goto out; - } - -+ mpp->prflag = PRFLAG_UNSET; - ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp, 0); - if (ret != MPATH_PR_SUCCESS ) - { -@@ -3858,12 +3863,12 @@ int mpath_pr_event_handle(struct path *pp) - struct multipath * mpp; - - if (pp->bus != SYSFS_BUS_SCSI) -- return 0; -+ goto no_pr; - - mpp = pp->mpp; - - if (!get_be64(mpp->reservation_key)) -- return -1; -+ goto no_pr; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); -@@ -3876,4 +3881,8 @@ int mpath_pr_event_handle(struct path *pp) - pthread_attr_destroy(&attr); - rc = pthread_join(thread, NULL); - return 0; -+ -+no_pr: -+ pp->mpp->prflag = PRFLAG_UNSET; -+ return 0; - } diff --git a/0019-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0019-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch diff --git a/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch b/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch deleted file mode 100644 index 085fd70..0000000 --- a/0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:13 -0600 -Subject: [PATCH] multipathd: add missing newline to cli_del_map reply - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/cli_handlers.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index ec5db1b8..44bf43df 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -760,7 +760,7 @@ cli_del_map (void * v, struct strbuf *reply, void * data) - } - rc = ev_remove_map(param, alias, minor, vecs); - if (rc == 2) -- append_strbuf_str(reply, "delayed"); -+ append_strbuf_str(reply, "delayed\n"); - - free(alias); - return rc; diff --git a/0020-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0020-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch diff --git a/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch b/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch deleted file mode 100644 index ee08327..0000000 --- a/0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:14 -0600 -Subject: [PATCH] libmultipath: skip extra vector work in remove_maps - -Instead of repeatedly removing the first vector element, and shifting -the rest to fill in, call remove_map() without a vector, so it just -frees the devices. The vector will be completely cleaned up by -vector_free() immediately afterwards. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs_vec.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 5a618767..f3fdc5a6 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -392,10 +392,8 @@ remove_maps(struct vectors * vecs) - if (!vecs) - return; - -- vector_foreach_slot (vecs->mpvec, mpp, i) { -- remove_map(mpp, vecs->pathvec, vecs->mpvec); -- i--; -- } -+ vector_foreach_slot (vecs->mpvec, mpp, i) -+ remove_map(mpp, vecs->pathvec, NULL); - - vector_free(vecs->mpvec); - vecs->mpvec = NULL; diff --git a/0021-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 100% rename from 0021-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch diff --git a/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch b/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch deleted file mode 100644 index f545df7..0000000 --- a/0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:15 -0600 -Subject: [PATCH] libmultipath: orphan paths if coalesce_paths frees newmp - -If coalesce_paths() is called without a mpvec, it will free all the -multipath devices on newmp at the end. This will clear pp->mpp from the -path, but it doesn't completely unitialize them. cli_add_map() can call -coalsce_paths() this way, when adding a device that doesn't currently -exist. cli_add_map() first creates the device in the kernel, and then -calls ev_add_map() to add it to multipathd. If something goes wrong in -ev_add_map(), the paths will still be initialized, even though they're -orphans. - -Fix this by calling remove_map() to orphan the paths that belong to -the multipath devices being deleted by coalesce_paths(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e551047a..e689f8a7 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1273,8 +1273,11 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - ret = CP_OK; - out: - free(size_mismatch_seen); -- if (!mpvec) -- free_multipathvec(newmp, KEEP_PATHS); -+ if (!mpvec) { -+ vector_foreach_slot (newmp, mpp, i) -+ remove_map(mpp, vecs->pathvec, NULL); -+ vector_free(newmp); -+ } - return ret; - } - diff --git a/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 96% rename from 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index c98543b..714a1bb 100644 --- a/0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index b9f360b4..5eb752ee 100644 +index 90f940f1..3549740a 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -92,7 +92,7 @@ index b9f360b4..5eb752ee 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -840,7 +886,7 @@ main (int argc, char *argv[]) +@@ -842,7 +888,7 @@ main (int argc, char *argv[]) conf->force_sync = 1; if (atexit(cleanup_vecs)) condlog(1, "failed to register cleanup handler for vecs: %m"); @@ -101,7 +101,7 @@ index b9f360b4..5eb752ee 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -911,6 +957,10 @@ main (int argc, char *argv[]) +@@ -913,6 +959,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -138,7 +138,7 @@ index 88149d53..072a03ee 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index d76f94f9..bb5f383a 100644 +index 311f49c7..5324f4bc 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -17,6 +17,7 @@ ConditionVirtualization=!container diff --git a/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch b/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch deleted file mode 100644 index 6ffa6fc..0000000 --- a/0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch +++ /dev/null @@ -1,609 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 9 Nov 2022 21:20:58 +0100 -Subject: [PATCH] libmultipath: is_path_valid(): check if device is in use - -To check whether we will be able to add a given device can be part -of a multipath map, we have two tests in check_path_valid(): -released_to_systemd() and the O_EXCL test. The former isn't helpful -if "multipath -u" is called for the first time for a given device, -and the latter is only used in the "find_multipaths smart" case, because -actively opening the device with O_EXCL, even for a very short time, is prone -to races with other processes. - -It turns out that this may cause issues in some scenarios. We saw problems in -once case where "find_multipaths greedy" was used with a single -non-multipahted root disk and a very large number of multipath LUNs. -The root disk would first be classified as multipath device. multipathd -would try to create a map, fail (because the disk was mounted) and -trigger another uevent. But because of the very large number of multipath -devices, this event was queued up behind thousands of other events, and -the root device timed out eventually. - -While a simple workaround for the given problem would be proper blacklisting -or using a different find_multipaths mode, I am proposing a different -solution here. An additional test is added in is_path_valid() which -checks whether the given device is currently in use by 1. sysfs holders, -2. mounts (from /proc/self/mountinfo) or 3. swaps (from /proc/swaps). 2. -and 3. are similar to systemd's device detection after switching root. -This must not only be done for the device itself, but also for all its -partitions. For mountinfo and swaps, libmount is utilized. - -With this patch, "multipath -u" will make devices with mounted or otherwise -used partitions available to systemd early, without waiting for multipathd -to fail setting up the map and re-triggering an uevent. This should avoid -the issue described above even without blacklisting. The downside of it -is a longer runtime of "multipath -u" for almost all devices, in particular -for real multipath devices. The runtime required for the new checks was in the -order of 0.1ms-1ms in my tests. Moreover, there is a certain risk that devices may -wrongly classified as non-multipath because of transient mounts or holders -created by other processes. - -To make this code compile on older distributions, we need some additional -checks in create-config.mk. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 2 +- - create-config.mk | 11 +- - libmpathutil/libmpathutil.version | 6 + - libmpathutil/util.c | 12 + - libmpathutil/util.h | 2 + - libmultipath/Makefile | 2 +- - libmultipath/alias.c | 11 - - libmultipath/valid.c | 270 ++++++++++++++++++++++ - tests/Makefile | 2 +- - tests/valid.c | 48 ++++ - 10 files changed, 351 insertions(+), 15 deletions(-) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index abf17bf0..9e6c0e89 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -31,7 +31,7 @@ jobs: - sudo apt-get install --yes gcc - make perl-base pkg-config valgrind - libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev libmount-dev - - name: build - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) READLINE=${{ matrix.rl }} - - name: test -diff --git a/create-config.mk b/create-config.mk -index 2a95ec56..f128375f 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -23,7 +23,7 @@ check_cmd = $(shell \ - - # Check whether a function with name $1 has been declared in header file $2. - check_func = $(shell \ -- if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ -+ if grep -Eq "^(extern[[:blank:]]+)?[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \ - found=1; \ - status="yes"; \ - else \ -@@ -104,6 +104,15 @@ ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h - FPIN_SUPPORT = 1 - endif - -+libmount_h := $(shell $(PKGCONFIG) --variable=includedir mount)/libmount/libmount.h -+ifneq ($(call check_func,mnt_unref_cache,$(libmount_h)),0) -+ DEFINES += LIBMOUNT_HAS_MNT_UNREF_CACHE -+endif -+ -+ifneq ($(call check_func,mnt_table_parse_swaps,$(libmount_h)),0) -+ DEFINES += LIBMOUNT_SUPPORTS_SWAP -+endif -+ - ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0) - ANA_SUPPORT := 1 - endif -diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version -index 1238fc93..dd007be4 100644 ---- a/libmpathutil/libmpathutil.version -+++ b/libmpathutil/libmpathutil.version -@@ -133,3 +133,9 @@ LIBMPATHUTIL_1.1 { - global: - cleanup_fd_ptr; - } LIBMPATHUTIL_1.0; -+ -+LIBMPATHUTIL_1.2 { -+global: -+ cleanup_vector_free; -+ cleanup_fclose; -+} LIBMPATHUTIL_1.0; -diff --git a/libmpathutil/util.c b/libmpathutil/util.c -index 9662e1ed..92f25a50 100644 ---- a/libmpathutil/util.c -+++ b/libmpathutil/util.c -@@ -386,6 +386,18 @@ void cleanup_mutex(void *arg) - pthread_mutex_unlock(arg); - } - -+void cleanup_vector_free(void *arg) -+{ -+ if (arg) -+ vector_free((vector)arg); -+} -+ -+void cleanup_fclose(void *p) -+{ -+ if (p) -+ fclose(p); -+} -+ - struct bitfield *alloc_bitfield(unsigned int maxbit) - { - unsigned int n; -diff --git a/libmpathutil/util.h b/libmpathutil/util.h -index 75e20fd8..99a471d0 100644 ---- a/libmpathutil/util.h -+++ b/libmpathutil/util.h -@@ -48,6 +48,8 @@ int should_exit(void); - void cleanup_fd_ptr(void *arg); - void cleanup_free_ptr(void *arg); - void cleanup_mutex(void *arg); -+void cleanup_vector_free(void *arg); -+void cleanup_fclose(void *p); - - struct scandir_result { - struct dirent **di; -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index 3df851e2..61aa611f 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -7,7 +7,7 @@ DEVLIB := libmultipath.so - CPPFLAGS += -I$(mpathutildir) -I$(mpathcmddir) -I$(nvmedir) -D_GNU_SOURCE $(SYSTEMD_CPPFLAGS) - CFLAGS += $(LIB_CFLAGS) - LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \ -- -lurcu -laio $(SYSTEMD_LIBDEPS) -+ -lmount -lurcu -laio $(SYSTEMD_LIBDEPS) - - # object files referencing MULTIPATH_DIR or CONFIG_DIR - # they need to be recompiled for unit tests -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 05201224..c0139a2e 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -667,11 +667,6 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - return rc; - } - --static void cleanup_fclose(void *p) --{ -- fclose(p); --} -- - static int alias_compar(const void *p1, const void *p2) - { - const char *alias1 = (*(struct mpentry * const *)p1)->alias; -@@ -684,12 +679,6 @@ static int alias_compar(const void *p1, const void *p2) - return alias1 ? -1 : alias2 ? 1 : 0; - } - --static void cleanup_vector_free(void *arg) --{ -- if (arg) -- vector_free((vector)arg); --} -- - /* - * check_alias_settings(): test for inconsistent alias configuration - * -diff --git a/libmultipath/valid.c b/libmultipath/valid.c -index a6aa9215..d4dae3ed 100644 ---- a/libmultipath/valid.c -+++ b/libmultipath/valid.c -@@ -17,6 +17,8 @@ - #include - #include - #include -+#include -+#include - - #include "vector.h" - #include "config.h" -@@ -30,12 +32,271 @@ - #include "mpath_cmd.h" - #include "valid.h" - -+static int subdir_filter(const struct dirent *ent) -+{ -+ unsigned int j; -+ static char const *const skip[] = { -+ ".", -+ "..", -+ "holders", -+ "integrity", -+ "mq", -+ "power", -+ "queue", -+ "slaves", -+ "trace", -+ }; -+ -+ if (ent->d_type != DT_DIR) -+ return 0; -+ -+ for (j = 0; j < ARRAY_SIZE(skip); j++) -+ if (!strcmp(skip[j], ent->d_name)) -+ return 0; -+ return 1; -+} -+ -+static int read_partitions(const char *syspath, vector parts) -+{ -+ struct scandir_result sr = { .n = 0 }; -+ char path[PATH_MAX], *last; -+ char *prop; -+ int i; -+ -+ strlcpy(path, syspath, sizeof(path)); -+ sr.n = scandir(path, &sr.di, subdir_filter, NULL); -+ if (sr.n == -1) -+ return -errno; -+ -+ pthread_cleanup_push_cast(free_scandir_result, &sr); -+ -+ /* parts[0] is the whole disk */ -+ if ((prop = strdup(strrchr(path, '/') + 1)) != NULL) { -+ if (vector_alloc_slot(parts)) -+ vector_set_slot(parts, prop); -+ else -+ free(prop); -+ } -+ -+ last = path + strlen(path); -+ for (i = 0; i < sr.n; i++) { -+ struct stat st; -+ -+ /* only add dirs that have the "partition" attribute */ -+ snprintf(last, sizeof(path) - (last - path), "/%s/partition", -+ sr.di[i]->d_name); -+ -+ if (stat(path, &st) == 0 && -+ (prop = strdup(sr.di[i]->d_name)) != NULL) { -+ if (vector_alloc_slot(parts)) -+ vector_set_slot(parts, prop); -+ else -+ free(prop); -+ } -+ } -+ -+ pthread_cleanup_pop(1); -+ return 0; -+} -+ -+static int no_dots(const struct dirent *ent) -+{ -+ const char *name = ent->d_name; -+ -+ if (name[0] == '.' && -+ (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) -+ return 0; -+ return 1; -+} -+ -+static int check_holders(const char *syspath) -+{ -+ struct scandir_result __attribute__((cleanup(free_scandir_result))) -+ sr = { .n = 0 }; -+ -+ sr.n = scandir(syspath, &sr.di, no_dots, NULL); -+ if (sr.n > 0) -+ condlog(4, "%s: found holders under %s", __func__, syspath); -+ return sr.n; -+} -+ -+static int check_all_holders(const struct _vector *parts) -+{ -+ char syspath[PATH_MAX]; -+ const char *sysname; -+ unsigned int j; -+ -+ if (VECTOR_SIZE(parts) == 0) -+ return 0; -+ -+ if (safe_sprintf(syspath, "/sys/class/block/%s/holders", -+ (const char *)VECTOR_SLOT(parts, 0))) -+ return -EOVERFLOW; -+ -+ if (check_holders(syspath) > 0) -+ return 1; -+ -+ j = 1; -+ vector_foreach_slot_after(parts, sysname, j) { -+ if (safe_sprintf(syspath, "/sys/class/block/%s/%s/holders", -+ (const char *)VECTOR_SLOT(parts, 0), sysname)) -+ return -EOVERFLOW; -+ if (check_holders(syspath) > 0) -+ return 1; -+ } -+ return 0; -+} -+ -+static void cleanup_table(void *arg) -+{ -+ if (arg) -+ mnt_free_table((struct libmnt_table *)arg); -+} -+ -+static void cleanup_cache(void *arg) -+{ -+ if (arg) -+#ifdef LIBMOUNT_HAS_MNT_UNREF_CACHE -+ mnt_unref_cache((struct libmnt_cache *)arg); -+#else -+ mnt_free_cache((struct libmnt_cache *)arg); -+#endif -+} -+ -+/* -+ * Passed a vector of partitions and a libmount table, -+ * check if any of the partitions in the vector is referenced in the table. -+ * Note that mnt_table_find_srcpath() also resolves mounts by symlinks. -+ */ -+static int check_mnt_table(const struct _vector *parts, -+ struct libmnt_table *tbl, -+ const char *table_name) -+{ -+ unsigned int i; -+ const char *sysname; -+ char devpath[PATH_MAX]; -+ -+ vector_foreach_slot(parts, sysname, i) { -+ if (!safe_sprintf(devpath, "/dev/%s", sysname) && -+ mnt_table_find_srcpath(tbl, devpath, -+ MNT_ITER_FORWARD) != NULL) { -+ condlog(4, "%s: found %s in %s", __func__, -+ sysname, table_name); -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+static int check_mountinfo(const struct _vector *parts) -+{ -+ static const char mountinfo[] = "/proc/self/mountinfo"; -+ struct libmnt_table *tbl; -+ struct libmnt_cache *cache; -+ FILE *stream; -+ int used = 0, ret; -+ -+ tbl = mnt_new_table(); -+ if (!tbl ) -+ return -errno; -+ -+ pthread_cleanup_push(cleanup_table, tbl); -+ cache = mnt_new_cache(); -+ if (cache) { -+ pthread_cleanup_push(cleanup_cache, cache); -+ if (mnt_table_set_cache(tbl, cache) == 0) { -+ stream = fopen(mountinfo, "r"); -+ if (stream != NULL) { -+ pthread_cleanup_push(cleanup_fclose, stream); -+ ret = mnt_table_parse_stream(tbl, stream, mountinfo); -+ pthread_cleanup_pop(1); -+ -+ if (ret == 0) -+ used = check_mnt_table(parts, tbl, -+ "mountinfo"); -+ } -+ } -+ pthread_cleanup_pop(1); -+ } -+ pthread_cleanup_pop(1); -+ return used; -+} -+ -+#ifdef LIBMOUNT_SUPPORTS_SWAP -+static int check_swaps(const struct _vector *parts) -+{ -+ struct libmnt_table *tbl; -+ struct libmnt_cache *cache; -+ int used = 0, ret; -+ -+ tbl = mnt_new_table(); -+ if (!tbl ) -+ return -errno; -+ -+ pthread_cleanup_push(cleanup_table, tbl); -+ cache = mnt_new_cache(); -+ if (cache) { -+ pthread_cleanup_push(cleanup_cache, cache); -+ if (mnt_table_set_cache(tbl, cache) == 0) { -+ ret = mnt_table_parse_swaps(tbl, NULL); -+ if (ret == 0) -+ used = check_mnt_table(parts, tbl, "swaps"); -+ } -+ pthread_cleanup_pop(1); -+ } -+ pthread_cleanup_pop(1); -+ return used; -+} -+#else -+static int check_swaps(const struct _vector *parts __attribute__((unused))) -+{ -+ return 0; -+} -+#endif -+ -+ -+/* -+ * Given a block device, check if the device itself or any of its -+ * partitions is in use -+ * - by sysfs holders (e.g. LVM) -+ * - mounted according to /proc/self/mountinfo -+ * - used as swap -+ */ -+static int is_device_in_use(struct udev_device *udevice) -+{ -+ const char *syspath; -+ vector parts; -+ int used = 0, ret; -+ -+ syspath = udev_device_get_syspath(udevice); -+ if (!syspath) -+ return -ENOMEM; -+ -+ parts = vector_alloc(); -+ if (!parts) -+ return -ENOMEM; -+ -+ pthread_cleanup_push_cast(free_strvec, parts); -+ if ((ret = read_partitions(syspath, parts)) == 0) -+ used = check_all_holders(parts) > 0 || -+ check_mountinfo(parts) > 0 || -+ check_swaps(parts) > 0; -+ pthread_cleanup_pop(1); -+ -+ if (ret < 0) -+ return ret; -+ -+ condlog(3, "%s: %s is %sin use", __func__, syspath, used ? "" : "not "); -+ return used; -+} -+ - int - is_path_valid(const char *name, struct config *conf, struct path *pp, - bool check_multipathd) - { - int r; - int fd; -+ const char *prop; - - if (!pp || !name || !conf) - return PATH_IS_ERROR; -@@ -80,6 +341,10 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, - if (!pp->udev) - return PATH_IS_ERROR; - -+ prop = udev_device_get_property_value(pp->udev, "DEVTYPE"); -+ if (prop == NULL || strcmp(prop, "disk")) -+ return PATH_IS_NOT_VALID; -+ - r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); - if (r == PATHINFO_SKIPPED) - return PATH_IS_NOT_VALID; -@@ -96,6 +361,11 @@ is_path_valid(const char *name, struct config *conf, struct path *pp, - return PATH_IS_ERROR; - } - -+ if ((conf->find_multipaths == FIND_MULTIPATHS_GREEDY || -+ conf->find_multipaths == FIND_MULTIPATHS_SMART) && -+ is_device_in_use(pp->udev) > 0) -+ return PATH_IS_NOT_VALID; -+ - if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) - return PATH_IS_VALID; - -diff --git a/tests/Makefile b/tests/Makefile -index 860338b2..1648ab9d 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -55,7 +55,7 @@ vpd-test_LIBDEPS := -ludev -lpthread -ldl - alias-test_TESTDEPS := test-log.o - alias-test_LIBDEPS := -lpthread -ldl - valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o --valid-test_LIBDEPS := -ludev -lpthread -ldl -+valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl - devt-test_LIBDEPS := -ludev - mpathvalid-test_LIBDEPS := -ludev -lpthread -ldl - mpathvalid-test_OBJDEPS := $(mpathvaliddir)/mpath_valid.o -diff --git a/tests/valid.c b/tests/valid.c -index 398b771e..70329324 100644 ---- a/tests/valid.c -+++ b/tests/valid.c -@@ -83,6 +83,13 @@ struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *u - return NULL; - } - -+/* For devtype check */ -+const char *__wrap_udev_device_get_property_value(struct udev_device *udev_device, const char *property) -+{ -+ check_expected(property); -+ return mock_ptr_type(char *); -+} -+ - /* For the "hidden" check in pathinfo() */ - const char *__wrap_udev_device_get_sysattr_value(struct udev_device *udev_device, - const char *sysattr) -@@ -97,6 +104,12 @@ int __wrap_add_foreign(struct udev_device *udev_device) - return mock_type(int); - } - -+/* For is_device_used() */ -+const char *__wrap_udev_device_get_sysname(struct udev_device *udev_device) -+{ -+ return mock_ptr_type(char *); -+} -+ - /* called from pathinfo() */ - int __wrap_filter_devnode(struct config *conf, const struct _vector *elist, - const char *vendor, const char * product, const char *dev) -@@ -165,6 +178,11 @@ int __wrap_is_failed_wwid(const char *wwid) - return ret; - } - -+const char *__wrap_udev_device_get_syspath(struct udev_device *udevice) -+{ -+ return mock_ptr_type(char *); -+} -+ - int __wrap_check_wwids_file(char *wwid, int write_wwid) - { - bool passed = mock_type(bool); -@@ -225,6 +243,8 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, - will_return(__wrap_udev_device_new_from_subsystem_sysname, true); - will_return(__wrap_udev_device_new_from_subsystem_sysname, - name); -+ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); -+ will_return(__wrap_udev_device_get_property_value, "disk"); - if (stage == STAGE_GET_UDEV_DEVICE) - return; - if (stage == STAGE_PATHINFO_REAL) { -@@ -250,6 +270,10 @@ static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, - return; - will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); - will_return(__wrap_is_failed_wwid, wwid); -+ /* avoid real is_device_in_use() check */ -+ if (conf.find_multipaths == FIND_MULTIPATHS_GREEDY || -+ conf.find_multipaths == FIND_MULTIPATHS_SMART) -+ will_return(__wrap_udev_device_get_syspath, NULL); - if (stage == STAGE_IS_FAILED) - return; - will_return(__wrap_check_wwids_file, false); -@@ -347,6 +371,30 @@ static void test_check_multipathd(void **state) - assert_int_equal(is_path_valid(name, &conf, &pp, true), - PATH_IS_ERROR); - assert_string_equal(pp.dev, name); -+ -+ /* test pass because connect succeeded. succeed getting udev. Wrong DEVTYPE */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); -+ will_return(__wrap_udev_device_get_property_value, "partition"); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ -+ /* test pass because connect succeeded. succeed getting udev. Bad DEVTYPE */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ expect_string(__wrap_udev_device_get_property_value, property, "DEVTYPE"); -+ will_return(__wrap_udev_device_get_property_value, NULL); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); - } - - static void test_pathinfo(void **state) diff --git a/0023-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0023-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch b/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch deleted file mode 100644 index 9f3dcb2..0000000 --- a/0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 2 Jan 2023 12:39:36 +0100 -Subject: [PATCH] libmpathpersist: use conf->timeout for updating persistent - reservations - -On systems with many LUNs, multipathd may fail to respond within the -default timeout to a "setprkey" command because the vecs lock is held -by the path checker. Honor the globally configured uxsock timeout in -libmpathpersist. - -Reported-by: boposki (github.com/opensvc/multipath-tools/pull/58) -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_updatepr.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c -index 4529a82b..36bd777e 100644 ---- a/libmpathpersist/mpath_updatepr.c -+++ b/libmpathpersist/mpath_updatepr.c -@@ -14,6 +14,9 @@ - #include - #include "debug.h" - #include "mpath_cmd.h" -+#include "vector.h" -+#include "globals.h" -+#include "config.h" - #include "uxsock.h" - #include "mpathpr.h" - -@@ -24,6 +27,12 @@ static int do_update_pr(char *alias, char *cmd, char *key) - char str[256]; - char *reply; - int ret = 0; -+ int timeout; -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ timeout = conf->uxsock_timeout; -+ put_multipath_config(conf); - - fd = mpath_connect(); - if (fd == -1) { -@@ -41,7 +50,7 @@ static int do_update_pr(char *alias, char *cmd, char *key) - mpath_disconnect(fd); - return -1; - } -- ret = recv_packet(fd, &reply, DEFAULT_REPLY_TIMEOUT); -+ ret = recv_packet(fd, &reply, timeout); - if (ret < 0) { - condlog(2, "%s: message=%s recv error=%d", alias, str, errno); - ret = -1; diff --git a/0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch b/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch deleted file mode 100644 index fe7f001..0000000 --- a/0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 30 Nov 2022 21:07:45 +0100 -Subject: [PATCH] libmultipath: pathinfo: don't fail for devices lacking - INQUIRY properties -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some SAS devices (e.g. Seagate factory recertified 'white label' drives) may -come with the Vendor field blank. This causes Multipath to fail to -complete the discovery of those devices. - -Such devices violate the SCSI Spec. From the SPC-6, §6.7.2: -"The T10 VENDOR IDENTIFICATION field contains eight bytes of left-aligned -ASCII data (see 4.3.1) identifying the manufacturer of the logical unit. The -T10 vendor identification shall be one assigned by INCITS.". - -But as we don't identify WWIDs by vendor and product, we don't need to discard -these devices right away. We can go ahead fingers crossed, and hope that the -the other VPD pages for the device are correct. - -We obviously can't look up reasonable device properties for such devices in -our hwtable. It would be up to the user to deal with that. - -Reported by: Allyn Malventano (github.com/opensvc/multipath-tools/issues/56) -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 22 +++++++++++++--------- - 1 file changed, 13 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index d9ee2cb9..67ac0e6d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1472,6 +1472,7 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - { - struct udev_device *parent; - const char *attr_path = NULL; -+ static const char unknown[] = "UNKNOWN"; - - parent = pp->udev; - while (parent) { -@@ -1492,19 +1493,22 @@ scsi_sysfs_pathinfo (struct path *pp, const struct _vector *hwtable) - if (!attr_path || pp->sg_id.host_no == -1) - return PATHINFO_FAILED; - -- if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) -- return PATHINFO_FAILED;; -- -+ if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0) { -+ condlog(1, "%s: broken device without vendor ID", pp->dev); -+ strlcpy(pp->vendor_id, unknown, SCSI_VENDOR_SIZE); -+ } - condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id); - -- if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) -- return PATHINFO_FAILED;; -- -+ if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0) { -+ condlog(1, "%s: broken device without product ID", pp->dev); -+ strlcpy(pp->product_id, unknown, PATH_PRODUCT_SIZE); -+ } - condlog(3, "%s: product = %s", pp->dev, pp->product_id); - -- if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) -- return PATHINFO_FAILED;; -- -+ if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0) { -+ condlog(2, "%s: broken device without revision", pp->dev); -+ strlcpy(pp->rev, unknown, PATH_REV_SIZE); -+ } - condlog(3, "%s: rev = %s", pp->dev, pp->rev); - - /* diff --git a/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 97% rename from 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 824c747..4e0b116 100644 --- a/0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 67ac0e6d..7fdbc1c3 100644 +index 6865cd92..72825829 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, @@ -45,7 +45,7 @@ index 67ac0e6d..7fdbc1c3 100644 case 0x1: /* T-10 Vendor ID: Prio 2 */ diff --git a/tests/vpd.c b/tests/vpd.c -index a7d2092c..2366cfba 100644 +index 1b2d62d6..7309b5c5 100644 --- a/tests/vpd.c +++ b/tests/vpd.c @@ -231,11 +231,13 @@ static const char * const str_prefix[] = { diff --git a/0010-libmultipath-bump-ABI-version-to-18.0.0.patch b/0010-libmultipath-bump-ABI-version-to-18.0.0.patch deleted file mode 100644 index 0d9a3c1..0000000 --- a/0010-libmultipath-bump-ABI-version-to-18.0.0.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 25 Jan 2023 11:35:38 +0100 -Subject: [PATCH] libmultipath: bump ABI version to 18.0.0 - -Commit 6b81153 ("libmultipath: make prflag an enum") changed -the size and member offsets of struct multipath. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/libmultipath.version | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index faef2a2d..015623cc 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { - put_multipath_config; - }; - --LIBMULTIPATH_17.0.0 { -+LIBMULTIPATH_18.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; diff --git a/0026-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 100% rename from 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch diff --git a/0011-libmultipath-use-select_reload_action-in-select_acti.patch b/0011-libmultipath-use-select_reload_action-in-select_acti.patch deleted file mode 100644 index 05cc2ce..0000000 --- a/0011-libmultipath-use-select_reload_action-in-select_acti.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:18 -0600 -Subject: [PATCH] libmultipath: use select_reload_action in select_action - -Since we have a function to set the action to reload, use it. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e689f8a7..050b984a 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -729,9 +729,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - - if (force_reload) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RELOAD; -- condlog(3, "%s: set ACT_RELOAD (forced by user)", -- mpp->alias); -+ select_reload_action(mpp, "forced by user"); - return; - } - if (cmpp->size != mpp->size) { -@@ -744,9 +742,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - - if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RELOAD; -- condlog(3, "%s: set ACT_RELOAD (udev incomplete)", -- mpp->alias); -+ select_reload_action(mpp, "udev incomplete"); - return; - } - diff --git a/0027-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 100% rename from 0027-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch diff --git a/0012-libmultipath-select-resize-action-even-if-reload-is-.patch b/0012-libmultipath-select-resize-action-even-if-reload-is-.patch deleted file mode 100644 index 39518c4..0000000 --- a/0012-libmultipath-select-resize-action-even-if-reload-is-.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:19 -0600 -Subject: [PATCH] libmultipath: select resize action even if reload is forced - -The ACT_RESIZE action is the same as the ACT_RELOAD action, except that -it flushes outstanding IO because the device size is changing and -the new size might be too small for some of the outstanding IO. If we've -detected a size change, and a forced reload is requested, we still need -to flush the IO because the reload will change the device size. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 050b984a..6811e661 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -727,11 +727,6 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - return; - } - -- if (force_reload) { -- mpp->force_udev_reload = 1; -- select_reload_action(mpp, "forced by user"); -- return; -- } - if (cmpp->size != mpp->size) { - mpp->force_udev_reload = 1; - mpp->action = ACT_RESIZE; -@@ -740,6 +735,12 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - return; - } - -+ if (force_reload) { -+ mpp->force_udev_reload = 1; -+ select_reload_action(mpp, "forced by user"); -+ return; -+ } -+ - if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) { - mpp->force_udev_reload = 1; - select_reload_action(mpp, "udev incomplete"); diff --git a/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch b/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch deleted file mode 100644 index 3574bac..0000000 --- a/0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:20 -0600 -Subject: [PATCH] libmultipath: cleanup ACT_CREATE code in select_action - -Combine the two separate blocks that set ACT_CREATE into one. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 38 +++++++++++++++++--------------------- - 1 file changed, 17 insertions(+), 21 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 6811e661..e870e0f6 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -686,33 +686,29 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - if (mpp->need_reload || (cmpp && cmpp->need_reload)) - force_reload = 1; - -- if (!cmpp_by_name) { -- if (cmpp) { -- condlog(2, "%s: rename %s to %s", mpp->wwid, -- cmpp->alias, mpp->alias); -- strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); -- mpp->action = ACT_RENAME; -- if (force_reload) { -- mpp->force_udev_reload = 1; -- mpp->action = ACT_FORCERENAME; -- } -- return; -+ if (!cmpp) { -+ if (cmpp_by_name) { -+ condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", -+ mpp->wwid, mpp->alias, cmpp_by_name->wwid); -+ /* We can do this because wwid wasn't found */ -+ free(mpp->alias); -+ mpp->alias = strdup(mpp->wwid); - } - mpp->action = ACT_CREATE; -- condlog(3, "%s: set ACT_CREATE (map does not exist)", -- mpp->alias); -+ condlog(3, "%s: set ACT_CREATE (map does not exist%s)", -+ mpp->alias, cmpp_by_name ? ", name changed" : ""); - return; - } - -- if (!cmpp) { -- condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", -- mpp->wwid, mpp->alias, cmpp_by_name->wwid); -- /* We can do this because wwid wasn't found */ -- free(mpp->alias); -- mpp->alias = strdup(mpp->wwid); -- mpp->action = ACT_CREATE; -- condlog(3, "%s: set ACT_CREATE (map does not exist, name changed)", -+ if (!cmpp_by_name) { -+ condlog(2, "%s: rename %s to %s", mpp->wwid, cmpp->alias, - mpp->alias); -+ strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); -+ mpp->action = ACT_RENAME; -+ if (force_reload) { -+ mpp->force_udev_reload = 1; -+ mpp->action = ACT_FORCERENAME; -+ } - return; - } - diff --git a/0014-libmultipath-keep-renames-from-stopping-other-multip.patch b/0014-libmultipath-keep-renames-from-stopping-other-multip.patch deleted file mode 100644 index f597e61..0000000 --- a/0014-libmultipath-keep-renames-from-stopping-other-multip.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 13:34:21 -0600 -Subject: [PATCH] libmultipath: keep renames from stopping other multipath - actions - -If select_action() is called and a multipath device needs to be renamed, -the code currently checks if force_reload is set, and if so, does the -reload after the rename. But if force_reload isn't set, only the rename -happens, regardless of what other actions are needed. This can happen if -multipathd starts up and a device needs both a reload and a rename. - -Make multipath check for resize, reload, and switch pathgroup along with -rename, and do both if necessary. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 62 +++++++++++++++++----------------------- - libmultipath/configure.h | 4 ++- - 2 files changed, 30 insertions(+), 36 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e870e0f6..4a1c28bb 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -670,7 +670,8 @@ static bool is_udev_ready(struct multipath *cmpp) - static void - select_reload_action(struct multipath *mpp, const char *reason) - { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (%s)", mpp->alias, reason); - } - -@@ -681,6 +682,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - struct multipath * cmpp_by_name; - char * mpp_feat, * cmpp_feat; - -+ mpp->action = ACT_NOTHING; - cmpp = find_mp_by_wwid(curmp, mpp->wwid); - cmpp_by_name = find_mp_by_alias(curmp, mpp->alias); - if (mpp->need_reload || (cmpp && cmpp->need_reload)) -@@ -705,14 +707,8 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - mpp->alias); - strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); - mpp->action = ACT_RENAME; -- if (force_reload) { -- mpp->force_udev_reload = 1; -- mpp->action = ACT_FORCERENAME; -- } -- return; -- } -- -- if (cmpp != cmpp_by_name) { -+ /* don't return here. Check for other needed actions */ -+ } else if (cmpp != cmpp_by_name) { - condlog(2, "%s: unable to rename %s to %s (%s is used by %s)", - mpp->wwid, cmpp->alias, mpp->alias, - mpp->alias, cmpp_by_name->wwid); -@@ -720,12 +716,13 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - free(mpp->alias); - mpp->alias = strdup(cmpp->alias); - mpp->action = ACT_IMPOSSIBLE; -- return; -+ /* don't return here. Check for other needed actions */ - } - - if (cmpp->size != mpp->size) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RESIZE; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RESIZE_RENAME : -+ ACT_RESIZE; - condlog(3, "%s: set ACT_RESIZE (size change)", - mpp->alias); - return; -@@ -801,14 +798,14 @@ void select_action (struct multipath *mpp, const struct _vector *curmp, - return; - } - if (cmpp->nextpg != mpp->bestpg) { -- mpp->action = ACT_SWITCHPG; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME : -+ ACT_SWITCHPG; - condlog(3, "%s: set ACT_SWITCHPG (next path group change)", - mpp->alias); - return; - } -- mpp->action = ACT_NOTHING; -- condlog(3, "%s: set ACT_NOTHING (map unchanged)", -- mpp->alias); -+ if (mpp->action == ACT_NOTHING) -+ condlog(3, "%s: set ACT_NOTHING (map unchanged)", mpp->alias); - return; - } - -@@ -909,6 +906,17 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - } - } - -+ if (mpp->action == ACT_RENAME || mpp->action == ACT_SWITCHPG_RENAME || -+ mpp->action == ACT_RELOAD_RENAME || -+ mpp->action == ACT_RESIZE_RENAME) { -+ conf = get_multipath_config(); -+ pthread_cleanup_push(put_multipath_config, conf); -+ r = dm_rename(mpp->alias_old, mpp->alias, -+ conf->partition_delim, mpp->skip_kpartx); -+ pthread_cleanup_pop(1); -+ if (r == DOMAP_FAIL) -+ return r; -+ } - switch (mpp->action) { - case ACT_REJECT: - case ACT_NOTHING: -@@ -916,6 +924,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - return DOMAP_EXIST; - - case ACT_SWITCHPG: -+ case ACT_SWITCHPG_RENAME: - dm_switchgroup(mpp->alias, mpp->bestpg); - /* - * we may have avoided reinstating paths because there where in -@@ -942,6 +951,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RELOAD: -+ case ACT_RELOAD_RENAME: - sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; -@@ -949,6 +959,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RESIZE: -+ case ACT_RESIZE_RENAME: - sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; -@@ -956,29 +967,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RENAME: -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- r = dm_rename(mpp->alias_old, mpp->alias, -- conf->partition_delim, mpp->skip_kpartx); -- pthread_cleanup_pop(1); -- break; -- -- case ACT_FORCERENAME: -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- r = dm_rename(mpp->alias_old, mpp->alias, -- conf->partition_delim, mpp->skip_kpartx); -- pthread_cleanup_pop(1); -- if (r) { -- sysfs_set_max_sectors_kb(mpp, 1); -- if (mpp->ghost_delay_tick > 0 && -- pathcount(mpp, PATH_UP)) -- mpp->ghost_delay_tick = 0; -- r = dm_addmap_reload(mpp, params, 0); -- } - break; - - default: -+ r = DOMAP_FAIL; - break; - } - -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 2bf73e65..9d935db3 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -18,9 +18,11 @@ enum actions { - ACT_RENAME, - ACT_CREATE, - ACT_RESIZE, -- ACT_FORCERENAME, -+ ACT_RELOAD_RENAME, - ACT_DRY_RUN, - ACT_IMPOSSIBLE, -+ ACT_RESIZE_RENAME, -+ ACT_SWITCHPG_RENAME, - }; - - /* diff --git a/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch b/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch deleted file mode 100644 index 866080f..0000000 --- a/0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 Feb 2023 09:20:35 +0100 -Subject: [PATCH] libmpathpersist: fix resource leak in update_map_pr() - -The "no available paths" case would leak the memory resp points to. -Found by coverity. - -Fixes: 50e2c16 ("multipathd: handle no active paths in update_map_pr") - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist_int.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c -index 8b52b746..178c2f54 100644 ---- a/libmpathpersist/mpath_persist_int.c -+++ b/libmpathpersist/mpath_persist_int.c -@@ -733,7 +733,7 @@ int update_map_pr(struct multipath *mpp) - int noisy=0; - struct prin_resp *resp; - unsigned int i; -- int ret, isFound; -+ int ret = MPATH_PR_OTHER, isFound; - - if (!get_be64(mpp->reservation_key)) - { -@@ -754,7 +754,7 @@ int update_map_pr(struct multipath *mpp) - { - condlog(0,"%s: No available paths to check pr status", - mpp->alias); -- return MPATH_PR_OTHER; -+ goto out; - } - mpp->prflag = PRFLAG_UNSET; - ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); -@@ -762,15 +762,15 @@ int update_map_pr(struct multipath *mpp) - if (ret != MPATH_PR_SUCCESS ) - { - condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret); -- free(resp); -- return ret; -+ goto out; - } - -+ ret = MPATH_PR_SUCCESS; -+ - if (resp->prin_descriptor.prin_readkeys.additional_length == 0 ) - { - condlog(3,"%s: No key found. Device may not be registered. ", mpp->alias); -- free(resp); -- return MPATH_PR_SUCCESS; -+ goto out; - } - - condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, -@@ -795,6 +795,7 @@ int update_map_pr(struct multipath *mpp) - condlog(2, "%s: prflag flag set.", mpp->alias ); - } - -+out: - free(resp); -- return MPATH_PR_SUCCESS; -+ return ret; - } diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index a6fe03c..ca8b8aa 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,42 +1,27 @@ Name: device-mapper-multipath -Version: 0.9.4 -Release: 2%{?dist} +Version: 0.9.5 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.4.tar.gz -o multipath-tools-0.9.4.tgz -Source0: multipath-tools-0.9.4.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.5.tar.gz -o multipath-tools-0.9.5.tgz +Source0: multipath-tools-0.9.5.tgz Source1: multipath.conf -Patch0001: 0001-multipathd-make-pr-registration-consistent.patch -Patch0002: 0002-libmultipath-make-prflag-an-enum.patch -Patch0003: 0003-multipathd-handle-no-active-paths-in-update_map_pr.patch -Patch0004: 0004-multipathd-add-missing-newline-to-cli_del_map-reply.patch -Patch0005: 0005-libmultipath-skip-extra-vector-work-in-remove_maps.patch -Patch0006: 0006-libmultipath-orphan-paths-if-coalesce_paths-frees-ne.patch -Patch0007: 0007-libmultipath-is_path_valid-check-if-device-is-in-use.patch -Patch0008: 0008-libmpathpersist-use-conf-timeout-for-updating-persis.patch -Patch0009: 0009-libmultipath-pathinfo-don-t-fail-for-devices-lacking.patch -Patch0010: 0010-libmultipath-bump-ABI-version-to-18.0.0.patch -Patch0011: 0011-libmultipath-use-select_reload_action-in-select_acti.patch -Patch0012: 0012-libmultipath-select-resize-action-even-if-reload-is-.patch -Patch0013: 0013-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch -Patch0014: 0014-libmultipath-keep-renames-from-stopping-other-multip.patch -Patch0015: 0015-libmpathpersist-fix-resource-leak-in-update_map_pr.patch -Patch0016: 0016-RH-fixup-udev-rules-for-redhat.patch -Patch0017: 0017-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0018: 0018-RH-don-t-start-without-a-config-file.patch -Patch0019: 0019-RH-Fix-nvme-function-missing-argument.patch -Patch0020: 0020-RH-use-rpm-optflags-if-present.patch -Patch0021: 0021-RH-add-mpathconf.patch -Patch0022: 0022-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0023: 0023-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0024: 0024-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0025: 0025-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0026: 0026-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0027: 0027-RH-compile-with-libreadline-support.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -123,7 +108,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.4 -p1 +%autosetup -n multipath-tools-0.9.5 -p1 cp %{SOURCE1} . %build @@ -245,6 +230,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue May 16 2023 Benjamin Marzinski - 0.9.5-1 +- Update to the latest upstream release + * Previous patches 0001-0015 are included in the source tarball +- Rename redhat patches + * Previous patches 0016-0027 are now patches 0001-0012 + * Thu Feb 2 2023 Benjamin Marzinski - 0.9.4-2 - Update to the head of the upstream staging branch * Patches 0011-0015 are from the upstream staging branch diff --git a/sources b/sources index 462cab6..ece6ffe 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.4.tgz) = 5e0dcea610fc215e345444c04453a38f39c73e493c2bc53f6b3a90cd701266aabdf7c4693dfc321099af836d0019bf27355e265ad5db5deff48f8bb94ed4719d +SHA512 (multipath-tools-0.9.5.tgz) = 39c2e5d45542c6076eb3b17b9994629b4c1f74347aa43e0119001fa2d07d3a606fd5e617962906a11b313afb37a115bd8eec2ef24447e980e61b5900625f9146 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From d88fe4b9560ffa9bd363b3e344f82e0705cbd169 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jul 2023 17:19:23 +0000 Subject: [PATCH 06/33] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index ca8b8aa..268e4b9 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.5 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -230,6 +230,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 19 2023 Fedora Release Engineering - 0.9.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue May 16 2023 Benjamin Marzinski - 0.9.5-1 - Update to the latest upstream release * Previous patches 0001-0015 are included in the source tarball From e5eddaae1a3d86387da90d35f7c9fddac02d03a4 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 22 Sep 2023 15:29:43 -0500 Subject: [PATCH 07/33] device-mapper-multipath-0.9.6-1 Update to the head of the upstream staging branch Rename redhat patches * Previous patches 0001-0012 are now patches 0041-0052 Add 0053-RH-Add-mpathcleanup.patch * add mpathcleanup program --- .gitignore | 1 + ...fs_set_scsi_tmo-do-nothing-for-ACT_D.patch | 51 + ...libmultipath-add-alias_already_taken.patch | 75 + ...fy-use_existing_alias-and-get_user_f.patch | 207 ++ ...er-allocate-an-alias-that-s-already-.patch | 101 + ...kup_binding-add-comment-about-the-al.patch | 61 + ...test-simplify-debugging-for-condlog-.patch | 35 + ...tests-add-tests-for-get_user_friendl.patch | 493 +++++ ...test-consistent-use-of-macros-in-ali.patch | 365 ++++ ...tests-convert-mock_-failed-used-_ali.patch | 246 +++ ...test-use-mock_bindings_file-consiste.patch | 500 +++++ ...-global-variable-for-current-binding.patch | 109 ++ ...ame-fix_bindings_file-to-update_bind.patch | 40 + ...lias.c-move-bindings-related-code-up.patch | 285 +++ ...ate_bindings_file-take-filename-argu.patch | 61 + ...ate_bindings_file-use-a-single-write.patch | 59 + ...ate_bindings_file-don-t-log-temp-fil.patch | 29 + ...path-alias.c-factor-out-read_binding.patch | 94 + ...libmultipath-keep-bindings-in-memory.patch | 545 ++++++ ...ultipath-tools-tests-fix-alias-tests.patch | 1698 +++++++++++++++++ ...get_uuid-return-emtpy-UUID-for-non-e.patch | 53 + ...dapt-to-new-semantics-of-dm_get_uuid.patch | 158 ++ ...th-sort-aliases-by-length-and-strcmp.patch | 98 + ...tests-fix-alias-test-after-sort-orde.patch | 90 + ...plify-get_free_id-assuming-total-ord.patch | 122 ++ ...tests-adapt-alias-tests-for-total-or.patch | 203 ++ ...tests-add-test-for-ordering-of-bindi.patch | 275 +++ ...-bindings-file-with-inotify-timestam.patch | 597 ++++++ ...tests-mock-pthread_mutex_-lock-unloc.patch | 102 + ...Makefile-sanitize-paths-for-configur.patch | 73 + ...add-compile-time-configuration-for-e.patch | 58 + ...man-pages-generate-with-correct-path.patch | 366 ++++ ...-Makefile-fix-bug-in-install-section.patch | 25 + ...README.md-improve-documentation-for-.patch | 75 + ...nt-built-in-values-for-deprecated-op.patch | 55 + 0035-multipath-add-a-missing-newline.patch | 25 + ...allow-prefixes-with-and-w-o-trailing.patch | 66 + ...recate-bindings_file-wwids_file-prke.patch | 897 +++++++++ ...id-Warray-bounds-error-in-uatomic-op.patch | 158 ++ 0039-multipath-tools-fix-spelling.patch | 52 + ...-support-to-handle-FPIN-Li-events-fo.patch | 300 +++ ... 0041-RH-fixup-udev-rules-for-redhat.patch | 14 +- ...property-blacklist-exception-builtin.patch | 41 +- ...RH-don-t-start-without-a-config-file.patch | 50 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0045-RH-use-rpm-optflags-if-present.patch | 14 +- ...hconf.patch => 0046-RH-add-mpathconf.patch | 14 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 26 +- ...-default-find_mutipaths-value-to-off.patch | 2 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 4 +- ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- 0053-RH-Add-mpathcleanup.patch | 186 ++ device-mapper-multipath.spec | 83 +- sources | 2 +- 56 files changed, 9256 insertions(+), 89 deletions(-) create mode 100644 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch create mode 100644 0002-libmultipath-add-alias_already_taken.patch create mode 100644 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch create mode 100644 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch create mode 100644 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch create mode 100644 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch create mode 100644 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch create mode 100644 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch create mode 100644 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch create mode 100644 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch create mode 100644 0011-libmultipath-add-global-variable-for-current-binding.patch create mode 100644 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch create mode 100644 0013-libmultipath-alias.c-move-bindings-related-code-up.patch create mode 100644 0014-libmultipath-update_bindings_file-take-filename-argu.patch create mode 100644 0015-libmultipath-update_bindings_file-use-a-single-write.patch create mode 100644 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch create mode 100644 0017-libmultipath-alias.c-factor-out-read_binding.patch create mode 100644 0018-libmultipath-keep-bindings-in-memory.patch create mode 100644 0019-multipath-tools-tests-fix-alias-tests.patch create mode 100644 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch create mode 100644 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch create mode 100644 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch create mode 100644 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch create mode 100644 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch create mode 100644 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch create mode 100644 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch create mode 100644 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch create mode 100644 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch create mode 100644 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch create mode 100644 0030-multipath-tools-add-compile-time-configuration-for-e.patch create mode 100644 0031-multipath-tools-man-pages-generate-with-correct-path.patch create mode 100644 0032-libdmmp-Makefile-fix-bug-in-install-section.patch create mode 100644 0033-multipath-tools-README.md-improve-documentation-for-.patch create mode 100644 0034-libmultipath-print-built-in-values-for-deprecated-op.patch create mode 100644 0035-multipath-add-a-missing-newline.patch create mode 100644 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch create mode 100644 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch create mode 100644 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch create mode 100644 0039-multipath-tools-fix-spelling.patch create mode 100644 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch rename 0001-RH-fixup-udev-rules-for-redhat.patch => 0041-RH-fixup-udev-rules-for-redhat.patch (89%) rename 0002-RH-Remove-the-property-blacklist-exception-builtin.patch => 0042-RH-Remove-the-property-blacklist-exception-builtin.patch (79%) rename 0003-RH-don-t-start-without-a-config-file.patch => 0043-RH-don-t-start-without-a-config-file.patch (71%) rename 0004-RH-Fix-nvme-function-missing-argument.patch => 0044-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0005-RH-use-rpm-optflags-if-present.patch => 0045-RH-use-rpm-optflags-if-present.patch (83%) rename 0006-RH-add-mpathconf.patch => 0046-RH-add-mpathconf.patch (98%) rename 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (87%) rename 0008-RH-reset-default-find_mutipaths-value-to-off.patch => 0048-RH-reset-default-find_mutipaths-value-to-off.patch (96%) rename 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (95%) rename 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (98%) rename 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) rename 0012-RH-compile-with-libreadline-support.patch => 0052-RH-compile-with-libreadline-support.patch (96%) create mode 100644 0053-RH-Add-mpathcleanup.patch diff --git a/.gitignore b/.gitignore index 18226b9..75c4abc 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.3.tgz /multipath-tools-0.9.4.tgz /multipath-tools-0.9.5.tgz +/multipath-tools-0.9.6.tgz diff --git a/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch b/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch new file mode 100644 index 0000000..9b8a486 --- /dev/null +++ b/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 16:21:43 +0200 +Subject: [PATCH] libmultipath: sysfs_set_scsi_tmo: do nothing for ACT_DRY_RUN + +"multipath -d" might change sysfs timeouts of SCSI devices. +Make sure it doesn't. + +Signed-off-by: Martin Wilck +Cc: Jehan Singh +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 4 ++-- + libmultipath/discovery.c | 3 +++ + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 9513baae..029fbbd2 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1193,13 +1193,13 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + + if (cmpp) + mpp->queue_mode = cmpp->queue_mode; ++ if (cmd == CMD_DRY_RUN && mpp->action == ACT_UNDEF) ++ mpp->action = ACT_DRY_RUN; + if (setup_map(mpp, ¶ms, vecs)) { + remove_map(mpp, vecs->pathvec, NULL); + continue; + } + +- if (cmd == CMD_DRY_RUN) +- mpp->action = ACT_DRY_RUN; + if (mpp->action == ACT_UNDEF) + select_action(mpp, curmp, + force_reload == FORCE_RELOAD_YES ? 1 : 0); +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index e4de48e7..84ce5fe7 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -857,6 +857,9 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) + bool warn_dev_loss = false; + bool warn_fast_io_fail = false; + ++ if (mpp->action == ACT_DRY_RUN || mpp->action == ACT_REJECT) ++ return 0; ++ + if (mpp->no_path_retry > 0) { + uint64_t no_path_retry_tmo = + (uint64_t)mpp->no_path_retry * conf->checkint; diff --git a/0002-libmultipath-add-alias_already_taken.patch b/0002-libmultipath-add-alias_already_taken.patch new file mode 100644 index 0000000..8ed3c7b --- /dev/null +++ b/0002-libmultipath-add-alias_already_taken.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 21:36:11 +0200 +Subject: [PATCH] libmultipath: add alias_already_taken() + +Factor out a trivial helper function. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 32 +++++++++++++++++++------------- + 1 file changed, 19 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index c0139a2e..83ded886 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "util.h" +@@ -109,30 +110,35 @@ scan_devname(const char *alias, const char *prefix) + return n; + } + +-static int +-id_already_taken(int id, const char *prefix, const char *map_wwid) ++static bool alias_already_taken(const char *alias, const char *map_wwid) + { +- STRBUF_ON_STACK(buf); +- const char *alias; +- +- if (append_strbuf_str(&buf, prefix) < 0 || +- format_devname(&buf, id) < 0) +- return 0; + +- alias = get_strbuf_str(&buf); + if (dm_map_present(alias)) { + char wwid[WWID_SIZE]; + + /* If both the name and the wwid match, then it's fine.*/ + if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && + strncmp(map_wwid, wwid, sizeof(wwid)) == 0) +- return 0; +- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias); +- return 1; ++ return false; ++ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", ++ map_wwid, alias); ++ return true; + } +- return 0; ++ return false; + } + ++static bool id_already_taken(int id, const char *prefix, const char *map_wwid) ++{ ++ STRBUF_ON_STACK(buf); ++ const char *alias; ++ ++ if (append_strbuf_str(&buf, prefix) < 0 || ++ format_devname(&buf, id) < 0) ++ return false; ++ ++ alias = get_strbuf_str(&buf); ++ return alias_already_taken(alias, map_wwid); ++} + + /* + * Returns: 0 if matching entry in WWIDs file found diff --git a/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch b/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch new file mode 100644 index 0000000..5beb1fe --- /dev/null +++ b/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch @@ -0,0 +1,207 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 22:00:58 +0200 +Subject: [PATCH] libmultipath: unify use_existing_alias() and + get_user_friendly_alias() + +These functions are only called from select_alias(). The logic +is more obvious when unified in a single function. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 82 ++++++++++++------------------------------ + libmultipath/alias.h | 9 ++--- + libmultipath/propsel.c | 19 +++++----- + 3 files changed, 34 insertions(+), 76 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 83ded886..68f5d848 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -329,13 +329,13 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) + return alias; + } + +-char * +-use_existing_alias (const char *wwid, const char *file, const char *alias_old, +- const char *prefix, int bindings_read_only) ++char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, ++ const char *prefix, bool bindings_read_only) + { + char *alias = NULL; + int id = 0; + int fd, can_write; ++ bool new_binding = false; + char buff[WWID_SIZE]; + FILE *f; + +@@ -349,6 +349,10 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + close(fd); + return NULL; + } ++ ++ if (!strlen(alias_old)) ++ goto new_alias; ++ + /* lookup the binding. if it exists, the wwid will be in buff + * either way, id contains the id for the alias + */ +@@ -358,14 +362,14 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + /* if buff is our wwid, it's already + * allocated correctly + */ +- if (strcmp(buff, wwid) == 0) ++ if (strcmp(buff, wwid) == 0) { + alias = strdup(alias_old); +- else { +- alias = NULL; ++ goto out; ++ } else { + condlog(0, "alias %s already bound to wwid %s, cannot reuse", + alias_old, buff); ++ goto new_alias; + } +- goto out; + } + + id = lookup_binding(f, wwid, &alias, NULL, 0); +@@ -377,8 +381,15 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + + /* allocate the existing alias in the bindings file */ + id = scan_devname(alias_old, prefix); +- if (id <= 0) +- goto out; ++ ++new_alias: ++ if (id <= 0) { ++ id = lookup_binding(f, wwid, &alias, prefix, 1); ++ if (id <= 0) ++ goto out; ++ else ++ new_binding = true; ++ } + + if (fflush(f) != 0) { + condlog(0, "cannot fflush bindings file stream : %s", +@@ -388,8 +399,9 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, + + if (can_write && !bindings_read_only) { + alias = allocate_binding(fd, wwid, id, prefix); +- condlog(0, "Allocated existing binding [%s] for WWID [%s]", +- alias, wwid); ++ if (alias && !new_binding) ++ condlog(2, "Allocated existing binding [%s] for WWID [%s]", ++ alias, wwid); + } + + out: +@@ -399,54 +411,6 @@ out: + return alias; + } + +-char * +-get_user_friendly_alias(const char *wwid, const char *file, const char *prefix, +- int bindings_read_only) +-{ +- char *alias; +- int fd, id; +- FILE *f; +- int can_write; +- +- if (!wwid || *wwid == '\0') { +- condlog(3, "Cannot find binding for empty WWID"); +- return NULL; +- } +- +- fd = open_file(file, &can_write, bindings_file_header); +- if (fd < 0) +- return NULL; +- +- f = fdopen(fd, "r"); +- if (!f) { +- condlog(0, "cannot fdopen on bindings file descriptor : %s", +- strerror(errno)); +- close(fd); +- return NULL; +- } +- +- id = lookup_binding(f, wwid, &alias, prefix, 1); +- if (id < 0) { +- fclose(f); +- return NULL; +- } +- +- pthread_cleanup_push(free, alias); +- +- if (fflush(f) != 0) { +- condlog(0, "cannot fflush bindings file stream : %s", +- strerror(errno)); +- free(alias); +- alias = NULL; +- } else if (can_write && !bindings_read_only && !alias) +- alias = allocate_binding(fd, wwid, id, prefix); +- +- fclose(f); +- +- pthread_cleanup_pop(0); +- return alias; +-} +- + int + get_user_friendly_wwid(const char *alias, char *buff, const char *file) + { +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index dbc950c4..fa332233 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -2,13 +2,10 @@ + #define _ALIAS_H + + int valid_alias(const char *alias); +-char *get_user_friendly_alias(const char *wwid, const char *file, +- const char *prefix, +- int bindings_readonly); + int get_user_friendly_wwid(const char *alias, char *buff, const char *file); +-char *use_existing_alias (const char *wwid, const char *file, +- const char *alias_old, +- const char *prefix, int bindings_read_only); ++char *get_user_friendly_alias(const char *wwid, const char *file, ++ const char *alias_old, ++ const char *prefix, bool bindings_read_only); + + struct config; + int check_alias_settings(const struct config *); +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index d6bce129..354e883f 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -401,19 +401,16 @@ int select_alias(struct config *conf, struct multipath * mp) + + select_alias_prefix(conf, mp); + +- if (strlen(mp->alias_old) > 0) { +- mp->alias = use_existing_alias(mp->wwid, conf->bindings_file, +- mp->alias_old, mp->alias_prefix, +- conf->bindings_read_only); +- memset (mp->alias_old, 0, WWID_SIZE); +- origin = "(setting: using existing alias)"; +- } ++ mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, ++ mp->alias_old, mp->alias_prefix, ++ conf->bindings_read_only); + +- if (mp->alias == NULL) { +- mp->alias = get_user_friendly_alias(mp->wwid, +- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); ++ if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) ++ origin = "(setting: using existing alias)"; ++ else if (mp->alias) + origin = "(setting: user_friendly_name)"; +- } ++ memset (mp->alias_old, 0, WWID_SIZE); ++ + out: + if (mp->alias == NULL) { + mp->alias = strdup(mp->wwid); diff --git a/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch b/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch new file mode 100644 index 0000000..3d05b85 --- /dev/null +++ b/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 22:23:29 +0200 +Subject: [PATCH] libmultipath: never allocate an alias that's already taken + +If the bindings file is changed in a way that multipathd can't handle +(e.g. by swapping the aliases of two maps), multipathd must not try +to re-use an alias that is already used by another map. Creating +or renaming a map with such an alias will fail. We already avoid +this for some cases, but not for all. Fix it. + +Signed-off-by: Martin Wilck +Cc: David Bond +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 31 +++++++++++++++++++++++-------- + tests/alias.c | 2 +- + 2 files changed, 24 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 68f5d848..3e3dfe98 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -120,7 +120,7 @@ static bool alias_already_taken(const char *alias, const char *map_wwid) + if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && + strncmp(map_wwid, wwid, sizeof(wwid)) == 0) + return false; +- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", ++ condlog(3, "%s: alias '%s' already taken, reselecting alias", + map_wwid, alias); + return true; + } +@@ -359,12 +359,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al + rlookup_binding(f, buff, alias_old); + + if (strlen(buff) > 0) { +- /* if buff is our wwid, it's already +- * allocated correctly +- */ ++ /* If buff is our wwid, it's already allocated correctly. */ + if (strcmp(buff, wwid) == 0) { + alias = strdup(alias_old); + goto out; ++ + } else { + condlog(0, "alias %s already bound to wwid %s, cannot reuse", + alias_old, buff); +@@ -372,19 +371,35 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al + } + } + +- id = lookup_binding(f, wwid, &alias, NULL, 0); ++ /* ++ * Look for an existing alias in the bindings file. ++ * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. ++ */ ++ lookup_binding(f, wwid, &alias, NULL, 0); + if (alias) { +- condlog(3, "Use existing binding [%s] for WWID [%s]", +- alias, wwid); ++ if (alias_already_taken(alias, wwid)) { ++ free(alias); ++ alias = NULL; ++ } else ++ condlog(3, "Use existing binding [%s] for WWID [%s]", ++ alias, wwid); + goto out; + } + +- /* allocate the existing alias in the bindings file */ ++ /* alias_old is already taken by our WWID, update bindings file. */ + id = scan_devname(alias_old, prefix); + + new_alias: + if (id <= 0) { ++ /* ++ * no existing alias was provided, or allocating it ++ * failed. Try a new one. ++ */ + id = lookup_binding(f, wwid, &alias, prefix, 1); ++ if (id == 0 && alias_already_taken(alias, wwid)) { ++ free(alias); ++ alias = NULL; ++ } + if (id <= 0) + goto out; + else +diff --git a/tests/alias.c b/tests/alias.c +index 3ca6c28b..11f209e0 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -398,7 +398,7 @@ static void mock_self_alias(const char *alias, const char *wwid) + will_return(__wrap_dm_get_uuid, wwid); + } + +-#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, but not in bindings file. reselecting alias\n" ++#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" + + static void mock_failed_alias(const char *alias, char *msg) + { diff --git a/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch b/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch new file mode 100644 index 0000000..71d077a --- /dev/null +++ b/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 22:30:16 +0200 +Subject: [PATCH] libmultipath: lookup_binding: add comment about the algorithm + +When I read this code, I always get confused. Adding comments to +explain the algorithm. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 35 +++++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 3e3dfe98..9e9ac563 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -172,6 +172,41 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + alias = strtok_r(buf, " \t", &saveptr); + if (!alias) /* blank line */ + continue; ++ ++ /* ++ * Find an unused index - explanation of the algorithm ++ * ++ * ID: 1 = mpatha, 2 = mpathb, ... ++ * ++ * We assume the bindings are unsorted. The only constraint ++ * is that no ID occurs more than once. IDs that occur in the ++ * bindings are called "used". ++ * ++ * We call the list 1,2,3,..., exactly in this order, the list ++ * of "expected" IDs. The variable "id" always holds the next ++ * "expected" ID, IOW the last "expected" ID encountered plus 1. ++ * Thus all IDs below "id" are known to be used. However, at the ++ * end of the loop, the value of "id" isn't necessarily unused. ++ * ++ * "smallest_bigger_id" is the smallest used ID that was ++ * encountered while it was larger than the next "expected" ID ++ * at that iteration. Let X be some used ID. If all IDs below X ++ * are used and encountered in the right sequence before X, "id" ++ * will be > X when the loop ends. Otherwise, X was encountered ++ * "out of order", the condition (X > id) holds when X is ++ * encountered, and "smallest_bigger_id" will be set to X; i.e. ++ * it will be less or equal than X when the loop ends. ++ * ++ * At the end of the loop, (id < smallest_bigger_id) means that ++ * the value of "id" had been encountered neither in order nor ++ * out of order, and is thus unused. (id >= smallest_bigger_id) ++ * means that "id"'s value is in use. In this case, we play safe ++ * and use "biggest_id + 1" as the next value to try. ++ * ++ * biggest_id is always > smallest_bigger_id, except in the ++ * "perfectly ordered" case. ++ */ ++ + curr_id = scan_devname(alias, prefix); + if (curr_id == id) { + if (id < INT_MAX) diff --git a/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch b/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch new file mode 100644 index 0000000..a206358 --- /dev/null +++ b/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Aug 2023 22:56:41 +0200 +Subject: [PATCH] multipath-tools test: simplify debugging for condlog mismatch + +If there's a mismatch between expected and actual log message, +print both messages. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/test-log.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tests/test-log.c b/tests/test-log.c +index c1745872..63516999 100644 +--- a/tests/test-log.c ++++ b/tests/test-log.c +@@ -16,12 +16,14 @@ void __wrap_dlog (int prio, const char * fmt, ...) + va_list ap; + char *expected; + +- check_expected(prio); + va_start(ap, fmt); + vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); + va_end(ap); + fprintf(stderr, "%s(%d): %s", __func__, prio, buff); + expected = mock_ptr_type(char *); ++ if (memcmp(expected, buff, strlen(expected))) ++ fprintf(stderr, "%s(expected): %s", __func__, expected); ++ check_expected(prio); + assert_memory_equal(buff, expected, strlen(expected)); + } + diff --git a/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch b/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch new file mode 100644 index 0000000..f829db4 --- /dev/null +++ b/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch @@ -0,0 +1,493 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 23 Aug 2023 22:57:29 +0200 +Subject: [PATCH] multipath-tools tests: add tests for + get_user_friendly_alias() + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 441 insertions(+) + +diff --git a/tests/alias.c b/tests/alias.c +index 11f209e0..7e443b06 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -81,6 +81,35 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + return ret; + } + ++#define TEST_FDNO 1234 ++#define TEST_FPTR ((FILE *) 0xaffe) ++ ++int __wrap_open_file(const char *file, int *can_write, const char *header) ++{ ++ int cw = mock_type(int); ++ ++ *can_write = cw; ++ return TEST_FDNO; ++} ++ ++FILE *__wrap_fdopen(int fd, const char *mode) ++{ ++ assert_int_equal(fd, TEST_FDNO); ++ return TEST_FPTR; ++} ++ ++int __wrap_fflush(FILE *f) ++{ ++ assert_ptr_equal(f, TEST_FPTR); ++ return 0; ++} ++ ++int __wrap_fclose(FILE *f) ++{ ++ assert_ptr_equal(f, TEST_FPTR); ++ return 0; ++} ++ + /* strbuf wrapper for the old format_devname() */ + static int __format_devname(char *name, int id, size_t len, const char *prefix) + { +@@ -399,6 +428,22 @@ static void mock_self_alias(const char *alias, const char *wwid) + } + + #define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" ++#define NOMATCH_STR(alias_str) ("No matching alias [" alias_str "] in bindings file.\n") ++#define FOUND_STR(alias_str, wwid_str) \ ++ "Found matching wwid [" wwid_str "] in bindings file." \ ++ " Setting alias to " alias_str "\n" ++#define FOUND_ALIAS_STR(alias_str, wwid_str) \ ++ "Found matching alias [" alias_str "] in bindings file." \ ++ " Setting wwid to " wwid_str "\n" ++#define NOMATCH_WWID_STR(wwid_str) ("No matching wwid [" wwid_str "] in bindings file.\n") ++#define NEW_STR(alias_str, wwid_str) ("Created new binding [" alias_str "] for WWID [" wwid_str "]\n") ++#define EXISTING_STR(alias_str, wwid_str) ("Use existing binding [" alias_str "] for WWID [" wwid_str "]\n") ++#define ALLOC_STR(alias_str, wwid_str) ("Allocated existing binding [" alias_str "] for WWID [" wwid_str "]\n") ++#define BINDING_STR(alias_str, wwid_str) (alias_str " " wwid_str "\n") ++#define BOUND_STR(alias_str, wwid_str) ("alias "alias_str " already bound to wwid " wwid_str ", cannot reuse") ++#define ERR_STR(alias_str, wwid_str) ("ERROR: old alias [" alias_str "] for wwid [" wwid_str "] is used by other map\n") ++#define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") ++#define NOMORE_STR "no more available user_friendly_names\n" + + static void mock_failed_alias(const char *alias, char *msg) + { +@@ -421,6 +466,24 @@ static void mock_used_alias(const char *alias, char *msg) + expect_condlog(3, msg); + } + ++static void mock_bindings_file(const char *content, int match_line) ++{ ++ static char cnt[1024]; ++ char *token; ++ int i; ++ ++ assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); ++ ++ for (token = strtok(cnt, "\n"), i = 0; ++ token && *token; ++ token = strtok(NULL, "\n"), i++) { ++ will_return(__wrap_fgets, token); ++ if (match_line == i) ++ return; ++ } ++ will_return(__wrap_fgets, NULL); ++} ++ + static void lb_empty(void **state) + { + int rc; +@@ -1147,6 +1210,382 @@ static int test_allocate_binding(void) + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++#define mock_allocate_binding(alias, wwid) \ ++ do { \ ++ static const char ln[] = BINDING_STR(alias, wwid); \ ++ \ ++ will_return(__wrap_lseek, 0); \ ++ expect_value(__wrap_write, count, strlen(ln)); \ ++ expect_string(__wrap_write, buf, ln); \ ++ will_return(__wrap_write, strlen(ln)); \ ++ expect_condlog(3, NEW_STR(alias, wwid)); \ ++ } while (0) ++ ++static void gufa_empty_new_rw(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHa", "WWID0"); ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_empty_new_ro_1(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, false); ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_empty_new_ro_2(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, NULL); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_match_a_unused(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_unused_alias("MPATHa"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_match_a_self(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_self_alias("MPATHa", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_match_a_used(void **state) { ++ char *alias; ++ ++ will_return(__wrap_open_file, true); ++ ++ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_nomatch_a_c(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHc WWID2", ++ -1); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); ++ ++ mock_allocate_binding("MPATHb", "WWID1"); ++ ++ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHb"); ++ free(alias); ++} ++ ++static void gufa_nomatch_c_a(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHc WWID2\n" ++ "MPATHa WWID0", ++ -1); ++ mock_unused_alias("MPATHb"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); ++ ++ mock_allocate_binding("MPATHb", "WWID1"); ++ ++ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHb"); ++ free(alias); ++} ++ ++static void gufa_nomatch_c_b(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHc WWID2\n" ++ "MPATHb WWID1\n", ++ -1); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHa", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_nomatch_c_b_used(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHc WWID2\n" ++ "MPATHb WWID1", ++ -1); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID4")); ++ mock_unused_alias("MPATHd"); ++ ++ mock_allocate_binding("MPATHd", "WWID4"); ++ ++ alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHd"); ++ free(alias); ++} ++ ++static void gufa_nomatch_b_f_a(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHf WWID6\n" ++ "MPATHa WWID0\n", ++ -1); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); ++ mock_unused_alias("MPATHg"); ++ ++ mock_allocate_binding("MPATHg", "WWID7"); ++ ++ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHg"); ++ free(alias); ++} ++ ++static void gufa_old_empty(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ /* rlookup_binding for ALIAS */ ++ will_return(__wrap_fgets, NULL); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ /* lookup_binding */ ++ will_return(__wrap_fgets, NULL); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHz", "WWID0"); ++ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHz"); ++ free(alias); ++} ++ ++static void gufa_old_match(void **state) { ++ char *alias; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHz WWID0", ++ 1); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHz"); ++ free(alias); ++} ++ ++static void gufa_old_match_other(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHz WWID9"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHa"); ++ ++ mock_allocate_binding("MPATHa", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_old_match_other_used(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHz WWID9"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, -1); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHb"); ++ ++ mock_allocate_binding("MPATHb", "WWID0"); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHb"); ++ free(alias); ++} ++ ++static void gufa_old_match_other_wwidmatch(void **state) { ++ char *alias; ++ static const char bindings[] = ("MPATHz WWID9\n" ++ "MPATHc WWID2"); ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, 1); ++ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); ++ mock_unused_alias("MPATHc"); ++ ++ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHc"); ++ free(alias); ++} ++ ++static void gufa_old_match_other_wwidmatch_used(void **state) { ++ char *alias; ++ static const char bindings[] = ("MPATHz WWID9\n" ++ "MPATHc WWID2"); ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); ++ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); ++ ++ mock_bindings_file(bindings, 1); ++ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); ++ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ ++ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_old_nomatch_wwidmatch(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHa WWID0"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_unused_alias("MPATHa"); ++ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHa"); ++ free(alias); ++} ++ ++static void gufa_old_nomatch_wwidmatch_used(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHa WWID0"; ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ mock_bindings_file(bindings, 0); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void gufa_old_nomatch_nowwidmatch(void **state) { ++ char *alias; ++ static const char bindings[] = "MPATHb WWID1"; ++ ++ will_return(__wrap_open_file, true); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_STR("MPATHz")); ++ ++ mock_bindings_file(bindings, -1); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ ++ mock_allocate_binding("MPATHz", "WWID0"); ++ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); ++ ++ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ assert_string_equal(alias, "MPATHz"); ++ free(alias); ++} ++ ++static int test_get_user_friendly_alias() ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(gufa_empty_new_rw), ++ cmocka_unit_test(gufa_empty_new_ro_1), ++ cmocka_unit_test(gufa_empty_new_ro_2), ++ cmocka_unit_test(gufa_match_a_unused), ++ cmocka_unit_test(gufa_match_a_self), ++ cmocka_unit_test(gufa_match_a_used), ++ cmocka_unit_test(gufa_nomatch_a_c), ++ cmocka_unit_test(gufa_nomatch_c_a), ++ cmocka_unit_test(gufa_nomatch_c_b), ++ cmocka_unit_test(gufa_nomatch_c_b_used), ++ cmocka_unit_test(gufa_nomatch_b_f_a), ++ cmocka_unit_test(gufa_old_empty), ++ cmocka_unit_test(gufa_old_match), ++ cmocka_unit_test(gufa_old_match_other), ++ cmocka_unit_test(gufa_old_match_other_used), ++ cmocka_unit_test(gufa_old_match_other_wwidmatch), ++ cmocka_unit_test(gufa_old_match_other_wwidmatch_used), ++ cmocka_unit_test(gufa_old_nomatch_wwidmatch), ++ cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), ++ cmocka_unit_test(gufa_old_nomatch_nowwidmatch), ++ }; ++ ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ + int main(void) + { + int ret = 0; +@@ -1157,6 +1596,8 @@ int main(void) + ret += test_lookup_binding(); + ret += test_rlookup_binding(); + ret += test_allocate_binding(); ++ ret += test_allocate_binding(); ++ ret += test_get_user_friendly_alias(); + + return ret; + } diff --git a/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch b/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch new file mode 100644 index 0000000..430ceaf --- /dev/null +++ b/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch @@ -0,0 +1,365 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 10:40:32 +0200 +Subject: [PATCH] multipath-tools test: consistent use of macros in alias test + +Use the macros introduced with the tests for get_user_friendly_alias() +also in the previously existing tests. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 80 ++++++++++++++++++++++++--------------------------- + 1 file changed, 38 insertions(+), 42 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index 7e443b06..427b2814 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -490,7 +490,7 @@ static void lb_empty(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); + assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); +@@ -503,7 +503,7 @@ static void lb_empty_unused(void **state) + + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHa"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); +@@ -518,7 +518,7 @@ static void lb_empty_failed(void **state) + will_return(__wrap_fgets, NULL); + mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -533,7 +533,7 @@ static void lb_empty_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -548,7 +548,7 @@ static void lb_empty_1_used_self(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); + mock_self_alias("MPATHb", "WWID0"); +- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -561,8 +561,7 @@ static void lb_match_a(void **state) + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); +- expect_condlog(3, "Found matching wwid [WWID0] in bindings file." +- " Setting alias to MPATHa\n"); ++ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); +@@ -577,7 +576,7 @@ static void lb_nomatch_a(void **state) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -590,7 +589,7 @@ static void lb_nomatch_a_bad_check(void **state) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -604,7 +603,7 @@ static void lb_nomatch_a_unused(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -622,7 +621,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); + mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); + mock_self_alias("MPATHf", "WWID1"); +- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); +@@ -635,8 +634,7 @@ static void do_lb_match_c(void **state, int check_if_taken) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHc WWID1\n"); +- expect_condlog(3, "Found matching wwid [WWID1] in bindings file." +- " Setting alias to MPATHc\n"); ++ expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); +@@ -662,7 +660,7 @@ static void lb_nomatch_a_c(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHc WWID1\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -677,7 +675,7 @@ static void lb_nomatch_a_d_unused(void **state) + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -693,7 +691,7 @@ static void lb_nomatch_a_d_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); + mock_unused_alias("MPATHc"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -710,7 +708,7 @@ static void lb_nomatch_a_d_2_used(void **state) + mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); + mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); + mock_unused_alias("MPATHe"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -728,7 +726,7 @@ static void lb_nomatch_a_d_3_used(void **state) + mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); + mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); + mock_unused_alias("MPATHf"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); +@@ -742,7 +740,7 @@ static void lb_nomatch_c_a(void **state) + will_return(__wrap_fgets, "MPATHc WWID1\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -758,7 +756,7 @@ static void lb_nomatch_d_a_unused(void **state) + will_return(__wrap_fgets, "MPATHd WWID0\n"); + will_return(__wrap_fgets, NULL); + mock_unused_alias("MPATHb"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -775,7 +773,7 @@ static void lb_nomatch_d_a_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); + mock_unused_alias("MPATHe"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -790,7 +788,7 @@ static void lb_nomatch_a_b(void **state) + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -806,7 +804,7 @@ static void lb_nomatch_a_b_bad(void **state) + will_return(__wrap_fgets, "MPATHb\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -823,7 +821,7 @@ static void lb_nomatch_a_b_bad_self(void **state) + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + mock_self_alias("MPATHc", "WWID2"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -838,7 +836,7 @@ static void lb_nomatch_b_a(void **state) + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 27); + assert_ptr_equal(alias, NULL); +@@ -857,7 +855,7 @@ static void lb_nomatch_b_a_3_used(void **state) + mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); + mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); + mock_unused_alias("MPATHad"); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 30); + assert_ptr_equal(alias, NULL); +@@ -873,7 +871,7 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -898,7 +896,7 @@ static void lb_nomatch_int_max_used(void **state) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -913,7 +911,7 @@ static void lb_nomatch_int_max_m1(void **state) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); +@@ -929,7 +927,7 @@ static void lb_nomatch_int_max_m1_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -945,7 +943,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); +- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); +@@ -961,7 +959,7 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + will_return(__wrap_fgets, NULL); + mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); +- expect_condlog(0, "no more available user_friendly_names\n"); ++ expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -1017,7 +1015,7 @@ static void rl_empty(void **state) + + buf[0] = '\0'; + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1030,8 +1028,7 @@ static void rl_match_a(void **state) + + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa WWID0\n"); +- expect_condlog(3, "Found matching alias [MPATHa] in bindings file. " +- "Setting wwid to WWID0\n"); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, 0); + assert_string_equal(buf, "WWID0"); +@@ -1045,7 +1042,7 @@ static void rl_nomatch_a(void **state) + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- expect_condlog(3, "No matching alias [MPATHb] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHb")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1060,7 +1057,7 @@ static void rl_malformed_a(void **state) + will_return(__wrap_fgets, "MPATHa \n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); +- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1080,7 +1077,7 @@ static void rl_overlong_a(void **state) + will_return(__wrap_fgets, line); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); +- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); ++ expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +@@ -1095,8 +1092,7 @@ static void rl_match_b(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHb WWID2\n"); +- expect_condlog(3, "Found matching alias [MPATHb] in bindings file. " +- "Setting wwid to WWID2\n"); ++ expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, 0); + assert_string_equal(buf, "WWID2"); +@@ -1125,7 +1121,7 @@ static void al_a(void **state) + expect_value(__wrap_write, count, strlen(ln)); + expect_string(__wrap_write, buf, ln); + will_return(__wrap_write, strlen(ln)); +- expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); ++ expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); + + alias = allocate_binding(0, "WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); +@@ -1142,7 +1138,7 @@ static void al_zz(void **state) + expect_value(__wrap_write, count, strlen(ln)); + expect_string(__wrap_write, buf, ln); + will_return(__wrap_write, strlen(ln)); +- expect_condlog(3, "Created new binding [MPATHzz] for WWID [WWIDzz]\n"); ++ expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); + + alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); + assert_ptr_not_equal(alias, NULL); diff --git a/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch b/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch new file mode 100644 index 0000000..9d71adf --- /dev/null +++ b/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch @@ -0,0 +1,246 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 10:49:32 +0200 +Subject: [PATCH] multipath-tools tests: convert mock_{failed,used}_alias to + macros + +This way we can further improve readability of the individual test +cases. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 92 +++++++++++++++++++++++++-------------------------- + 1 file changed, 46 insertions(+), 46 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index 427b2814..a32b43e8 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -445,26 +445,26 @@ static void mock_self_alias(const char *alias, const char *wwid) + #define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") + #define NOMORE_STR "no more available user_friendly_names\n" + +-static void mock_failed_alias(const char *alias, char *msg) +-{ +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 1); +- expect_string(__wrap_dm_get_uuid, name, alias); +- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); +- will_return(__wrap_dm_get_uuid, 1); +- expect_condlog(3, msg); +-} ++#define mock_failed_alias(alias, wwid) \ ++ do { \ ++ expect_string(__wrap_dm_map_present, str, alias); \ ++ will_return(__wrap_dm_map_present, 1); \ ++ expect_string(__wrap_dm_get_uuid, name, alias); \ ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ ++ will_return(__wrap_dm_get_uuid, 1); \ ++ expect_condlog(3, USED_STR(alias, wwid)); \ ++ } while (0) + +-static void mock_used_alias(const char *alias, char *msg) +-{ +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 1); +- expect_string(__wrap_dm_get_uuid, name, alias); +- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); +- will_return(__wrap_dm_get_uuid, 0); +- will_return(__wrap_dm_get_uuid, "WWID_USED"); +- expect_condlog(3, msg); +-} ++#define mock_used_alias(alias, wwid) \ ++ do { \ ++ expect_string(__wrap_dm_map_present, str, alias); \ ++ will_return(__wrap_dm_map_present, 1); \ ++ expect_string(__wrap_dm_get_uuid, name, alias); \ ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ ++ will_return(__wrap_dm_get_uuid, 0); \ ++ will_return(__wrap_dm_get_uuid, "WWID_USED"); \ ++ expect_condlog(3, USED_STR(alias, wwid)); \ ++ } while(0) + + static void mock_bindings_file(const char *content, int match_line) + { +@@ -516,7 +516,7 @@ static void lb_empty_failed(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_failed_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -531,7 +531,7 @@ static void lb_empty_1_used(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -546,7 +546,7 @@ static void lb_empty_1_used_self(void **state) + char *alias; + + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + mock_self_alias("MPATHb", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -616,10 +616,10 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID1")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID1")); +- mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); +- mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); ++ mock_used_alias("MPATHb", "WWID1"); ++ mock_used_alias("MPATHc", "WWID1"); ++ mock_used_alias("MPATHd", "WWID1"); ++ mock_failed_alias("MPATHe", "WWID1"); + mock_self_alias("MPATHf", "WWID1"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +@@ -689,7 +689,7 @@ static void lb_nomatch_a_d_1_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHc"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -705,8 +705,8 @@ static void lb_nomatch_a_d_2_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); ++ mock_used_alias("MPATHc", "WWID2"); + mock_unused_alias("MPATHe"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -722,9 +722,9 @@ static void lb_nomatch_a_d_3_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID1\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); +- mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); ++ mock_used_alias("MPATHc", "WWID2"); ++ mock_used_alias("MPATHe", "WWID2"); + mock_unused_alias("MPATHf"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -771,7 +771,7 @@ static void lb_nomatch_d_a_1_used(void **state) + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHd WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); ++ mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHe"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -851,9 +851,9 @@ static void lb_nomatch_b_a_3_used(void **state) + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHaa", USED_STR("MPATHaa", "WWID2")); +- mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); +- mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); ++ mock_used_alias("MPATHaa", "WWID2"); ++ mock_used_alias("MPATHab", "WWID2"); ++ mock_used_alias("MPATHac", "WWID2"); + mock_unused_alias("MPATHad"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -895,7 +895,7 @@ static void lb_nomatch_int_max_used(void **state) + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); ++ mock_used_alias("MPATHa", "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); +@@ -926,7 +926,7 @@ static void lb_nomatch_int_max_m1_used(void **state) + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); +@@ -941,7 +941,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); ++ mock_used_alias("MPATHa", "WWID2"); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -957,8 +957,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, NULL); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); ++ mock_used_alias("MPATHa", "WWID2"); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, -1); +@@ -1291,7 +1291,7 @@ static void gufa_match_a_used(void **state) { + + will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_ptr_equal(alias, NULL); +@@ -1355,7 +1355,7 @@ static void gufa_nomatch_c_b_used(void **state) { + mock_bindings_file("MPATHc WWID2\n" + "MPATHb WWID1", + -1); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); ++ mock_used_alias("MPATHa", "WWID4"); + expect_condlog(3, NOMATCH_WWID_STR("WWID4")); + mock_unused_alias("MPATHd"); + +@@ -1450,7 +1450,7 @@ static void gufa_old_match_other_used(void **state) { + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); + + mock_bindings_file(bindings, -1); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_unused_alias("MPATHb"); + +@@ -1493,7 +1493,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { + + mock_bindings_file(bindings, 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); +- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); ++ mock_used_alias("MPATHc", "WWID2"); + + alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); +@@ -1528,7 +1528,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { + + mock_bindings_file(bindings, 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); +- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); diff --git a/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch b/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch new file mode 100644 index 0000000..2105f5a --- /dev/null +++ b/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch @@ -0,0 +1,500 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 11:13:44 +0200 +Subject: [PATCH] multipath-tools test: use mock_bindings_file() consistently + +Further improve test readablity. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 178 +++++++++++++++++++++----------------------------- + 1 file changed, 76 insertions(+), 102 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index a32b43e8..f334f928 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -489,7 +489,7 @@ static void lb_empty(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); + assert_int_equal(rc, 1); +@@ -501,7 +501,7 @@ static void lb_empty_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -515,7 +515,7 @@ static void lb_empty_failed(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_failed_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); +@@ -530,7 +530,7 @@ static void lb_empty_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); +@@ -545,7 +545,7 @@ static void lb_empty_1_used_self(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_used_alias("MPATHa", "WWID0"); + mock_self_alias("MPATHb", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); +@@ -560,7 +560,7 @@ static void lb_match_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ mock_bindings_file("MPATHa WWID0\n", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); + assert_int_equal(rc, 0); +@@ -574,8 +574,7 @@ static void lb_nomatch_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); + assert_int_equal(rc, 2); +@@ -587,8 +586,7 @@ static void lb_nomatch_a_bad_check(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); + assert_int_equal(rc, -1); +@@ -600,8 +598,7 @@ static void lb_nomatch_a_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +@@ -614,8 +611,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + mock_used_alias("MPATHb", "WWID1"); + mock_used_alias("MPATHc", "WWID1"); + mock_used_alias("MPATHd", "WWID1"); +@@ -632,8 +628,8 @@ static void do_lb_match_c(void **state, int check_if_taken) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHc WWID1\n"); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHc WWID1", 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, 0); +@@ -657,9 +653,8 @@ static void lb_nomatch_a_c(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHc WWID1", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); +@@ -671,9 +666,8 @@ static void lb_nomatch_a_d_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -686,9 +680,8 @@ static void lb_nomatch_a_d_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHc"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -702,9 +695,8 @@ static void lb_nomatch_a_d_2_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_unused_alias("MPATHe"); +@@ -719,9 +711,8 @@ static void lb_nomatch_a_d_3_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHd WWID1", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_used_alias("MPATHe", "WWID2"); +@@ -737,9 +728,8 @@ static void lb_nomatch_c_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHc WWID1\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 2); +@@ -751,10 +741,9 @@ static void lb_nomatch_d_a_unused(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHc WWID1\n" ++ "MPATHa WWID0\n" ++ "MPATHd WWID0\n", -1); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -767,10 +756,9 @@ static void lb_nomatch_d_a_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHc WWID1\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHd WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHc WWID1\n" ++ "MPATHa WWID0\n" ++ "MPATHd WWID0\n", -1); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHe"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -784,10 +772,9 @@ static void lb_nomatch_a_b(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb WWID1\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 3); +@@ -799,10 +786,9 @@ static void lb_nomatch_a_b_bad(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb\n", -1); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); +@@ -815,10 +801,9 @@ static void lb_nomatch_a_b_bad_self(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb\n", -1); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + mock_self_alias("MPATHc", "WWID2"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -832,10 +817,9 @@ static void lb_nomatch_b_a(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHz WWID26\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, 27); +@@ -847,10 +831,9 @@ static void lb_nomatch_b_a_3_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATHz WWID26\n" ++ "MPATHa WWID0\n", -1); + mock_used_alias("MPATHaa", "WWID2"); + mock_used_alias("MPATHab", "WWID2"); + mock_used_alias("MPATHac", "WWID2"); +@@ -867,10 +850,9 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); + assert_int_equal(rc, -1); +@@ -892,9 +874,8 @@ static void lb_nomatch_int_max_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); + mock_used_alias("MPATHa", "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -907,10 +888,9 @@ static void lb_nomatch_int_max_m1(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" ++ "MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); + assert_int_equal(rc, INT_MAX); +@@ -922,10 +902,9 @@ static void lb_nomatch_int_max_m1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" ++ "MPATHa WWID0\n", -1); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -938,9 +917,8 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); + mock_used_alias("MPATHa", "WWID2"); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +@@ -954,9 +932,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + int rc; + char *alias; + +- will_return(__wrap_fgets, "MPATHb WWID1\n"); +- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHb WWID1\n" ++ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); + mock_used_alias("MPATHa", "WWID2"); + mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); + expect_condlog(0, NOMORE_STR); +@@ -1014,7 +991,7 @@ static void rl_empty(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1027,7 +1004,7 @@ static void rl_match_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa WWID0\n"); ++ mock_bindings_file("MPATHa WWID0\n", 0); + expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, 0); +@@ -1040,8 +1017,7 @@ static void rl_nomatch_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa WWID0\n", -1); + expect_condlog(3, NOMATCH_STR("MPATHb")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, -1); +@@ -1054,8 +1030,7 @@ static void rl_malformed_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa \n"); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("MPATHa \n", -1); + expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); +@@ -1074,8 +1049,7 @@ static void rl_overlong_a(void **state) + snprintf(line + sizeof(line) - 2, 2, "\n"); + + buf[0] = '\0'; +- will_return(__wrap_fgets, line); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file(line, -1); + expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); +@@ -1089,9 +1063,9 @@ static void rl_match_b(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- will_return(__wrap_fgets, "MPATHa WWID0\n"); +- will_return(__wrap_fgets, "MPATHz WWID26\n"); +- will_return(__wrap_fgets, "MPATHb WWID2\n"); ++ mock_bindings_file("MPATHa WWID0\n" ++ "MPATHz WWID26\n" ++ "MPATHb WWID2\n", 2); + expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, 0); +@@ -1222,7 +1196,7 @@ static void gufa_empty_new_rw(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1235,7 +1209,7 @@ static void gufa_empty_new_rw(void **state) { + static void gufa_empty_new_ro_1(void **state) { + char *alias; + will_return(__wrap_open_file, false); +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1248,7 +1222,7 @@ static void gufa_empty_new_ro_2(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1261,7 +1235,7 @@ static void gufa_match_a_unused(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ mock_bindings_file("MPATHa WWID0", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHa"); + +@@ -1275,7 +1249,7 @@ static void gufa_match_a_self(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ mock_bindings_file("MPATHa WWID0", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_self_alias("MPATHa", "WWID0"); + +@@ -1289,7 +1263,7 @@ static void gufa_match_a_used(void **state) { + + will_return(__wrap_open_file, true); + +- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); ++ mock_bindings_file("MPATHa WWID0", 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +@@ -1389,11 +1363,11 @@ static void gufa_old_empty(void **state) { + will_return(__wrap_open_file, true); + + /* rlookup_binding for ALIAS */ +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_STR("MPATHz")); + + /* lookup_binding */ +- will_return(__wrap_fgets, NULL); ++ mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + + mock_allocate_binding("MPATHz", "WWID0"); diff --git a/0011-libmultipath-add-global-variable-for-current-binding.patch b/0011-libmultipath-add-global-variable-for-current-binding.patch new file mode 100644 index 0000000..c91259d --- /dev/null +++ b/0011-libmultipath-add-global-variable-for-current-binding.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 15:32:17 +0200 +Subject: [PATCH] libmultipath: add global variable for current bindings + +Add a variable global_bindings that holds the currently active vector of +bindings. This variable is freed at program exit. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 11 +++++++++-- + libmultipath/alias.h | 1 + + libmultipath/libmultipath.version | 1 + + multipath/main.c | 2 ++ + multipathd/main.c | 1 + + 5 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 9e9ac563..dd363fd8 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -511,6 +511,7 @@ static void _free_binding(struct binding *bdg) + * an abstract type. + */ + typedef struct _vector Bindings; ++static Bindings global_bindings = { .allocated = 0 }; + + static void free_bindings(Bindings *bindings) + { +@@ -522,6 +523,11 @@ static void free_bindings(Bindings *bindings) + vector_reset(bindings); + } + ++void cleanup_bindings(void) ++{ ++ free_bindings(&global_bindings); ++} ++ + enum { + BINDING_EXISTS, + BINDING_CONFLICT, +@@ -751,7 +757,6 @@ int check_alias_settings(const struct config *conf) + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + +- pthread_cleanup_push_cast(free_bindings, &bindings); + fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); + if (fd != -1) { + FILE *file = fdopen(fd, "r"); +@@ -771,6 +776,8 @@ int check_alias_settings(const struct config *conf) + close(fd); + } + } +- pthread_cleanup_pop(1); ++ ++ cleanup_bindings(); ++ global_bindings = bindings; + return rc; + } +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index fa332233..37b49d9c 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -9,5 +9,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, + + struct config; + int check_alias_settings(const struct config *); ++void cleanup_bindings(void); + + #endif /* _ALIAS_H */ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index a7b8c337..ddd302f5 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -64,6 +64,7 @@ global: + checker_name; + checker_state_name; + check_foreign; ++ cleanup_bindings; + cleanup_lock; + coalesce_paths; + count_active_paths; +diff --git a/multipath/main.c b/multipath/main.c +index b78f3162..45e9745f 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -843,6 +843,8 @@ main (int argc, char *argv[]) + conf->force_sync = 1; + if (atexit(cleanup_vecs)) + condlog(1, "failed to register cleanup handler for vecs: %m"); ++ if (atexit(cleanup_bindings)) ++ condlog(1, "failed to register cleanup handler for bindings: %m"); + while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 'v': +diff --git a/multipathd/main.c b/multipathd/main.c +index 2e02a548..214ed4ae 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3325,6 +3325,7 @@ static void cleanup_child(void) + { + cleanup_threads(); + cleanup_vecs(); ++ cleanup_bindings(); + if (poll_dmevents) + cleanup_dmevent_waiter(); + diff --git a/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch b/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch new file mode 100644 index 0000000..e0f8673 --- /dev/null +++ b/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 15:37:15 +0200 +Subject: [PATCH] libmultipath: rename fix_bindings_file() to + update_bindings_file() + +We will use this function in a more generic way, give it a more +generic name. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index dd363fd8..0aac2393 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -595,8 +595,8 @@ static int write_bindings_file(const Bindings *bindings, int fd) + return 0; + } + +-static int fix_bindings_file(const struct config *conf, +- const Bindings *bindings) ++static int update_bindings_file(const struct config *conf, ++ const Bindings *bindings) + { + int rc; + int fd = -1; +@@ -766,7 +766,7 @@ int check_alias_settings(const struct config *conf) + rc = _check_bindings_file(conf, file, &bindings); + pthread_cleanup_pop(1); + if (rc == -1 && can_write && !conf->bindings_read_only) +- rc = fix_bindings_file(conf, &bindings); ++ rc = update_bindings_file(conf, &bindings); + else if (rc == -1) + condlog(0, "ERROR: bad settings in read-only bindings file %s", + conf->bindings_file); diff --git a/0013-libmultipath-alias.c-move-bindings-related-code-up.patch b/0013-libmultipath-alias.c-move-bindings-related-code-up.patch new file mode 100644 index 0000000..1ad7b9e --- /dev/null +++ b/0013-libmultipath-alias.c-move-bindings-related-code-up.patch @@ -0,0 +1,285 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 16:54:54 +0200 +Subject: [PATCH] libmultipath: alias.c: move bindings related code up + +No code changes, just moving code. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 239 ++++++++++++++++++++++--------------------- + 1 file changed, 120 insertions(+), 119 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 0aac2393..7af403da 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "util.h" +@@ -51,6 +52,125 @@ + + static const char bindings_file_header[] = BINDINGS_FILE_HEADER; + ++struct binding { ++ char *alias; ++ char *wwid; ++}; ++ ++/* ++ * Perhaps one day we'll implement this more efficiently, thus use ++ * an abstract type. ++ */ ++typedef struct _vector Bindings; ++static Bindings global_bindings = { .allocated = 0 }; ++ ++enum { ++ BINDING_EXISTS, ++ BINDING_CONFLICT, ++ BINDING_ADDED, ++ BINDING_DELETED, ++ BINDING_NOTFOUND, ++ BINDING_ERROR, ++}; ++ ++static void _free_binding(struct binding *bdg) ++{ ++ free(bdg->wwid); ++ free(bdg->alias); ++ free(bdg); ++} ++ ++static int add_binding(Bindings *bindings, const char *alias, const char *wwid) ++{ ++ struct binding *bdg; ++ int i, cmp = 0; ++ ++ /* ++ * Keep the bindings array sorted by alias. ++ * Optimization: Search backwards, assuming that the bindings file is ++ * sorted already. ++ */ ++ vector_foreach_slot_backwards(bindings, bdg, i) { ++ if ((cmp = strcmp(bdg->alias, alias)) <= 0) ++ break; ++ } ++ ++ /* Check for exact match */ ++ if (i >= 0 && cmp == 0) ++ return strcmp(bdg->wwid, wwid) ? ++ BINDING_CONFLICT : BINDING_EXISTS; ++ ++ i++; ++ bdg = calloc(1, sizeof(*bdg)); ++ if (bdg) { ++ bdg->wwid = strdup(wwid); ++ bdg->alias = strdup(alias); ++ if (bdg->wwid && bdg->alias && ++ vector_insert_slot(bindings, i, bdg)) ++ return BINDING_ADDED; ++ else ++ _free_binding(bdg); ++ } ++ ++ return BINDING_ERROR; ++} ++ ++static int write_bindings_file(const Bindings *bindings, int fd) ++{ ++ struct binding *bnd; ++ STRBUF_ON_STACK(line); ++ int i; ++ ++ if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) ++ != sizeof(BINDINGS_FILE_HEADER) - 1) ++ return -1; ++ ++ vector_foreach_slot(bindings, bnd, i) { ++ int len; ++ ++ if ((len = print_strbuf(&line, "%s %s\n", ++ bnd->alias, bnd->wwid)) < 0) ++ return -1; ++ if (write(fd, get_strbuf_str(&line), len) != len) ++ return -1; ++ truncate_strbuf(&line, 0); ++ } ++ return 0; ++} ++ ++static int update_bindings_file(const struct config *conf, ++ const Bindings *bindings) ++{ ++ int rc; ++ int fd = -1; ++ char tempname[PATH_MAX]; ++ mode_t old_umask; ++ ++ if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) ++ return -1; ++ /* coverity: SECURE_TEMP */ ++ old_umask = umask(0077); ++ if ((fd = mkstemp(tempname)) == -1) { ++ condlog(1, "%s: mkstemp: %m", __func__); ++ return -1; ++ } ++ umask(old_umask); ++ pthread_cleanup_push(cleanup_fd_ptr, &fd); ++ rc = write_bindings_file(bindings, fd); ++ pthread_cleanup_pop(1); ++ if (rc == -1) { ++ condlog(1, "failed to write new bindings file %s", ++ tempname); ++ unlink(tempname); ++ return rc; ++ } ++ if ((rc = rename(tempname, conf->bindings_file)) == -1) ++ condlog(0, "%s: rename: %m", __func__); ++ else ++ condlog(1, "updated bindings file %s", conf->bindings_file); ++ return rc; ++} ++ + int + valid_alias(const char *alias) + { +@@ -494,25 +614,6 @@ get_user_friendly_wwid(const char *alias, char *buff, const char *file) + return 0; + } + +-struct binding { +- char *alias; +- char *wwid; +-}; +- +-static void _free_binding(struct binding *bdg) +-{ +- free(bdg->wwid); +- free(bdg->alias); +- free(bdg); +-} +- +-/* +- * Perhaps one day we'll implement this more efficiently, thus use +- * an abstract type. +- */ +-typedef struct _vector Bindings; +-static Bindings global_bindings = { .allocated = 0 }; +- + static void free_bindings(Bindings *bindings) + { + struct binding *bdg; +@@ -528,106 +629,6 @@ void cleanup_bindings(void) + free_bindings(&global_bindings); + } + +-enum { +- BINDING_EXISTS, +- BINDING_CONFLICT, +- BINDING_ADDED, +- BINDING_DELETED, +- BINDING_NOTFOUND, +- BINDING_ERROR, +-}; +- +-static int add_binding(Bindings *bindings, const char *alias, const char *wwid) +-{ +- struct binding *bdg; +- int i, cmp = 0; +- +- /* +- * Keep the bindings array sorted by alias. +- * Optimization: Search backwards, assuming that the bindings file is +- * sorted already. +- */ +- vector_foreach_slot_backwards(bindings, bdg, i) { +- if ((cmp = strcmp(bdg->alias, alias)) <= 0) +- break; +- } +- +- /* Check for exact match */ +- if (i >= 0 && cmp == 0) +- return strcmp(bdg->wwid, wwid) ? +- BINDING_CONFLICT : BINDING_EXISTS; +- +- i++; +- bdg = calloc(1, sizeof(*bdg)); +- if (bdg) { +- bdg->wwid = strdup(wwid); +- bdg->alias = strdup(alias); +- if (bdg->wwid && bdg->alias && +- vector_insert_slot(bindings, i, bdg)) +- return BINDING_ADDED; +- else +- _free_binding(bdg); +- } +- +- return BINDING_ERROR; +-} +- +-static int write_bindings_file(const Bindings *bindings, int fd) +-{ +- struct binding *bnd; +- STRBUF_ON_STACK(line); +- int i; +- +- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) +- != sizeof(BINDINGS_FILE_HEADER) - 1) +- return -1; +- +- vector_foreach_slot(bindings, bnd, i) { +- int len; +- +- if ((len = print_strbuf(&line, "%s %s\n", +- bnd->alias, bnd->wwid)) < 0) +- return -1; +- if (write(fd, get_strbuf_str(&line), len) != len) +- return -1; +- truncate_strbuf(&line, 0); +- } +- return 0; +-} +- +-static int update_bindings_file(const struct config *conf, +- const Bindings *bindings) +-{ +- int rc; +- int fd = -1; +- char tempname[PATH_MAX]; +- mode_t old_umask; +- +- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) +- return -1; +- /* coverity: SECURE_TEMP */ +- old_umask = umask(0077); +- if ((fd = mkstemp(tempname)) == -1) { +- condlog(1, "%s: mkstemp: %m", __func__); +- return -1; +- } +- umask(old_umask); +- pthread_cleanup_push(cleanup_fd_ptr, &fd); +- rc = write_bindings_file(bindings, fd); +- pthread_cleanup_pop(1); +- if (rc == -1) { +- condlog(1, "failed to write new bindings file %s", +- tempname); +- unlink(tempname); +- return rc; +- } +- if ((rc = rename(tempname, conf->bindings_file)) == -1) +- condlog(0, "%s: rename: %m", __func__); +- else +- condlog(1, "updated bindings file %s", conf->bindings_file); +- return rc; +-} +- + static int _check_bindings_file(const struct config *conf, FILE *file, + Bindings *bindings) + { diff --git a/0014-libmultipath-update_bindings_file-take-filename-argu.patch b/0014-libmultipath-update_bindings_file-take-filename-argu.patch new file mode 100644 index 0000000..6b9d2e8 --- /dev/null +++ b/0014-libmultipath-update_bindings_file-take-filename-argu.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 15:53:49 +0200 +Subject: [PATCH] libmultipath: update_bindings_file: take filename argument + +This function just uses the file name, no other configuration +parameters. Also, pass the Bindings argument first to use the +same convention as the other functions in this file. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 7af403da..9bd3875e 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -138,15 +138,15 @@ static int write_bindings_file(const Bindings *bindings, int fd) + return 0; + } + +-static int update_bindings_file(const struct config *conf, +- const Bindings *bindings) ++static int update_bindings_file(const Bindings *bindings, ++ const char *bindings_file) + { + int rc; + int fd = -1; + char tempname[PATH_MAX]; + mode_t old_umask; + +- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) ++ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) + return -1; + /* coverity: SECURE_TEMP */ + old_umask = umask(0077); +@@ -164,10 +164,10 @@ static int update_bindings_file(const struct config *conf, + unlink(tempname); + return rc; + } +- if ((rc = rename(tempname, conf->bindings_file)) == -1) ++ if ((rc = rename(tempname, bindings_file)) == -1) + condlog(0, "%s: rename: %m", __func__); + else +- condlog(1, "updated bindings file %s", conf->bindings_file); ++ condlog(1, "updated bindings file %s", bindings_file); + return rc; + } + +@@ -767,7 +767,7 @@ int check_alias_settings(const struct config *conf) + rc = _check_bindings_file(conf, file, &bindings); + pthread_cleanup_pop(1); + if (rc == -1 && can_write && !conf->bindings_read_only) +- rc = update_bindings_file(conf, &bindings); ++ rc = update_bindings_file(&bindings, conf->bindings_file); + else if (rc == -1) + condlog(0, "ERROR: bad settings in read-only bindings file %s", + conf->bindings_file); diff --git a/0015-libmultipath-update_bindings_file-use-a-single-write.patch b/0015-libmultipath-update_bindings_file-use-a-single-write.patch new file mode 100644 index 0000000..1e1fd15 --- /dev/null +++ b/0015-libmultipath-update_bindings_file-use-a-single-write.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 15:54:45 +0200 +Subject: [PATCH] libmultipath: update_bindings_file: use a single write() + +Save code and syscalls by assembling the content in memory first. +write() may return less bytes written than expected. Deal with it. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 9bd3875e..92f90f05 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -118,22 +118,30 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + static int write_bindings_file(const Bindings *bindings, int fd) + { + struct binding *bnd; +- STRBUF_ON_STACK(line); ++ STRBUF_ON_STACK(content); + int i; ++ size_t len; + +- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) +- != sizeof(BINDINGS_FILE_HEADER) - 1) ++ if (__append_strbuf_str(&content, BINDINGS_FILE_HEADER, ++ sizeof(BINDINGS_FILE_HEADER) - 1) == -1) + return -1; + + vector_foreach_slot(bindings, bnd, i) { +- int len; +- +- if ((len = print_strbuf(&line, "%s %s\n", +- bnd->alias, bnd->wwid)) < 0) ++ if (print_strbuf(&content, "%s %s\n", ++ bnd->alias, bnd->wwid) < 0) + return -1; +- if (write(fd, get_strbuf_str(&line), len) != len) ++ } ++ len = get_strbuf_len(&content); ++ while (len > 0) { ++ ssize_t n = write(fd, get_strbuf_str(&content), len); ++ ++ if (n < 0) ++ return n; ++ else if (n == 0) { ++ condlog(2, "%s: short write", __func__); + return -1; +- truncate_strbuf(&line, 0); ++ } ++ len -= n; + } + return 0; + } diff --git a/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch b/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch new file mode 100644 index 0000000..1126b95 --- /dev/null +++ b/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 22:33:39 +0200 +Subject: [PATCH] libmultipath: update_bindings_file: don't log temp file name + +The name of the temp file is unlikely to be helpful for users, +and hard to predict in the unit test. Omit it. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 92f90f05..afa5879e 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -167,8 +167,7 @@ static int update_bindings_file(const Bindings *bindings, + rc = write_bindings_file(bindings, fd); + pthread_cleanup_pop(1); + if (rc == -1) { +- condlog(1, "failed to write new bindings file %s", +- tempname); ++ condlog(1, "failed to write new bindings file"); + unlink(tempname); + return rc; + } diff --git a/0017-libmultipath-alias.c-factor-out-read_binding.patch b/0017-libmultipath-alias.c-factor-out-read_binding.patch new file mode 100644 index 0000000..8c9cb08 --- /dev/null +++ b/0017-libmultipath-alias.c-factor-out-read_binding.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 24 Aug 2023 21:17:25 +0200 +Subject: [PATCH] libmultipath: alias.c: factor out read_binding() + +This way we can test the parsing of input lines from the bindings +file more easily. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 58 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 40 insertions(+), 18 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index afa5879e..ecf4a2ac 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -636,6 +636,43 @@ void cleanup_bindings(void) + free_bindings(&global_bindings); + } + ++enum { ++ READ_BINDING_OK, ++ READ_BINDING_SKIP, ++}; ++ ++static int read_binding(char *line, unsigned int linenr, char **alias, ++ char **wwid) { ++ char *c, *saveptr; ++ ++ c = strpbrk(line, "#\n\r"); ++ if (c) ++ *c = '\0'; ++ ++ *alias = strtok_r(line, " \t", &saveptr); ++ if (!*alias) /* blank line */ ++ return READ_BINDING_SKIP; ++ ++ *wwid = strtok_r(NULL, " \t", &saveptr); ++ if (!*wwid) { ++ condlog(1, "invalid line %u in bindings file, missing WWID", ++ linenr); ++ return READ_BINDING_SKIP; ++ } ++ if (strlen(*wwid) > WWID_SIZE - 1) { ++ condlog(3, ++ "Ignoring too large wwid at %u in bindings file", ++ linenr); ++ return READ_BINDING_SKIP; ++ } ++ c = strtok_r(NULL, " \t", &saveptr); ++ if (c) ++ /* This is non-fatal */ ++ condlog(1, "invalid line %d in bindings file, extra args \"%s\"", ++ linenr, c); ++ return READ_BINDING_OK; ++} ++ + static int _check_bindings_file(const struct config *conf, FILE *file, + Bindings *bindings) + { +@@ -647,27 +684,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + + pthread_cleanup_push(cleanup_free_ptr, &line); + while ((n = getline(&line, &line_len, file)) >= 0) { +- char *c, *alias, *wwid, *saveptr; ++ char *alias, *wwid; + const char *mpe_wwid; + +- linenr++; +- c = strpbrk(line, "#\n\r"); +- if (c) +- *c = '\0'; +- alias = strtok_r(line, " \t", &saveptr); +- if (!alias) /* blank line */ +- continue; +- wwid = strtok_r(NULL, " \t", &saveptr); +- if (!wwid) { +- condlog(1, "invalid line %d in bindings file, missing WWID", +- linenr); ++ if (read_binding(line, ++linenr, &alias, &wwid) ++ == READ_BINDING_SKIP) + continue; +- } +- c = strtok_r(NULL, " \t", &saveptr); +- if (c) +- /* This is non-fatal */ +- condlog(1, "invalid line %d in bindings file, extra args \"%s\"", +- linenr, c); + + mpe_wwid = get_mpe_wwid(conf->mptable, alias); + if (mpe_wwid && strcmp(mpe_wwid, wwid)) { diff --git a/0018-libmultipath-keep-bindings-in-memory.patch b/0018-libmultipath-keep-bindings-in-memory.patch new file mode 100644 index 0000000..bb26ea2 --- /dev/null +++ b/0018-libmultipath-keep-bindings-in-memory.patch @@ -0,0 +1,545 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 22 Aug 2023 21:14:51 +0200 +Subject: [PATCH] libmultipath: keep bindings in memory + +Rather than opening the bindings file every time we must retrieve +a binding, keep the contents in memory and write the file only +if additions have been made. This simplifies the code, and should speed up +alias lookups significantly. As a side effect, the aliases will be stored +sorted by alias, which changes the way aliases are allocated if there are +unused "holes" in the sequence of aliases. For example, if the bindings file +contains mpathb, mpathy, and mpatha, in this order, the next new alias used to +be mpathz and is now mpathc. + +Another side effect is that multipathd will not automatically pick up changes +to the bindings file at runtime without a reconfigure operation. It is +questionable whether these on-the-fly changes were a good idea in the first +place, as inconsistent configurations may easily come to pass. It desired, +it would be feasible to implement automatic update of the bindings using the +existing inotify approach. + +The new implementation of get_user_friendly_alias() is slightly different +than before. The logic is summarized in a comment in the code. Unit tests +will be provided that illustrate the changes. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 351 ++++++++++++++++----------------------- + libmultipath/alias.h | 2 +- + libmultipath/configure.c | 3 +- + 3 files changed, 144 insertions(+), 212 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index ecf4a2ac..d6563749 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -50,8 +50,6 @@ + "# alias wwid\n" \ + "#\n" + +-static const char bindings_file_header[] = BINDINGS_FILE_HEADER; +- + struct binding { + char *alias; + char *wwid; +@@ -80,6 +78,45 @@ static void _free_binding(struct binding *bdg) + free(bdg); + } + ++static const struct binding *get_binding_for_alias(const Bindings *bindings, ++ const char *alias) ++{ ++ const struct binding *bdg; ++ int i; ++ ++ if (!alias) ++ return NULL; ++ vector_foreach_slot(bindings, bdg, i) { ++ if (!strncmp(bdg->alias, alias, WWID_SIZE)) { ++ condlog(3, "Found matching alias [%s] in bindings file." ++ " Setting wwid to %s", alias, bdg->wwid); ++ return bdg; ++ } ++ } ++ ++ condlog(3, "No matching alias [%s] in bindings file.", alias); ++ return NULL; ++} ++ ++static const struct binding *get_binding_for_wwid(const Bindings *bindings, ++ const char *wwid) ++{ ++ const struct binding *bdg; ++ int i; ++ ++ if (!wwid) ++ return NULL; ++ vector_foreach_slot(bindings, bdg, i) { ++ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { ++ condlog(3, "Found matching wwid [%s] in bindings file." ++ " Setting alias to %s", wwid, bdg->alias); ++ return bdg; ++ } ++ } ++ condlog(3, "No matching wwid [%s] in bindings file.", wwid); ++ return NULL; ++} ++ + static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + { + struct binding *bdg; +@@ -115,6 +152,24 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + return BINDING_ERROR; + } + ++static int delete_binding(Bindings *bindings, const char *wwid) ++{ ++ struct binding *bdg; ++ int i; ++ ++ vector_foreach_slot(bindings, bdg, i) { ++ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { ++ _free_binding(bdg); ++ break; ++ } ++ } ++ if (i >= VECTOR_SIZE(bindings)) ++ return BINDING_NOTFOUND; ++ ++ vector_del_slot(bindings, i); ++ return BINDING_DELETED; ++} ++ + static int write_bindings_file(const Bindings *bindings, int fd) + { + struct binding *bnd; +@@ -267,38 +322,15 @@ static bool id_already_taken(int id, const char *prefix, const char *map_wwid) + return alias_already_taken(alias, map_wwid); + } + +-/* +- * Returns: 0 if matching entry in WWIDs file found +- * -1 if an error occurs +- * >0 a free ID that could be used for the WWID at hand +- * *map_alias is set to a freshly allocated string with the matching alias if +- * the function returns 0, or to NULL otherwise. +- */ +-static int +-lookup_binding(FILE *f, const char *map_wwid, char **map_alias, +- const char *prefix, int check_if_taken) ++int get_free_id(const Bindings *bindings, const char *prefix, const char *map_wwid) + { +- char buf[LINE_MAX]; +- unsigned int line_nr = 0; +- int id = 1; ++ const struct binding *bdg; ++ int i, id = 1; + int biggest_id = 1; + int smallest_bigger_id = INT_MAX; + +- *map_alias = NULL; +- +- rewind(f); +- while (fgets(buf, LINE_MAX, f)) { +- const char *alias, *wwid; +- char *c, *saveptr; +- int curr_id; +- +- line_nr++; +- c = strpbrk(buf, "#\n\r"); +- if (c) +- *c = '\0'; +- alias = strtok_r(buf, " \t", &saveptr); +- if (!alias) /* blank line */ +- continue; ++ vector_foreach_slot(bindings, bdg, i) { ++ int curr_id = scan_devname(bdg->alias, prefix); + + /* + * Find an unused index - explanation of the algorithm +@@ -333,8 +365,6 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + * biggest_id is always > smallest_bigger_id, except in the + * "perfectly ordered" case. + */ +- +- curr_id = scan_devname(alias, prefix); + if (curr_id == id) { + if (id < INT_MAX) + id++; +@@ -345,36 +375,15 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + } + if (curr_id > biggest_id) + biggest_id = curr_id; ++ + if (curr_id > id && curr_id < smallest_bigger_id) + smallest_bigger_id = curr_id; +- wwid = strtok_r(NULL, " \t", &saveptr); +- if (!wwid){ +- condlog(3, +- "Ignoring malformed line %u in bindings file", +- line_nr); +- continue; +- } +- if (strcmp(wwid, map_wwid) == 0){ +- condlog(3, "Found matching wwid [%s] in bindings file." +- " Setting alias to %s", wwid, alias); +- *map_alias = strdup(alias); +- if (*map_alias == NULL) { +- condlog(0, "Cannot copy alias from bindings " +- "file: out of memory"); +- return -1; +- } +- return 0; +- } +- } +- if (!prefix && check_if_taken) +- id = -1; +- if (id >= smallest_bigger_id) { +- if (biggest_id < INT_MAX) +- id = biggest_id + 1; +- else +- id = -1; + } +- if (id > 0 && check_if_taken) { ++ ++ if (id >= smallest_bigger_id) ++ id = biggest_id < INT_MAX ? biggest_id + 1 : -1; ++ ++ if (id > 0) { + while(id_already_taken(id, prefix, map_wwid)) { + if (id == INT_MAX) { + id = -1; +@@ -391,64 +400,17 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, + } + } + } +- if (id < 0) { ++ ++ if (id < 0) + condlog(0, "no more available user_friendly_names"); +- return -1; +- } else +- condlog(3, "No matching wwid [%s] in bindings file.", map_wwid); + return id; + } + +-static int +-rlookup_binding(FILE *f, char *buff, const char *map_alias) +-{ +- char line[LINE_MAX]; +- unsigned int line_nr = 0; +- +- buff[0] = '\0'; +- +- while (fgets(line, LINE_MAX, f)) { +- char *c, *saveptr; +- const char *alias, *wwid; +- +- line_nr++; +- c = strpbrk(line, "#\n\r"); +- if (c) +- *c = '\0'; +- alias = strtok_r(line, " \t", &saveptr); +- if (!alias) /* blank line */ +- continue; +- wwid = strtok_r(NULL, " \t", &saveptr); +- if (!wwid){ +- condlog(3, +- "Ignoring malformed line %u in bindings file", +- line_nr); +- continue; +- } +- if (strlen(wwid) > WWID_SIZE - 1) { +- condlog(3, +- "Ignoring too large wwid at %u in bindings file", line_nr); +- continue; +- } +- if (strcmp(alias, map_alias) == 0){ +- condlog(3, "Found matching alias [%s] in bindings file." +- " Setting wwid to %s", alias, wwid); +- strlcpy(buff, wwid, WWID_SIZE); +- return 0; +- } +- } +- condlog(3, "No matching alias [%s] in bindings file.", map_alias); +- +- return -1; +-} +- + static char * +-allocate_binding(int fd, const char *wwid, int id, const char *prefix) ++allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) + { + STRBUF_ON_STACK(buf); +- off_t offset; +- ssize_t len; +- char *alias, *c; ++ char *alias; + + if (id <= 0) { + condlog(0, "%s: cannot allocate new binding for id %d", +@@ -460,164 +422,135 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) + format_devname(&buf, id) == -1) + return NULL; + +- if (print_strbuf(&buf, " %s\n", wwid) < 0) +- return NULL; ++ alias = steal_strbuf_str(&buf); + +- offset = lseek(fd, 0, SEEK_END); +- if (offset < 0){ +- condlog(0, "Cannot seek to end of bindings file : %s", +- strerror(errno)); ++ if (add_binding(&global_bindings, alias, wwid) != BINDING_ADDED) { ++ condlog(0, "%s: cannot allocate new binding %s for %s", ++ __func__, alias, wwid); ++ free(alias); + return NULL; + } + +- len = get_strbuf_len(&buf); +- alias = steal_strbuf_str(&buf); +- +- if (write(fd, alias, len) != len) { +- condlog(0, "Cannot write binding to bindings file : %s", +- strerror(errno)); +- /* clear partial write */ +- if (ftruncate(fd, offset)) +- condlog(0, "Cannot truncate the header : %s", +- strerror(errno)); ++ if (update_bindings_file(&global_bindings, filename) == -1) { ++ condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); ++ delete_binding(&global_bindings, wwid); + free(alias); + return NULL; + } +- c = strchr(alias, ' '); +- if (c) +- *c = '\0'; + + condlog(3, "Created new binding [%s] for WWID [%s]", alias, wwid); + return alias; + } + ++/* ++ * get_user_friendly_alias() action table ++ * ++ * The table shows the various cases, the actions taken, and the CI ++ * functions from tests/alias.c that represent them. ++ * ++ * - O: old alias given ++ * - A: old alias in table (y: yes, correct WWID; X: yes, wrong WWID) ++ * - W: wwid in table ++ * ++ * | No | O | A | W | action | function gufa_X | ++ * |----+---+---+---+--------------------------------------------+------------------------------| ++ * | 1 | n | - | n | get new alias | nomatch_Y | ++ * | 2 | n | - | y | use alias from bindings | match_a_Y | ++ * | 3 | y | n | n | add binding for old alias | old_nomatch_nowwidmatch | ++ * | 4 | y | n | y | use alias from bindings (avoid duplicates) | old_nomatch_wwidmatch | ++ * | 5 | y | y | n | [ impossible ] | - | ++ * | 6 | y | y | y | use old alias == alias from bindings | old_match | ++ * | 7 | y | X | n | get new alias | old_match_other | ++ * | 8 | y | X | y | use alias from bindings | old_match_other_wwidmatch | ++ * ++ * Notes: ++ * - "use alias from bindings" means that the alias from the bindings file will ++ * be tried; if it is in use, the alias selection will fail. No other ++ * bindings will be attempted. ++ * - "get new alias" fails if all aliases are used up, or if writing the ++ * bindings file fails. ++ * - if "alias_old" is set, it can't be bound to a different map. alias_old is ++ * initialized in find_existing_alias() by scanning the mpvec. We trust ++ * that the mpvec corrcectly represents kernel state. ++ */ ++ + char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, + const char *prefix, bool bindings_read_only) + { + char *alias = NULL; + int id = 0; +- int fd, can_write; + bool new_binding = false; +- char buff[WWID_SIZE]; +- FILE *f; +- +- fd = open_file(file, &can_write, bindings_file_header); +- if (fd < 0) +- return NULL; +- +- f = fdopen(fd, "r"); +- if (!f) { +- condlog(0, "cannot fdopen on bindings file descriptor"); +- close(fd); +- return NULL; +- } ++ const struct binding *bdg; + +- if (!strlen(alias_old)) ++ if (!*alias_old) + goto new_alias; + +- /* lookup the binding. if it exists, the wwid will be in buff +- * either way, id contains the id for the alias +- */ +- rlookup_binding(f, buff, alias_old); +- +- if (strlen(buff) > 0) { +- /* If buff is our wwid, it's already allocated correctly. */ +- if (strcmp(buff, wwid) == 0) { ++ /* See if there's a binding matching both alias_old and wwid */ ++ bdg = get_binding_for_alias(&global_bindings, alias_old); ++ if (bdg) { ++ if (!strcmp(bdg->wwid, wwid)) { + alias = strdup(alias_old); + goto out; +- + } else { + condlog(0, "alias %s already bound to wwid %s, cannot reuse", +- alias_old, buff); ++ alias_old, bdg->wwid); + goto new_alias; + } + } + +- /* +- * Look for an existing alias in the bindings file. +- * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. +- */ +- lookup_binding(f, wwid, &alias, NULL, 0); +- if (alias) { +- if (alias_already_taken(alias, wwid)) { +- free(alias); +- alias = NULL; +- } else ++ /* allocate the existing alias in the bindings file */ ++ id = scan_devname(alias_old, prefix); ++ ++new_alias: ++ /* Check for existing binding of WWID */ ++ bdg = get_binding_for_wwid(&global_bindings, wwid); ++ if (bdg) { ++ if (!alias_already_taken(bdg->alias, wwid)) { + condlog(3, "Use existing binding [%s] for WWID [%s]", +- alias, wwid); ++ bdg->alias, wwid); ++ alias = strdup(bdg->alias); ++ } + goto out; + } + +- /* alias_old is already taken by our WWID, update bindings file. */ +- id = scan_devname(alias_old, prefix); +- +-new_alias: + if (id <= 0) { + /* + * no existing alias was provided, or allocating it + * failed. Try a new one. + */ +- id = lookup_binding(f, wwid, &alias, prefix, 1); +- if (id == 0 && alias_already_taken(alias, wwid)) { +- free(alias); +- alias = NULL; +- } ++ id = get_free_id(&global_bindings, prefix, wwid); + if (id <= 0) + goto out; + else + new_binding = true; + } + +- if (fflush(f) != 0) { +- condlog(0, "cannot fflush bindings file stream : %s", +- strerror(errno)); +- goto out; +- } ++ if (!bindings_read_only && id > 0) ++ alias = allocate_binding(file, wwid, id, prefix); + +- if (can_write && !bindings_read_only) { +- alias = allocate_binding(fd, wwid, id, prefix); +- if (alias && !new_binding) +- condlog(2, "Allocated existing binding [%s] for WWID [%s]", +- alias, wwid); +- } ++ if (alias && !new_binding) ++ condlog(2, "Allocated existing binding [%s] for WWID [%s]", ++ alias, wwid); + + out: +- pthread_cleanup_push(free, alias); +- fclose(f); +- pthread_cleanup_pop(0); + return alias; + } + +-int +-get_user_friendly_wwid(const char *alias, char *buff, const char *file) ++int get_user_friendly_wwid(const char *alias, char *buff) + { +- int fd, unused; +- FILE *f; ++ const struct binding *bdg; + + if (!alias || *alias == '\0') { + condlog(3, "Cannot find binding for empty alias"); + return -1; + } + +- fd = open_file(file, &unused, bindings_file_header); +- if (fd < 0) +- return -1; +- +- f = fdopen(fd, "r"); +- if (!f) { +- condlog(0, "cannot fdopen on bindings file descriptor : %s", +- strerror(errno)); +- close(fd); ++ bdg = get_binding_for_alias(&global_bindings, alias); ++ if (!bdg) { ++ *buff = '\0'; + return -1; + } +- +- rlookup_binding(f, buff, alias); +- if (!strlen(buff)) { +- fclose(f); +- return -1; +- } +- +- fclose(f); ++ strlcpy(buff, bdg->wwid, WWID_SIZE); + return 0; + } + +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index 37b49d9c..5ef6720b 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -2,7 +2,7 @@ + #define _ALIAS_H + + int valid_alias(const char *alias); +-int get_user_friendly_wwid(const char *alias, char *buff, const char *file); ++int get_user_friendly_wwid(const char *alias, char *buff); + char *get_user_friendly_alias(const char *wwid, const char *file, + const char *alias_old, + const char *prefix, bool bindings_read_only); +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 029fbbd2..d8094903 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1378,8 +1378,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, + refwwid = tmpwwid; + + /* or may be a binding */ +- else if (get_user_friendly_wwid(dev, tmpwwid, +- conf->bindings_file) == 0) ++ else if (get_user_friendly_wwid(dev, tmpwwid) == 0) + refwwid = tmpwwid; + + /* or may be an alias */ diff --git a/0019-multipath-tools-tests-fix-alias-tests.patch b/0019-multipath-tools-tests-fix-alias-tests.patch new file mode 100644 index 0000000..da618f6 --- /dev/null +++ b/0019-multipath-tools-tests-fix-alias-tests.patch @@ -0,0 +1,1698 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 25 Aug 2023 17:55:55 +0200 +Subject: [PATCH] multipath-tools tests: fix alias tests + +The different implementation of get_user_friendly_alias() and its helpers +necessitates changes in the unit tests. It would be nice if it didn't, but the +unit tests are too closely bound to the implementation to make this possible. + +- The bindings table is held in memory in alphabetically sorted order, which + may change the result of looking for free alias IDs if the entries in the + bindings file were unordered initially. In particular, if only a small + number of bindings exists, "holes" in the file will be detected more easily. + But because the sort order of the aliases differs from simple alphabetic + sorting ("mpathz" precedes "mpathaa"), a bindings file that contains all + bindings from "a" to "aa" (or more) will appear unsorted. + As an extra check, some of the unit tests deliberately use a different + implementation of add_binding() that does not order the bindings + table. + +- Broken lines in the bindings file never make it to the in-memory + representation. An alias that appeard "used" because it occurred in a broken + line will not appear used any more. Warnings about malformed lines will only + be printed while the bindings file is read, not from get_user_friendly_alias(). + +- The match_line argument of mock_bindings_file() is obsolete. + +- lookup_binding() and rlookup_binding() have been removed from + libmultipath. They are now emulated in the unit test code. + +- lookup_binding() didn't check for used alias in all cases previously, but it does now. + +- prefix != NULL and check_if_taken == false is not supported any more + in lookup_binding(). + +- allocate_binding() uses a very different sequence of systems calls now, as + it's implemented using update_bindings_file(). In particular, it's now more + difficult to predict the content of the write() call that creates the + bindings file. See comments for __wrap_write(). + +- some unit tests for get_user_friendly_alias() had to call + mock_bindings_file() twice, because the old implementation would read the + file twice (first rlookup_binding() and then lookup_binding()). This is not + necessary any more. + +- The unit tests need a teardown function to clear the bindings table in memory. + +- Minor changes are necessary because of changed ordering of the log messages. + Previously, lookup_binding() combined check for an existing entry and the + search for a new ID. The new algorithm does this in two separate steps and + tests for used aliases in between, which causes a change in the order in which + log messages are emitted. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 957 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 614 insertions(+), 343 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index f334f928..50a21ecf 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -3,10 +3,12 @@ + #include + #include + #include ++#include "strbuf.h" + #include "util.h" + #include "alias.h" + #include "test-log.h" + #include ++#include + + #include "globals.c" + #include "../libmultipath/alias.c" +@@ -20,18 +22,6 @@ + #define MPATH_ID_INT_MAX_p1 "fxshrxx" + #endif + +-void __wrap_rewind(FILE *stream) +-{} +- +-char *__wrap_fgets(char *buf, int n, FILE *stream) +-{ +- char *val = mock_ptr_type(char *); +- if (!val) +- return NULL; +- strlcpy(buf, val, n); +- return buf; +-} +- + static int __set_errno(int err) + { + if (err >= 0) { +@@ -43,23 +33,44 @@ static int __set_errno(int err) + } + } + +-off_t __wrap_lseek(int fd, off_t offset, int whence) ++/* ++ * allocate_binding -> write_bindings_file() writes the entire file, i.e. the ++ * header, any pre-existing bindings, and the new binding. The complete content ++ * depends on history and is different to predict here. Therefore we check only ++ * the newly added binding. Because add_binding() sorts entries, this new ++ * binding isn't necessarily the last one; receive it from will_return() and ++ * search for it with strstr(). ++ * If the string to be written doesn't start with the bindings file ++ * header, it's a test of a partial write. ++ */ ++ssize_t __wrap_write(int fd, const void *buf, size_t count) + { +- return __set_errno(mock_type(int)); ++ const char *binding, *start; + ++#if DEBUG_WRITE ++ fprintf(stderr, "%s: %zx exp %zx\n===\n%s\n===\n", __func__, strlen(buf), ++ count, (const char *)buf); ++#endif ++ if (!strncmp((const char *)buf, BINDINGS_FILE_HEADER, ++ sizeof(BINDINGS_FILE_HEADER) - 1)) ++ start = (const char *)buf + sizeof(BINDINGS_FILE_HEADER) - 1; ++ else ++ start = buf; ++ binding = mock_ptr_type(char *); ++ start = strstr(start, binding); ++ check_expected(count); ++ assert_ptr_not_equal(start, NULL); ++ return __set_errno(mock_type(int)); + } + +-ssize_t __wrap_write(int fd, const void *buf, size_t count) ++int __wrap_rename(const char *old, const char *new) + { +- check_expected(count); +- check_expected(buf); + return __set_errno(mock_type(int)); + } + +-int __wrap_ftruncate(int fd, off_t length) ++int __wrap_mkstemp(char *template) + { +- check_expected(length); +- return __set_errno(mock_type(int)); ++ return 10; + } + + int __wrap_dm_map_present(const char * str) +@@ -84,32 +95,6 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + #define TEST_FDNO 1234 + #define TEST_FPTR ((FILE *) 0xaffe) + +-int __wrap_open_file(const char *file, int *can_write, const char *header) +-{ +- int cw = mock_type(int); +- +- *can_write = cw; +- return TEST_FDNO; +-} +- +-FILE *__wrap_fdopen(int fd, const char *mode) +-{ +- assert_int_equal(fd, TEST_FDNO); +- return TEST_FPTR; +-} +- +-int __wrap_fflush(FILE *f) +-{ +- assert_ptr_equal(f, TEST_FPTR); +- return 0; +-} +- +-int __wrap_fclose(FILE *f) +-{ +- assert_ptr_equal(f, TEST_FPTR); +- return 0; +-} +- + /* strbuf wrapper for the old format_devname() */ + static int __format_devname(char *name, int id, size_t len, const char *prefix) + { +@@ -466,22 +451,85 @@ static void mock_self_alias(const char *alias, const char *wwid) + expect_condlog(3, USED_STR(alias, wwid)); \ + } while(0) + +-static void mock_bindings_file(const char *content, int match_line) ++static int add_binding_unsorted(Bindings *bindings, ++ const char *alias, const char *wwid) ++{ ++ struct binding *bdg = calloc(1, sizeof(*bdg)); ++ ++ if (!bdg) ++ return -1; ++ bdg->wwid = strdup(wwid); ++ bdg->alias = strdup(alias); ++ if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { ++ free(bdg->alias); ++ free(bdg->wwid); ++ free(bdg); ++ return BINDING_ERROR; ++ } ++ vector_set_slot(bindings, bdg); ++ return BINDING_ADDED; ++} ++ ++static void __mock_bindings_file(const char *content, ++ int (*add)(Bindings *, const char *, const char *)) + { +- static char cnt[1024]; +- char *token; ++ char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; ++ char *token, *savep = NULL; + int i; + +- assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); ++ cnt = strdup(content); ++ assert_ptr_not_equal(cnt, NULL); + +- for (token = strtok(cnt, "\n"), i = 0; ++ for (token = strtok_r(cnt, "\n", &savep), i = 0; + token && *token; +- token = strtok(NULL, "\n"), i++) { +- will_return(__wrap_fgets, token); +- if (match_line == i) +- return; ++ token = strtok_r(NULL, "\n", &savep), i++) { ++ char *alias, *wwid; ++ int rc; ++ ++ if (read_binding(token, i + 1, &alias, &wwid) ++ == READ_BINDING_SKIP) ++ continue; ++ ++ rc = add(&global_bindings, alias, wwid); ++ assert_int_equal(rc, BINDING_ADDED); + } +- will_return(__wrap_fgets, NULL); ++} ++ ++static void mock_bindings_file(const char *content) { ++ return __mock_bindings_file(content, add_binding); ++} ++ ++static void mock_bindings_file_unsorted(const char *content) { ++ return __mock_bindings_file(content, add_binding_unsorted); ++} ++ ++static int teardown_bindings(void **state) ++{ ++ cleanup_bindings(); ++ return 0; ++} ++ ++static int lookup_binding(FILE *dummy, const char *wwid, char **alias, ++ const char *prefix, int check_if_taken) ++{ ++ const struct binding *bdg; ++ int id; ++ ++ /* ++ * get_free_id() always checks if aliases are taken. ++ * Therefore if prefix is non-null, check_if_taken must be true. ++ */ ++ assert_true(!prefix || check_if_taken); ++ *alias = NULL; ++ bdg = get_binding_for_wwid(&global_bindings, wwid); ++ if (bdg) { ++ *alias = strdup(bdg->alias); ++ return 0; ++ } else if (!prefix && check_if_taken) ++ return -1; ++ ++ id = get_free_id(&global_bindings, prefix, wwid); ++ return id; + } + + static void lb_empty(void **state) +@@ -489,7 +537,7 @@ static void lb_empty(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); + assert_int_equal(rc, 1); +@@ -501,7 +549,7 @@ static void lb_empty_unused(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +@@ -515,10 +563,10 @@ static void lb_empty_failed(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_failed_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -530,10 +578,10 @@ static void lb_empty_1_used(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -545,10 +593,10 @@ static void lb_empty_1_used_self(void **state) + int rc; + char *alias; + +- mock_bindings_file("", -1); ++ mock_bindings_file(""); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_used_alias("MPATHa", "WWID0"); + mock_self_alias("MPATHb", "WWID0"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +@@ -560,9 +608,9 @@ static void lb_match_a(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", 0); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); +- rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); ++ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); +@@ -574,9 +622,10 @@ static void lb_nomatch_a(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); +- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); ++ mock_unused_alias("MPATHb"); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -586,8 +635,8 @@ static void lb_nomatch_a_bad_check(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); +- expect_condlog(0, NOMORE_STR); ++ mock_bindings_file("MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +@@ -598,7 +647,7 @@ static void lb_nomatch_a_unused(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +@@ -611,27 +660,27 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + int rc; + char *alias; + +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + mock_used_alias("MPATHb", "WWID1"); + mock_used_alias("MPATHc", "WWID1"); + mock_used_alias("MPATHd", "WWID1"); + mock_failed_alias("MPATHe", "WWID1"); + mock_self_alias("MPATHf", "WWID1"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); + } + +-static void do_lb_match_c(void **state, int check_if_taken) ++static void do_lb_match_c(void **state) + { + int rc; + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHc WWID1", 1); ++ "MPATHc WWID1"); + expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); +- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); ++ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHc"); +@@ -640,12 +689,12 @@ static void do_lb_match_c(void **state, int check_if_taken) + + static void lb_match_c(void **state) + { +- do_lb_match_c(state, 0); ++ do_lb_match_c(state); + } + + static void lb_match_c_check(void **state) + { +- do_lb_match_c(state, 1); ++ do_lb_match_c(state); + } + + static void lb_nomatch_a_c(void **state) +@@ -654,9 +703,10 @@ static void lb_nomatch_a_c(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHc WWID1", -1); ++ "MPATHc WWID1"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ mock_unused_alias("MPATHb"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -667,7 +717,7 @@ static void lb_nomatch_a_d_unused(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -681,10 +731,10 @@ static void lb_nomatch_a_d_1_used(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHc"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +@@ -696,11 +746,11 @@ static void lb_nomatch_a_d_2_used(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_unused_alias("MPATHe"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -712,12 +762,12 @@ static void lb_nomatch_a_d_3_used(void **state) + char *alias; + + mock_bindings_file("MPATHa WWID0\n" +- "MPATHd WWID1", -1); ++ "MPATHd WWID1"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_used_alias("MPATHc", "WWID2"); + mock_used_alias("MPATHe", "WWID2"); + mock_unused_alias("MPATHf"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 6); + assert_ptr_equal(alias, NULL); +@@ -729,9 +779,10 @@ static void lb_nomatch_c_a(void **state) + char *alias; + + mock_bindings_file("MPATHc WWID1\n" +- "MPATHa WWID0\n", -1); ++ "MPATHa WWID0\n"); ++ mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } +@@ -743,7 +794,7 @@ static void lb_nomatch_d_a_unused(void **state) + + mock_bindings_file("MPATHc WWID1\n" + "MPATHa WWID0\n" +- "MPATHd WWID0\n", -1); ++ "MPATHd WWID0\n"); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +@@ -758,10 +809,10 @@ static void lb_nomatch_d_a_1_used(void **state) + + mock_bindings_file("MPATHc WWID1\n" + "MPATHa WWID0\n" +- "MPATHd WWID0\n", -1); ++ "MPATHd WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + mock_used_alias("MPATHb", "WWID2"); + mock_unused_alias("MPATHe"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); +@@ -774,9 +825,10 @@ static void lb_nomatch_a_b(void **state) + + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb WWID1\n", -1); ++ "MPATHb WWID1\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ mock_unused_alias("MPATHc"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } +@@ -786,13 +838,19 @@ static void lb_nomatch_a_b_bad(void **state) + int rc; + char *alias; + ++ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); ++ /* ++ * The broken line will be ignored when constructing the bindings vector. ++ * Thus in lookup_binding() MPATHb is never encountered, ++ * and MPATHb appears usable. ++ */ + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb\n", -1); +- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); ++ "MPATHb\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); +- assert_int_equal(rc, 3); ++ mock_unused_alias("MPATHb"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } + +@@ -801,84 +859,200 @@ static void lb_nomatch_a_b_bad_self(void **state) + int rc; + char *alias; + ++ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb\n", -1); +- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); +- mock_self_alias("MPATHc", "WWID2"); ++ "MPATHb\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_self_alias("MPATHb", "WWID2"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +- assert_int_equal(rc, 3); ++ assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_b_a(void **state) ++static void lb_nomatch_b_z_a(void **state) + { + int rc; + char *alias; + ++ /* ++ * add_bindings() sorts alphabetically. Therefore get_free_id() ++ * finds MPATHc as a free entry. ++ */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" +- "MPATHa WWID0\n", -1); ++ "MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); +- assert_int_equal(rc, 27); ++ mock_unused_alias("MPATHc"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_b_a_3_used(void **state) ++static void lb_nomatch_b_aa_a(void **state) + { + int rc; + char *alias; + ++ /* ++ * add_bindings() sorts alphabetically. ("a", "aa", b"). ++ * The get_free_id() algorithm finds the "hole" after "b". ++ */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" +- "MPATHa WWID0\n", -1); +- mock_used_alias("MPATHaa", "WWID2"); +- mock_used_alias("MPATHab", "WWID2"); +- mock_used_alias("MPATHac", "WWID2"); +- mock_unused_alias("MPATHad"); ++ "MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_unused_alias("MPATHc"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +- assert_int_equal(rc, 30); ++ assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } + +-#ifdef MPATH_ID_INT_MAX +-static void do_lb_nomatch_int_max(void **state, int check_if_taken) ++static void fill_bindings(struct strbuf *buf, int start, int end) ++{ ++ int i; ++ ++ for (i = start; i <= end; i++) { ++ print_strbuf(buf, "MPATH"); ++ format_devname(buf, i + 1); ++ print_strbuf(buf, " WWID%d\n", i); ++ } ++} ++ ++static void lb_nomatch_b_a_aa(void **state) ++{ ++ int rc; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ /* ++ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) ++ * lookup_binding finds MPATHac as next free entry. ++ */ ++ fill_bindings(&buf, 0, 26); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); ++ mock_unused_alias("MPATHab"); ++ rc = lookup_binding(NULL, "WWID28", &alias, "MPATH", 1); ++ assert_int_equal(rc, 28); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_b_a_aa_zz(void **state) ++{ ++ int rc, i; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ /* ++ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) ++ * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is ++ * found before MPATHb, and MPATHzz was in the bindings, too. ++ */ ++ for (i = 0; i <= 26; i++) { ++ print_strbuf(&buf, "MPATH"); ++ format_devname(&buf, i + 1); ++ print_strbuf(&buf, " WWID%d\n", i); ++ } ++ print_strbuf(&buf, "MPATHzz WWID676\n"); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID703")); ++ mock_unused_alias("MPATHaaa"); ++ rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); ++ assert_int_equal(rc, 703); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_b_z_a_unsorted(void **state) ++{ ++ int rc; ++ char *alias; ++ ++ /* ++ * With unsorted bindings (shouldn't happen normally), get_free_id() ++ * plays safe and returns MPATHaa as first free entry. ++ */ ++ mock_bindings_file_unsorted("MPATHb WWID1\n" ++ "MPATHz WWID26\n" ++ "MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_unused_alias("MPATHaa"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 27); ++ assert_ptr_equal(alias, NULL); ++} ++ ++static void lb_nomatch_b_a(void **state) + { + int rc; + char *alias; + + mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" +- "MPATHa WWID0\n", -1); +- expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); +- assert_int_equal(rc, -1); ++ "MPATHa WWID0\n"); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); ++ mock_unused_alias("MPATHc"); ++ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_int_max(void **state) ++static void lb_nomatch_b_a_3_used(void **state) + { +- do_lb_nomatch_int_max(state, 0); ++ int rc; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ fill_bindings(&buf, 0, 26); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID31")); ++ mock_used_alias("MPATHab", "WWID31"); ++ mock_used_alias("MPATHac", "WWID31"); ++ mock_used_alias("MPATHad", "WWID31"); ++ mock_unused_alias("MPATHae"); ++ rc = lookup_binding(NULL, "WWID31", &alias, "MPATH", 1); ++ assert_int_equal(rc, 31); ++ assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_int_max_check(void **state) ++#ifdef MPATH_ID_INT_MAX ++/* ++ * The bindings will be sorted by alias, alphabetically, which is not ++ * the same as the "numeric" sort order for user-friendly aliases. ++ * get_free_id() selects the highest used ID + 1 if an unsorted entry ++ * is encountered in the bindings table and it's id is equal to the ++ * next "expected" id. This happens if all IDs from "a" to "aa" are ++ * in the table. If the INT_MAX entry is in the table, too, it will ++ * overflow. ++ */ ++static void lb_nomatch_int_max(void **state) + { +- do_lb_nomatch_int_max(state, 1); ++ int rc; ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ fill_bindings(&buf, 0, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); ++ expect_condlog(0, NOMORE_STR); ++ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); ++ assert_int_equal(rc, -1); ++ assert_ptr_equal(alias, NULL); + } + + static void lb_nomatch_int_max_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); +- mock_used_alias("MPATHa", "WWID2"); ++ fill_bindings(&buf, 1, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); ++ mock_used_alias("MPATHa", "WWIDNOMORE"); + expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -887,12 +1061,14 @@ static void lb_nomatch_int_max_m1(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" +- "MPATHa WWID0\n", -1); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); ++ fill_bindings(&buf, 0, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_unused_alias("MPATH" MPATH_ID_INT_MAX); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); + } +@@ -901,13 +1077,15 @@ static void lb_nomatch_int_max_m1_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" +- "MPATHa WWID0\n", -1); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); ++ fill_bindings(&buf, 0, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); + expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -916,13 +1094,15 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); +- mock_used_alias("MPATHa", "WWID2"); ++ fill_bindings(&buf, 1, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_used_alias("MPATHa", "WWIDMAX"); + mock_unused_alias("MPATH" MPATH_ID_INT_MAX); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); + } +@@ -931,13 +1111,17 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + { + int rc; + char *alias; ++ STRBUF_ON_STACK(buf); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); +- mock_used_alias("MPATHa", "WWID2"); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); ++ fill_bindings(&buf, 1, 26); ++ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ ++ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); ++ mock_used_alias("MPATHa", "WWIDMAX"); ++ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); + expect_condlog(0, NOMORE_STR); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); ++ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); + } +@@ -946,52 +1130,68 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + static int test_lookup_binding(void) + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(lb_empty), +- cmocka_unit_test(lb_empty_unused), +- cmocka_unit_test(lb_empty_failed), +- cmocka_unit_test(lb_empty_1_used), +- cmocka_unit_test(lb_empty_1_used_self), +- cmocka_unit_test(lb_match_a), +- cmocka_unit_test(lb_nomatch_a), +- cmocka_unit_test(lb_nomatch_a_bad_check), +- cmocka_unit_test(lb_nomatch_a_unused), +- cmocka_unit_test(lb_nomatch_a_3_used_failed_self), +- cmocka_unit_test(lb_match_c), +- cmocka_unit_test(lb_match_c_check), +- cmocka_unit_test(lb_nomatch_a_c), +- cmocka_unit_test(lb_nomatch_a_d_unused), +- cmocka_unit_test(lb_nomatch_a_d_1_used), +- cmocka_unit_test(lb_nomatch_a_d_2_used), +- cmocka_unit_test(lb_nomatch_a_d_3_used), +- cmocka_unit_test(lb_nomatch_c_a), +- cmocka_unit_test(lb_nomatch_d_a_unused), +- cmocka_unit_test(lb_nomatch_d_a_1_used), +- cmocka_unit_test(lb_nomatch_a_b), +- cmocka_unit_test(lb_nomatch_a_b_bad), +- cmocka_unit_test(lb_nomatch_a_b_bad_self), +- cmocka_unit_test(lb_nomatch_b_a), +- cmocka_unit_test(lb_nomatch_b_a_3_used), ++ cmocka_unit_test_teardown(lb_empty, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_failed, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_empty_1_used_self, teardown_bindings), ++ cmocka_unit_test_teardown(lb_match_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_bad_check, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_3_used_failed_self, teardown_bindings), ++ cmocka_unit_test_teardown(lb_match_c, teardown_bindings), ++ cmocka_unit_test_teardown(lb_match_c_check, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_c, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_2_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_d_3_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_c_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_d_a_unused, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_d_a_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_b, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_b_bad, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_a_b_bad_self, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_z_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), + #ifdef MPATH_ID_INT_MAX +- cmocka_unit_test(lb_nomatch_int_max), +- cmocka_unit_test(lb_nomatch_int_max_check), +- cmocka_unit_test(lb_nomatch_int_max_used), +- cmocka_unit_test(lb_nomatch_int_max_m1), +- cmocka_unit_test(lb_nomatch_int_max_m1_used), +- cmocka_unit_test(lb_nomatch_int_max_m1_1_used), +- cmocka_unit_test(lb_nomatch_int_max_m1_2_used), ++ cmocka_unit_test_teardown(lb_nomatch_int_max, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_1_used, teardown_bindings), ++ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_2_used, teardown_bindings), + #endif + }; + + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++static int rlookup_binding(FILE *dummy, char *buf, const char *alias) { ++ ++ const struct binding *bdg; ++ ++ bdg = get_binding_for_alias(&global_bindings, alias); ++ if (!bdg) { ++ return -1; ++ } ++ strlcpy(buf, bdg->wwid, WWID_SIZE); ++ return 0; ++} ++ + static void rl_empty(void **state) + { + int rc; + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1004,7 +1204,7 @@ static void rl_match_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("MPATHa WWID0\n", 0); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, 0); +@@ -1017,7 +1217,7 @@ static void rl_nomatch_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("MPATHa WWID0\n", -1); ++ mock_bindings_file("MPATHa WWID0\n"); + expect_condlog(3, NOMATCH_STR("MPATHb")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, -1); +@@ -1030,8 +1230,8 @@ static void rl_malformed_a(void **state) + char buf[WWID_SIZE]; + + buf[0] = '\0'; +- mock_bindings_file("MPATHa \n", -1); +- expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); ++ expect_condlog(1, "invalid line 1 in bindings file, missing WWID\n"); ++ mock_bindings_file("MPATHa \n"); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1049,8 +1249,8 @@ static void rl_overlong_a(void **state) + snprintf(line + sizeof(line) - 2, 2, "\n"); + + buf[0] = '\0'; +- mock_bindings_file(line, -1); + expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); ++ mock_bindings_file(line); + expect_condlog(3, NOMATCH_STR("MPATHa")); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); +@@ -1065,7 +1265,7 @@ static void rl_match_b(void **state) + buf[0] = '\0'; + mock_bindings_file("MPATHa WWID0\n" + "MPATHz WWID26\n" +- "MPATHb WWID2\n", 2); ++ "MPATHb WWID2\n"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, 0); +@@ -1075,31 +1275,41 @@ static void rl_match_b(void **state) + static int test_rlookup_binding(void) + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(rl_empty), +- cmocka_unit_test(rl_match_a), +- cmocka_unit_test(rl_nomatch_a), +- cmocka_unit_test(rl_malformed_a), +- cmocka_unit_test(rl_overlong_a), +- cmocka_unit_test(rl_match_b), ++ cmocka_unit_test_teardown(rl_empty, teardown_bindings), ++ cmocka_unit_test_teardown(rl_match_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_nomatch_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_malformed_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_overlong_a, teardown_bindings), ++ cmocka_unit_test_teardown(rl_match_b, teardown_bindings), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++void check_bindings_size(int n) ++{ ++ /* avoid -Waddress problem */ ++ Bindings *bindings = &global_bindings; ++ ++ assert_int_equal(VECTOR_SIZE(bindings), n); ++} ++ + static void al_a(void **state) + { + static const char ln[] = "MPATHa WWIDa\n"; + char *alias; + +- will_return(__wrap_lseek, 0); +- expect_value(__wrap_write, count, strlen(ln)); +- expect_string(__wrap_write, buf, ln); +- will_return(__wrap_write, strlen(ln)); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_rename, 0); ++ expect_condlog(1, "updated bindings file foo"); + expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); + +- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); ++ check_bindings_size(1); + free(alias); + } + +@@ -1108,15 +1318,17 @@ static void al_zz(void **state) + static const char ln[] = "MPATHzz WWIDzz\n"; + char *alias; + +- will_return(__wrap_lseek, 0); +- expect_value(__wrap_write, count, strlen(ln)); +- expect_string(__wrap_write, buf, ln); +- will_return(__wrap_write, strlen(ln)); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_rename, 0); ++ expect_condlog(1, "updated bindings file foo"); + expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); + +- alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); ++ alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHzz"); ++ check_bindings_size(1); + free(alias); + } + +@@ -1127,6 +1339,7 @@ static void al_0(void **state) + expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); + alias = allocate_binding(0, "WWIDa", 0, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); + } + + static void al_m2(void **state) +@@ -1136,67 +1349,133 @@ static void al_m2(void **state) + expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); + alias = allocate_binding(0, "WWIDa", -2, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); ++} ++ ++static void al_write_partial(void **state) ++{ ++ static const char ln[] = "MPATHa WWIDa\n"; ++ char *alias; ++ ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); ++ expect_value(__wrap_write, count, 1); ++ will_return(__wrap_write, ln + sizeof(ln) - 2); ++ will_return(__wrap_write, 1); ++ will_return(__wrap_rename, 0); ++ expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); ++ ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ assert_ptr_not_equal(alias, NULL); ++ assert_string_equal(alias, "MPATHa"); ++ check_bindings_size(1); ++ free(alias); + } + +-static void al_lseek_err(void **state) ++static void al_write_short(void **state) + { ++ static const char ln[] = "MPATHa WWIDa\n"; + char *alias; + +- will_return(__wrap_lseek, -ENODEV); +- expect_condlog(0, "Cannot seek to end of bindings file : No such device\n"); +- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); ++ expect_value(__wrap_write, count, 1); ++ will_return(__wrap_write, ln + sizeof(ln) - 2); ++ will_return(__wrap_write, 0); ++ expect_condlog(2, "write_bindings_file: short write"); ++ expect_condlog(1, "failed to write new bindings file"); ++ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); ++ ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); + } + + static void al_write_err(void **state) + { + static const char ln[] = "MPATHa WWIDa\n"; +- const int offset = 20; + char *alias; + +- will_return(__wrap_lseek, offset); +- expect_value(__wrap_write, count, strlen(ln)); +- expect_string(__wrap_write, buf, ln); +- will_return(__wrap_write, strlen(ln) - 1); +- expect_value(__wrap_ftruncate, length, offset); +- will_return(__wrap_ftruncate, 0); +- expect_condlog(0, "Cannot write binding to bindings file :"); ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, -EPERM); ++ expect_condlog(1, "failed to write new bindings file"); ++ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); + +- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); ++} ++ ++static void al_rename_err(void **state) ++{ ++ static const char ln[] = "MPATHa WWIDa\n"; ++ char *alias; ++ ++ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_write, ln); ++ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); ++ will_return(__wrap_rename, -EROFS); ++ ++ expect_condlog(0, "update_bindings_file: rename: Read-only file system"); ++ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); ++ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ assert_ptr_equal(alias, NULL); ++ check_bindings_size(0); + } + + static int test_allocate_binding(void) + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(al_a), +- cmocka_unit_test(al_zz), +- cmocka_unit_test(al_0), +- cmocka_unit_test(al_m2), +- cmocka_unit_test(al_lseek_err), +- cmocka_unit_test(al_write_err), ++ cmocka_unit_test_teardown(al_a, teardown_bindings), ++ cmocka_unit_test_teardown(al_zz, teardown_bindings), ++ cmocka_unit_test_teardown(al_0, teardown_bindings), ++ cmocka_unit_test_teardown(al_m2, teardown_bindings), ++ cmocka_unit_test_teardown(al_write_partial, teardown_bindings), ++ cmocka_unit_test_teardown(al_write_short, teardown_bindings), ++ cmocka_unit_test_teardown(al_write_err, teardown_bindings), ++ cmocka_unit_test_teardown(al_rename_err, teardown_bindings), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); + } + +-#define mock_allocate_binding(alias, wwid) \ ++#define mock_allocate_binding_err_len(alias, wwid, len, err, msg) \ + do { \ + static const char ln[] = BINDING_STR(alias, wwid); \ + \ +- will_return(__wrap_lseek, 0); \ +- expect_value(__wrap_write, count, strlen(ln)); \ +- expect_string(__wrap_write, buf, ln); \ +- will_return(__wrap_write, strlen(ln)); \ +- expect_condlog(3, NEW_STR(alias, wwid)); \ ++ expect_value(__wrap_write, count, \ ++ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ ++ will_return(__wrap_write, ln); \ ++ will_return(__wrap_write, \ ++ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ ++ will_return(__wrap_rename, err); \ ++ if (err == 0) { \ ++ expect_condlog(1, "updated bindings file x\n"); \ ++ expect_condlog(3, NEW_STR(alias, wwid)); \ ++ } else { \ ++ expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ ++ expect_condlog(1, "allocate_binding: deleting binding " \ ++ alias " for " wwid "\n"); \ ++ } \ + } while (0) + ++#define mock_allocate_binding_err(alias, wwid, err, msg) \ ++ mock_allocate_binding_err_len(alias, wwid, 0, err, msg) ++ ++#define mock_allocate_binding(alias, wwid) \ ++ mock_allocate_binding_err(alias, wwid, 0, "") ++ ++#define mock_allocate_binding_len(alias, wwid, len) \ ++ mock_allocate_binding_err_len(alias, wwid, len, 0, "") ++ + static void gufa_empty_new_rw(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +@@ -1208,10 +1487,11 @@ static void gufa_empty_new_rw(void **state) { + + static void gufa_empty_new_ro_1(void **state) { + char *alias; +- will_return(__wrap_open_file, false); +- mock_bindings_file("", -1); ++ ++ mock_bindings_file(""); + mock_unused_alias("MPATHa"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); + assert_ptr_equal(alias, NULL); +@@ -1220,11 +1500,9 @@ static void gufa_empty_new_ro_1(void **state) { + static void gufa_empty_new_ro_2(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("", -1); +- mock_unused_alias("MPATHa"); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHa"); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_ptr_equal(alias, NULL); +@@ -1233,11 +1511,10 @@ static void gufa_empty_new_ro_2(void **state) { + static void gufa_match_a_unused(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("MPATHa WWID0", 0); ++ mock_bindings_file("MPATHa WWID0"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHa"); ++ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); +@@ -1247,11 +1524,10 @@ static void gufa_match_a_unused(void **state) { + static void gufa_match_a_self(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file("MPATHa WWID0", 0); ++ mock_bindings_file("MPATHa WWID0"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_self_alias("MPATHa", "WWID0"); ++ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); +@@ -1261,9 +1537,8 @@ static void gufa_match_a_self(void **state) { + static void gufa_match_a_used(void **state) { + char *alias; + +- will_return(__wrap_open_file, true); + +- mock_bindings_file("MPATHa WWID0", 0); ++ mock_bindings_file("MPATHa WWID0"); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +@@ -1273,15 +1548,14 @@ static void gufa_match_a_used(void **state) { + + static void gufa_nomatch_a_c(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ static const char bindings[] = ("MPATHa WWID0\n" ++ "MPATHc WWID2\n"); + +- mock_bindings_file("MPATHa WWID0\n" +- "MPATHc WWID2", +- -1); ++ mock_bindings_file(bindings); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + +- mock_allocate_binding("MPATHb", "WWID1"); ++ mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); + + alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); +@@ -1290,15 +1564,14 @@ static void gufa_nomatch_a_c(void **state) { + + static void gufa_nomatch_c_a(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHc WWID2\n" ++ "MPATHa WWID0\n"); + +- mock_bindings_file("MPATHc WWID2\n" +- "MPATHa WWID0", +- -1); ++ mock_bindings_file(bindings); + mock_unused_alias("MPATHb"); + expect_condlog(3, NOMATCH_WWID_STR("WWID1")); + +- mock_allocate_binding("MPATHb", "WWID1"); ++ mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); +@@ -1307,15 +1580,14 @@ static void gufa_nomatch_c_a(void **state) { + + static void gufa_nomatch_c_b(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHc WWID2\n" ++ "MPATHb WWID1\n"); + +- mock_bindings_file("MPATHc WWID2\n" +- "MPATHb WWID1\n", +- -1); +- mock_unused_alias("MPATHa"); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_unused_alias("MPATHa"); + +- mock_allocate_binding("MPATHa", "WWID0"); ++ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHa"); +@@ -1324,16 +1596,15 @@ static void gufa_nomatch_c_b(void **state) { + + static void gufa_nomatch_c_b_used(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHc WWID2\n" ++ "MPATHb WWID1\n"); + +- mock_bindings_file("MPATHc WWID2\n" +- "MPATHb WWID1", +- -1); +- mock_used_alias("MPATHa", "WWID4"); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID4")); ++ mock_used_alias("MPATHa", "WWID4"); + mock_unused_alias("MPATHd"); + +- mock_allocate_binding("MPATHd", "WWID4"); ++ mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHd"); +@@ -1342,32 +1613,59 @@ static void gufa_nomatch_c_b_used(void **state) { + + static void gufa_nomatch_b_f_a(void **state) { + char *alias; +- will_return(__wrap_open_file, true); ++ const char bindings[] = ("MPATHb WWID1\n" ++ "MPATHf WWID6\n" ++ "MPATHa WWID0\n"); + +- mock_bindings_file("MPATHb WWID1\n" +- "MPATHf WWID6\n" +- "MPATHa WWID0\n", +- -1); ++ mock_bindings_file_unsorted(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID7")); + mock_unused_alias("MPATHg"); + +- mock_allocate_binding("MPATHg", "WWID7"); ++ mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); + assert_string_equal(alias, "MPATHg"); + free(alias); + } + ++static void gufa_nomatch_b_aa_a(void **state) { ++ char *alias; ++ STRBUF_ON_STACK(buf); ++ ++ fill_bindings(&buf, 0, 26); ++ mock_bindings_file(get_strbuf_str(&buf)); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); ++ mock_unused_alias("MPATHab"); ++ mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); ++ ++ alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHab"); ++ free(alias); ++} ++ ++static void gufa_nomatch_b_f_a_sorted(void **state) { ++ char *alias; ++ const char bindings[] = ("MPATHb WWID1\n" ++ "MPATHf WWID6\n" ++ "MPATHa WWID0\n"); ++ ++ mock_bindings_file(bindings); ++ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); ++ mock_unused_alias("MPATHc"); ++ ++ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); ++ ++ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ assert_string_equal(alias, "MPATHc"); ++ free(alias); ++} ++ + static void gufa_old_empty(void **state) { + char *alias; +- will_return(__wrap_open_file, true); + + /* rlookup_binding for ALIAS */ +- mock_bindings_file("", -1); ++ mock_bindings_file(""); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- /* lookup_binding */ +- mock_bindings_file("", -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + + mock_allocate_binding("MPATHz", "WWID0"); +@@ -1380,11 +1678,9 @@ static void gufa_old_empty(void **state) { + + static void gufa_old_match(void **state) { + char *alias; +- will_return(__wrap_open_file, true); + + mock_bindings_file("MPATHb WWID1\n" +- "MPATHz WWID0", +- 1); ++ "MPATHz WWID0"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); +@@ -1394,19 +1690,15 @@ static void gufa_old_match(void **state) { + + static void gufa_old_match_other(void **state) { + char *alias; +- static const char bindings[] = "MPATHz WWID9"; +- +- will_return(__wrap_open_file, true); ++ static const char bindings[] = "MPATHz WWID9\n"; + +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_unused_alias("MPATHa"); + +- mock_allocate_binding("MPATHa", "WWID0"); ++ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHa"); +@@ -1415,21 +1707,16 @@ static void gufa_old_match_other(void **state) { + + static void gufa_old_match_other_used(void **state) { + char *alias; +- static const char bindings[] = "MPATHz WWID9"; ++ static const char bindings[] = "MPATHz WWID9\n"; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, -1); +- mock_used_alias("MPATHa", "WWID0"); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); ++ mock_used_alias("MPATHa", "WWID0"); + mock_unused_alias("MPATHb"); + +- mock_allocate_binding("MPATHb", "WWID0"); +- ++ mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); +@@ -1439,15 +1726,13 @@ static void gufa_old_match_other_wwidmatch(void **state) { + char *alias; + static const char bindings[] = ("MPATHz WWID9\n" + "MPATHc WWID2"); +- will_return(__wrap_open_file, true); + +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); + mock_unused_alias("MPATHc"); ++ expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); + + alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHc"); +@@ -1459,13 +1744,9 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { + static const char bindings[] = ("MPATHz WWID9\n" + "MPATHc WWID2"); + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file(bindings, 0); ++ mock_bindings_file(bindings); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); + expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); +- +- mock_bindings_file(bindings, 1); + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); + mock_used_alias("MPATHc", "WWID2"); + +@@ -1477,12 +1758,8 @@ static void gufa_old_nomatch_wwidmatch(void **state) { + char *alias; + static const char bindings[] = "MPATHa WWID0"; + +- will_return(__wrap_open_file, true); +- +- mock_bindings_file(bindings, -1); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- mock_bindings_file(bindings, 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_unused_alias("MPATHa"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); +@@ -1495,12 +1772,9 @@ static void gufa_old_nomatch_wwidmatch(void **state) { + static void gufa_old_nomatch_wwidmatch_used(void **state) { + char *alias; + static const char bindings[] = "MPATHa WWID0"; +- will_return(__wrap_open_file, true); + +- mock_bindings_file(bindings, -1); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- mock_bindings_file(bindings, 0); + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +@@ -1510,17 +1784,13 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { + + static void gufa_old_nomatch_nowwidmatch(void **state) { + char *alias; +- static const char bindings[] = "MPATHb WWID1"; +- +- will_return(__wrap_open_file, true); ++ static const char bindings[] = "MPATHb WWID1\n"; + +- mock_bindings_file(bindings, -1); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_STR("MPATHz")); +- +- mock_bindings_file(bindings, -1); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + +- mock_allocate_binding("MPATHz", "WWID0"); ++ mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); + expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); + + alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); +@@ -1531,26 +1801,28 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { + static int test_get_user_friendly_alias() + { + const struct CMUnitTest tests[] = { +- cmocka_unit_test(gufa_empty_new_rw), +- cmocka_unit_test(gufa_empty_new_ro_1), +- cmocka_unit_test(gufa_empty_new_ro_2), +- cmocka_unit_test(gufa_match_a_unused), +- cmocka_unit_test(gufa_match_a_self), +- cmocka_unit_test(gufa_match_a_used), +- cmocka_unit_test(gufa_nomatch_a_c), +- cmocka_unit_test(gufa_nomatch_c_a), +- cmocka_unit_test(gufa_nomatch_c_b), +- cmocka_unit_test(gufa_nomatch_c_b_used), +- cmocka_unit_test(gufa_nomatch_b_f_a), +- cmocka_unit_test(gufa_old_empty), +- cmocka_unit_test(gufa_old_match), +- cmocka_unit_test(gufa_old_match_other), +- cmocka_unit_test(gufa_old_match_other_used), +- cmocka_unit_test(gufa_old_match_other_wwidmatch), +- cmocka_unit_test(gufa_old_match_other_wwidmatch_used), +- cmocka_unit_test(gufa_old_nomatch_wwidmatch), +- cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), +- cmocka_unit_test(gufa_old_nomatch_nowwidmatch), ++ cmocka_unit_test_teardown(gufa_empty_new_rw, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_empty_new_ro_1, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_empty_new_ro_2, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_match_a_unused, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_match_a_self, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_match_a_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_a_c, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_c_a, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_c_b, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_c_b_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_b_f_a, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_b_aa_a, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_nomatch_b_f_a_sorted, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_empty, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), ++ cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +@@ -1566,7 +1838,6 @@ int main(void) + ret += test_lookup_binding(); + ret += test_rlookup_binding(); + ret += test_allocate_binding(); +- ret += test_allocate_binding(); + ret += test_get_user_friendly_alias(); + + return ret; diff --git a/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch b/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch new file mode 100644 index 0000000..c105b01 --- /dev/null +++ b/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 25 Aug 2023 20:35:19 +0200 +Subject: [PATCH] libmultipath: dm_get_uuid(): return emtpy UUID for + non-existing maps + +libdevmapper will most probably not return a UUID for non-existing +maps anyway. But it's cheap to double-check here. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 248c3734..9be82f4e 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -706,12 +706,16 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) + { + struct dm_task *dmt; + const char *uuidtmp; ++ struct dm_info info; + int r = 1; + + dmt = libmp_dm_task_create(DM_DEVICE_INFO); + if (!dmt) + return 1; + ++ if (uuid_len > 0) ++ uuid[0] = '\0'; ++ + if (!dm_task_set_name (dmt, name)) + goto uuidout; + +@@ -720,11 +724,13 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) + goto uuidout; + } + ++ if (!dm_task_get_info(dmt, &info) || ++ !info.exists) ++ goto uuidout; ++ + uuidtmp = dm_task_get_uuid(dmt); + if (uuidtmp) + strlcpy(uuid, uuidtmp, uuid_len); +- else +- uuid[0] = '\0'; + + r = 0; + uuidout: diff --git a/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch b/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch new file mode 100644 index 0000000..4d15554 --- /dev/null +++ b/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch @@ -0,0 +1,158 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 28 Aug 2023 12:26:37 +0200 +Subject: [PATCH] libmultipath: adapt to new semantics of dm_get_uuid() + +dm_get_uuid() will return 1 for non-existing maps. Thus we don't need +to call dm_map_present() any more in alias_already_taken(). This changes +our semantics: previously we'd avoid using an alias for which dm_get_uuid() +had failed. Now we treat failure in dm_get_uuid() as indication that the +map doesn't exist. This is not dangerous because dm_task_get_uuid() cannot +fail, and thus the modified dm_get_uuid() will fail if and only if +dm_map_present() would return false. + +This makes the "failed alias" test mostly obsolete, as "failed" is now +treated as "unused". + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 25 +++++++++++++------------ + tests/alias.c | 32 +++++++------------------------- + 2 files changed, 20 insertions(+), 37 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index d6563749..58436ec0 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -295,18 +295,19 @@ scan_devname(const char *alias, const char *prefix) + static bool alias_already_taken(const char *alias, const char *map_wwid) + { + +- if (dm_map_present(alias)) { +- char wwid[WWID_SIZE]; +- +- /* If both the name and the wwid match, then it's fine.*/ +- if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && +- strncmp(map_wwid, wwid, sizeof(wwid)) == 0) +- return false; +- condlog(3, "%s: alias '%s' already taken, reselecting alias", +- map_wwid, alias); +- return true; +- } +- return false; ++ char wwid[WWID_SIZE]; ++ ++ /* If the map doesn't exist, it's fine */ ++ if (dm_get_uuid(alias, wwid, sizeof(wwid)) != 0) ++ return false; ++ ++ /* If both the name and the wwid match, it's fine.*/ ++ if (strncmp(map_wwid, wwid, sizeof(wwid)) == 0) ++ return false; ++ ++ condlog(3, "%s: alias '%s' already taken, reselecting alias", ++ map_wwid, alias); ++ return true; + } + + static bool id_already_taken(int id, const char *prefix, const char *map_wwid) +diff --git a/tests/alias.c b/tests/alias.c +index 50a21ecf..d1cc487b 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -73,12 +73,6 @@ int __wrap_mkstemp(char *template) + return 10; + } + +-int __wrap_dm_map_present(const char * str) +-{ +- check_expected(str); +- return mock_type(int); +-} +- + int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + { + int ret; +@@ -398,14 +392,13 @@ static int test_scan_devname(void) + + static void mock_unused_alias(const char *alias) + { +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 0); ++ expect_string(__wrap_dm_get_uuid, name, alias); ++ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); ++ will_return(__wrap_dm_get_uuid, 1); + } + + static void mock_self_alias(const char *alias, const char *wwid) + { +- expect_string(__wrap_dm_map_present, str, alias); +- will_return(__wrap_dm_map_present, 1); + expect_string(__wrap_dm_get_uuid, name, alias); + expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); + will_return(__wrap_dm_get_uuid, 0); +@@ -432,18 +425,13 @@ static void mock_self_alias(const char *alias, const char *wwid) + + #define mock_failed_alias(alias, wwid) \ + do { \ +- expect_string(__wrap_dm_map_present, str, alias); \ +- will_return(__wrap_dm_map_present, 1); \ + expect_string(__wrap_dm_get_uuid, name, alias); \ + expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ + will_return(__wrap_dm_get_uuid, 1); \ +- expect_condlog(3, USED_STR(alias, wwid)); \ + } while (0) + + #define mock_used_alias(alias, wwid) \ + do { \ +- expect_string(__wrap_dm_map_present, str, alias); \ +- will_return(__wrap_dm_map_present, 1); \ + expect_string(__wrap_dm_get_uuid, name, alias); \ + expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ + will_return(__wrap_dm_get_uuid, 0); \ +@@ -566,9 +554,8 @@ static void lb_empty_failed(void **state) + mock_bindings_file(""); + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_failed_alias("MPATHa", "WWID0"); +- mock_unused_alias("MPATHb"); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); +- assert_int_equal(rc, 2); ++ assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); + free(alias); + } +@@ -666,9 +653,8 @@ static void lb_nomatch_a_3_used_failed_self(void **state) + mock_used_alias("MPATHc", "WWID1"); + mock_used_alias("MPATHd", "WWID1"); + mock_failed_alias("MPATHe", "WWID1"); +- mock_self_alias("MPATHf", "WWID1"); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); +- assert_int_equal(rc, 6); ++ assert_int_equal(rc, 5); + assert_ptr_equal(alias, NULL); + } + +@@ -940,7 +926,7 @@ static void lb_nomatch_b_a_aa(void **state) + + static void lb_nomatch_b_a_aa_zz(void **state) + { +- int rc, i; ++ int rc; + char *alias; + STRBUF_ON_STACK(buf); + +@@ -949,11 +935,7 @@ static void lb_nomatch_b_a_aa_zz(void **state) + * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is + * found before MPATHb, and MPATHzz was in the bindings, too. + */ +- for (i = 0; i <= 26; i++) { +- print_strbuf(&buf, "MPATH"); +- format_devname(&buf, i + 1); +- print_strbuf(&buf, " WWID%d\n", i); +- } ++ fill_bindings(&buf, 0, 26); + print_strbuf(&buf, "MPATHzz WWID676\n"); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWID703")); diff --git a/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch b/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch new file mode 100644 index 0000000..1504bec --- /dev/null +++ b/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 15:19:54 +0200 +Subject: [PATCH] libmultipath: sort aliases by length and strcmp + +The current sort order of aliases is alphabetical, which is does not match +the actual order of aliases, where "mpathaa" > "mpathz". Change the ordering as +follows: first sort by string length, then alphabetically. This will make +sure that for aliases with the same prefix, alias order is correct ("mpathaaa" +will be sorted after "mpathzz", etc). Even for mixed prefixes, the alias +order will be correct for every individual prefix, even though aliases with +different prefixes may alternate in the file. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 45 +++++++++++++++++++++++++++++++++----------- + 1 file changed, 34 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 58436ec0..af6565b1 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -117,6 +117,35 @@ static const struct binding *get_binding_for_wwid(const Bindings *bindings, + return NULL; + } + ++/* ++ * Sort order for aliases. ++ * ++ * The "numeric" ordering of aliases for a given prefix P is ++ * Pa, ..., Pz, Paa, ..., Paz, Pba, ... , Pzz, Paaa, ..., Pzzz, Paaaa, ... ++ * We use the fact that for equal prefix, longer strings are always ++ * higher than shorter ones. Strings of equal length are sorted alphabetically. ++ * This is achieved by sorting be length first, then using strcmp(). ++ * If multiple prefixes are in use, the aliases with a given prefix will ++ * not necessarily be in a contiguous range of the vector, but they will ++ * be ordered such that for a given prefix, numercally higher aliases will ++ * always be sorted after lower ones. ++ */ ++static int alias_compar(const void *p1, const void *p2) ++{ ++ const char *alias1 = *((char * const *)p1); ++ const char *alias2 = *((char * const *)p2); ++ ++ if (alias1 && alias2) { ++ ssize_t ldif = strlen(alias1) - strlen(alias2); ++ ++ if (ldif) ++ return ldif; ++ return strcmp(alias1, alias2); ++ } else ++ /* Move NULL alias to the end */ ++ return alias1 ? -1 : alias2 ? 1 : 0; ++} ++ + static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + { + struct binding *bdg; +@@ -128,7 +157,7 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) + * sorted already. + */ + vector_foreach_slot_backwards(bindings, bdg, i) { +- if ((cmp = strcmp(bdg->alias, alias)) <= 0) ++ if ((cmp = alias_compar(&bdg->alias, &alias)) <= 0) + break; + } + +@@ -657,16 +686,10 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + return rc; + } + +-static int alias_compar(const void *p1, const void *p2) ++static int mp_alias_compar(const void *p1, const void *p2) + { +- const char *alias1 = (*(struct mpentry * const *)p1)->alias; +- const char *alias2 = (*(struct mpentry * const *)p2)->alias; +- +- if (alias1 && alias2) +- return strcmp(alias1, alias2); +- else +- /* Move NULL alias to the end */ +- return alias1 ? -1 : alias2 ? 1 : 0; ++ return alias_compar(&((*(struct mpentry * const *)p1)->alias), ++ &((*(struct mpentry * const *)p2)->alias)); + } + + /* +@@ -700,7 +723,7 @@ int check_alias_settings(const struct config *conf) + pthread_cleanup_push_cast(free_bindings, &bindings); + pthread_cleanup_push(cleanup_vector_free, mptable); + +- vector_sort(mptable, alias_compar); ++ vector_sort(mptable, mp_alias_compar); + vector_foreach_slot(mptable, mpe, i) { + if (!mpe->alias) + /* diff --git a/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch b/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch new file mode 100644 index 0000000..dd0f29d --- /dev/null +++ b/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 15:46:02 +0200 +Subject: [PATCH] multipath-tools tests: fix alias test after sort order change + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 30 ++++++++++++------------------ + 1 file changed, 12 insertions(+), 18 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index d1cc487b..8ed95d7a 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -932,16 +932,15 @@ static void lb_nomatch_b_a_aa_zz(void **state) + + /* + * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) +- * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is +- * found before MPATHb, and MPATHzz was in the bindings, too. ++ * lookup_binding finds MPATHab as next free entry. + */ + fill_bindings(&buf, 0, 26); + print_strbuf(&buf, "MPATHzz WWID676\n"); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWID703")); +- mock_unused_alias("MPATHaaa"); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); +- assert_int_equal(rc, 703); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -998,13 +997,8 @@ static void lb_nomatch_b_a_3_used(void **state) + + #ifdef MPATH_ID_INT_MAX + /* +- * The bindings will be sorted by alias, alphabetically, which is not +- * the same as the "numeric" sort order for user-friendly aliases. +- * get_free_id() selects the highest used ID + 1 if an unsorted entry +- * is encountered in the bindings table and it's id is equal to the +- * next "expected" id. This happens if all IDs from "a" to "aa" are +- * in the table. If the INT_MAX entry is in the table, too, it will +- * overflow. ++ * The bindings will be sorted by alias. Therefore we have no chance to ++ * simulate a "full" table. + */ + static void lb_nomatch_int_max(void **state) + { +@@ -1016,9 +1010,9 @@ static void lb_nomatch_int_max(void **state) + print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); +- expect_condlog(0, NOMORE_STR); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1049,9 +1043,9 @@ static void lb_nomatch_int_max_m1(void **state) + print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); +- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, INT_MAX); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1065,10 +1059,10 @@ static void lb_nomatch_int_max_m1_used(void **state) + print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); +- expect_condlog(0, NOMORE_STR); ++ mock_used_alias("MPATHab", "WWIDMAX"); ++ mock_unused_alias("MPATHac"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 29); + assert_ptr_equal(alias, NULL); + } + diff --git a/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch b/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch new file mode 100644 index 0000000..b16b3da --- /dev/null +++ b/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 19:50:51 +0200 +Subject: [PATCH] libmultipath: simplify get_free_id() assuming total ordering + +If we can assume that the bindings array is totally ordered for every +prefix, which the previous patch guarantees, the search for a free ID can be +simplified. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 85 ++++++++++---------------------------------- + 1 file changed, 18 insertions(+), 67 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index af6565b1..66e34e31 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -356,83 +356,34 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww + { + const struct binding *bdg; + int i, id = 1; +- int biggest_id = 1; +- int smallest_bigger_id = INT_MAX; + + vector_foreach_slot(bindings, bdg, i) { + int curr_id = scan_devname(bdg->alias, prefix); + +- /* +- * Find an unused index - explanation of the algorithm +- * +- * ID: 1 = mpatha, 2 = mpathb, ... +- * +- * We assume the bindings are unsorted. The only constraint +- * is that no ID occurs more than once. IDs that occur in the +- * bindings are called "used". +- * +- * We call the list 1,2,3,..., exactly in this order, the list +- * of "expected" IDs. The variable "id" always holds the next +- * "expected" ID, IOW the last "expected" ID encountered plus 1. +- * Thus all IDs below "id" are known to be used. However, at the +- * end of the loop, the value of "id" isn't necessarily unused. +- * +- * "smallest_bigger_id" is the smallest used ID that was +- * encountered while it was larger than the next "expected" ID +- * at that iteration. Let X be some used ID. If all IDs below X +- * are used and encountered in the right sequence before X, "id" +- * will be > X when the loop ends. Otherwise, X was encountered +- * "out of order", the condition (X > id) holds when X is +- * encountered, and "smallest_bigger_id" will be set to X; i.e. +- * it will be less or equal than X when the loop ends. +- * +- * At the end of the loop, (id < smallest_bigger_id) means that +- * the value of "id" had been encountered neither in order nor +- * out of order, and is thus unused. (id >= smallest_bigger_id) +- * means that "id"'s value is in use. In this case, we play safe +- * and use "biggest_id + 1" as the next value to try. +- * +- * biggest_id is always > smallest_bigger_id, except in the +- * "perfectly ordered" case. +- */ +- if (curr_id == id) { +- if (id < INT_MAX) +- id++; +- else { +- id = -1; +- break; +- } ++ if (curr_id == -1) ++ continue; ++ if (id > curr_id) { ++ condlog(0, "%s: ERROR: bindings are not sorted", __func__); ++ return -1; + } +- if (curr_id > biggest_id) +- biggest_id = curr_id; +- +- if (curr_id > id && curr_id < smallest_bigger_id) +- smallest_bigger_id = curr_id; ++ while (id < curr_id && id_already_taken(id, prefix, map_wwid)) ++ id++; ++ if (id < curr_id) ++ return id; ++ id++; ++ if (id <= 0) ++ break; + } + +- if (id >= smallest_bigger_id) +- id = biggest_id < INT_MAX ? biggest_id + 1 : -1; +- +- if (id > 0) { +- while(id_already_taken(id, prefix, map_wwid)) { +- if (id == INT_MAX) { +- id = -1; +- break; +- } +- id++; +- if (id == smallest_bigger_id) { +- if (biggest_id == INT_MAX) { +- id = -1; +- break; +- } +- if (biggest_id >= smallest_bigger_id) +- id = biggest_id + 1; +- } +- } ++ for (; id > 0; id++) { ++ if (!id_already_taken(id, prefix, map_wwid)) ++ break; + } + +- if (id < 0) ++ if (id <= 0) { ++ id = -1; + condlog(0, "no more available user_friendly_names"); ++ } + return id; + } + diff --git a/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch b/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch new file mode 100644 index 0000000..b1d6b15 --- /dev/null +++ b/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch @@ -0,0 +1,203 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 19:58:03 +0200 +Subject: [PATCH] multipath-tools tests: adapt alias tests for total ordering + +The "unsorted" test fail now, and are removed. The algorithm is now +better at finding "gaps". + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 88 ++++++++------------------------------------------- + 1 file changed, 14 insertions(+), 74 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index 8ed95d7a..dff5f93b 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -439,27 +439,7 @@ static void mock_self_alias(const char *alias, const char *wwid) + expect_condlog(3, USED_STR(alias, wwid)); \ + } while(0) + +-static int add_binding_unsorted(Bindings *bindings, +- const char *alias, const char *wwid) +-{ +- struct binding *bdg = calloc(1, sizeof(*bdg)); +- +- if (!bdg) +- return -1; +- bdg->wwid = strdup(wwid); +- bdg->alias = strdup(alias); +- if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { +- free(bdg->alias); +- free(bdg->wwid); +- free(bdg); +- return BINDING_ERROR; +- } +- vector_set_slot(bindings, bdg); +- return BINDING_ADDED; +-} +- +-static void __mock_bindings_file(const char *content, +- int (*add)(Bindings *, const char *, const char *)) ++static void __mock_bindings_file(const char *content) + { + char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; + char *token, *savep = NULL; +@@ -478,17 +458,13 @@ static void __mock_bindings_file(const char *content, + == READ_BINDING_SKIP) + continue; + +- rc = add(&global_bindings, alias, wwid); ++ rc = add_binding(&global_bindings, alias, wwid); + assert_int_equal(rc, BINDING_ADDED); + } + } + + static void mock_bindings_file(const char *content) { +- return __mock_bindings_file(content, add_binding); +-} +- +-static void mock_bindings_file_unsorted(const char *content) { +- return __mock_bindings_file(content, add_binding_unsorted); ++ return __mock_bindings_file(content); + } + + static int teardown_bindings(void **state) +@@ -861,10 +837,6 @@ static void lb_nomatch_b_z_a(void **state) + int rc; + char *alias; + +- /* +- * add_bindings() sorts alphabetically. Therefore get_free_id() +- * finds MPATHc as a free entry. +- */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" + "MPATHa WWID0\n"); +@@ -880,10 +852,6 @@ static void lb_nomatch_b_aa_a(void **state) + int rc; + char *alias; + +- /* +- * add_bindings() sorts alphabetically. ("a", "aa", b"). +- * The get_free_id() algorithm finds the "hole" after "b". +- */ + mock_bindings_file("MPATHb WWID1\n" + "MPATHz WWID26\n" + "MPATHa WWID0\n"); +@@ -911,10 +879,6 @@ static void lb_nomatch_b_a_aa(void **state) + char *alias; + STRBUF_ON_STACK(buf); + +- /* +- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) +- * lookup_binding finds MPATHac as next free entry. +- */ + fill_bindings(&buf, 0, 26); + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWID28")); +@@ -930,10 +894,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) + char *alias; + STRBUF_ON_STACK(buf); + +- /* +- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) +- * lookup_binding finds MPATHab as next free entry. +- */ + fill_bindings(&buf, 0, 26); + print_strbuf(&buf, "MPATHzz WWID676\n"); + mock_bindings_file(get_strbuf_str(&buf)); +@@ -944,25 +904,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) + assert_ptr_equal(alias, NULL); + } + +-static void lb_nomatch_b_z_a_unsorted(void **state) +-{ +- int rc; +- char *alias; +- +- /* +- * With unsorted bindings (shouldn't happen normally), get_free_id() +- * plays safe and returns MPATHaa as first free entry. +- */ +- mock_bindings_file_unsorted("MPATHb WWID1\n" +- "MPATHz WWID26\n" +- "MPATHa WWID0\n"); +- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); +- mock_unused_alias("MPATHaa"); +- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); +- assert_int_equal(rc, 27); +- assert_ptr_equal(alias, NULL); +-} +- + static void lb_nomatch_b_a(void **state) + { + int rc; +@@ -1027,9 +968,9 @@ static void lb_nomatch_int_max_used(void **state) + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); + mock_used_alias("MPATHa", "WWIDNOMORE"); +- expect_condlog(0, NOMORE_STR); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1077,9 +1018,9 @@ static void lb_nomatch_int_max_m1_1_used(void **state) + mock_bindings_file(get_strbuf_str(&buf)); + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); + mock_used_alias("MPATHa", "WWIDMAX"); +- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); ++ mock_unused_alias("MPATHab"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, INT_MAX); ++ assert_int_equal(rc, 28); + assert_ptr_equal(alias, NULL); + } + +@@ -1095,10 +1036,10 @@ static void lb_nomatch_int_max_m1_2_used(void **state) + + expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); + mock_used_alias("MPATHa", "WWIDMAX"); +- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); +- expect_condlog(0, NOMORE_STR); ++ mock_used_alias("MPATHab", "WWIDMAX"); ++ mock_unused_alias("MPATHac"); + rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); +- assert_int_equal(rc, -1); ++ assert_int_equal(rc, 29); + assert_ptr_equal(alias, NULL); + } + #endif +@@ -1133,7 +1074,6 @@ static int test_lookup_binding(void) + cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), +- cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), + cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), + #ifdef MPATH_ID_INT_MAX +@@ -1593,14 +1533,14 @@ static void gufa_nomatch_b_f_a(void **state) { + "MPATHf WWID6\n" + "MPATHa WWID0\n"); + +- mock_bindings_file_unsorted(bindings); ++ mock_bindings_file(bindings); + expect_condlog(3, NOMATCH_WWID_STR("WWID7")); +- mock_unused_alias("MPATHg"); ++ mock_unused_alias("MPATHc"); + +- mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); ++ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); + + alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); +- assert_string_equal(alias, "MPATHg"); ++ assert_string_equal(alias, "MPATHc"); + free(alias); + } + diff --git a/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch b/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch new file mode 100644 index 0000000..5317ef9 --- /dev/null +++ b/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch @@ -0,0 +1,275 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 21:39:44 +0200 +Subject: [PATCH] multipath-tools tests: add test for ordering of bindings + +As the assignment of free aliases now relies on the bindings being +properly sorted, add some unit tests to make sure the sorting algorithm +works. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/alias.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 209 insertions(+), 3 deletions(-) + +diff --git a/tests/alias.c b/tests/alias.c +index dff5f93b..7f3ff38a 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -13,6 +13,9 @@ + #include "globals.c" + #include "../libmultipath/alias.c" + ++/* For verbose printing of all aliases in the ordering tests */ ++#define ALIAS_DEBUG 0 ++ + #if INT_MAX == 0x7fffffff + /* user_friendly_name for map #INT_MAX */ + #define MPATH_ID_INT_MAX "fxshrxw" +@@ -439,11 +442,12 @@ static void mock_self_alias(const char *alias, const char *wwid) + expect_condlog(3, USED_STR(alias, wwid)); \ + } while(0) + +-static void __mock_bindings_file(const char *content) ++static void __mock_bindings_file(const char *content, bool conflict_ok) + { + char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; + char *token, *savep = NULL; + int i; ++ uintmax_t values[] = { BINDING_ADDED, BINDING_CONFLICT }; + + cnt = strdup(content); + assert_ptr_not_equal(cnt, NULL); +@@ -459,12 +463,12 @@ static void __mock_bindings_file(const char *content) + continue; + + rc = add_binding(&global_bindings, alias, wwid); +- assert_int_equal(rc, BINDING_ADDED); ++ assert_in_set(rc, values, conflict_ok ? 2 : 1); + } + } + + static void mock_bindings_file(const char *content) { +- return __mock_bindings_file(content); ++ return __mock_bindings_file(content, false); + } + + static int teardown_bindings(void **state) +@@ -1744,6 +1748,207 @@ static int test_get_user_friendly_alias() + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++/* Numbers 1-1000, randomly shuffled */ ++static const int random_numbers[1000] = { ++ 694, 977, 224, 178, 841, 818, 914, 549, 831, 942, 263, 834, 919, 800, ++ 111, 517, 719, 297, 988, 98, 332, 516, 754, 772, 495, 488, 331, 529, ++ 142, 747, 848, 618, 375, 624, 74, 753, 782, 944, 623, 468, 862, 997, ++ 417, 258, 298, 774, 673, 904, 883, 766, 867, 400, 11, 950, 14, 784, ++ 655, 155, 396, 9, 743, 93, 651, 245, 968, 306, 785, 581, 880, 486, ++ 168, 631, 203, 4, 663, 294, 702, 762, 619, 684, 48, 181, 21, 443, 643, ++ 863, 1000, 327, 26, 126, 382, 765, 586, 76, 49, 925, 319, 865, 797, ++ 876, 693, 334, 433, 243, 419, 901, 854, 326, 985, 347, 874, 527, 282, ++ 290, 380, 167, 95, 3, 257, 936, 60, 426, 227, 345, 577, 492, 467, 580, ++ 967, 422, 823, 718, 610, 64, 700, 412, 163, 288, 506, 828, 432, 51, ++ 356, 348, 539, 478, 17, 945, 602, 123, 450, 660, 429, 113, 310, 358, ++ 512, 758, 508, 19, 542, 304, 286, 446, 918, 723, 333, 603, 731, 978, ++ 230, 697, 109, 872, 175, 853, 947, 965, 121, 222, 101, 811, 117, 601, ++ 191, 752, 384, 415, 938, 278, 915, 715, 240, 552, 912, 838, 150, 840, ++ 627, 29, 636, 464, 861, 481, 992, 249, 934, 82, 368, 724, 807, 593, ++ 157, 147, 199, 637, 41, 62, 902, 505, 621, 342, 174, 260, 729, 961, ++ 219, 311, 629, 789, 81, 739, 860, 712, 223, 165, 741, 981, 485, 363, ++ 346, 709, 125, 369, 279, 634, 399, 162, 193, 769, 149, 314, 868, 612, ++ 524, 675, 341, 343, 476, 606, 388, 613, 850, 264, 903, 451, 908, 779, ++ 453, 148, 497, 46, 132, 43, 885, 955, 269, 395, 72, 128, 767, 989, ++ 929, 423, 742, 55, 13, 79, 924, 182, 295, 563, 668, 169, 974, 154, ++ 970, 54, 674, 52, 437, 570, 550, 531, 554, 793, 678, 218, 367, 105, ++ 197, 315, 958, 892, 86, 47, 284, 37, 561, 522, 198, 689, 817, 573, ++ 877, 201, 803, 501, 881, 546, 530, 523, 780, 579, 953, 135, 23, 620, ++ 84, 698, 303, 656, 357, 323, 494, 58, 131, 913, 995, 120, 70, 1, 195, ++ 365, 210, 25, 898, 173, 307, 239, 77, 418, 952, 963, 92, 455, 425, 12, ++ 536, 161, 328, 933, 401, 251, 735, 725, 362, 322, 557, 681, 302, 53, ++ 786, 801, 391, 946, 748, 133, 717, 851, 7, 372, 993, 387, 906, 373, ++ 667, 33, 670, 389, 209, 611, 896, 652, 69, 999, 344, 845, 633, 36, ++ 487, 192, 180, 45, 640, 427, 707, 805, 188, 152, 905, 217, 30, 252, ++ 386, 665, 299, 541, 410, 787, 5, 857, 751, 392, 44, 595, 146, 745, ++ 641, 957, 866, 773, 806, 815, 659, 102, 704, 430, 106, 296, 129, 847, ++ 130, 990, 669, 236, 225, 680, 159, 213, 438, 189, 447, 600, 232, 594, ++ 32, 56, 390, 647, 855, 428, 330, 714, 738, 706, 666, 461, 469, 482, ++ 558, 814, 559, 177, 575, 538, 309, 383, 261, 156, 420, 761, 630, 893, ++ 10, 116, 940, 844, 71, 377, 662, 312, 520, 244, 143, 759, 119, 186, ++ 592, 909, 864, 376, 768, 254, 265, 394, 511, 760, 574, 6, 436, 514, ++ 59, 226, 644, 956, 578, 825, 548, 145, 736, 597, 378, 821, 987, 897, ++ 354, 144, 722, 895, 589, 503, 826, 498, 543, 617, 763, 231, 808, 528, ++ 89, 479, 607, 737, 170, 404, 371, 65, 103, 340, 283, 141, 313, 858, ++ 289, 124, 971, 687, 954, 732, 39, 926, 176, 100, 267, 519, 890, 535, ++ 276, 448, 27, 457, 899, 385, 184, 275, 770, 544, 614, 449, 160, 658, ++ 259, 973, 108, 604, 24, 207, 562, 757, 744, 324, 444, 962, 591, 480, ++ 398, 409, 998, 253, 325, 445, 979, 8, 35, 118, 73, 683, 208, 85, 190, ++ 791, 408, 871, 657, 179, 18, 556, 496, 475, 20, 894, 484, 775, 889, ++ 463, 241, 730, 57, 907, 551, 859, 943, 185, 416, 870, 590, 435, 471, ++ 932, 268, 381, 626, 502, 565, 273, 534, 672, 778, 292, 473, 566, 104, ++ 172, 285, 832, 411, 329, 628, 397, 472, 271, 910, 711, 690, 969, 585, ++ 809, 941, 923, 555, 228, 685, 242, 94, 96, 211, 140, 61, 922, 795, ++ 869, 34, 255, 38, 984, 676, 15, 560, 632, 434, 921, 355, 582, 351, ++ 212, 200, 819, 960, 649, 852, 75, 771, 361, 996, 238, 316, 720, 671, ++ 462, 112, 569, 171, 664, 625, 588, 405, 553, 270, 533, 353, 842, 114, ++ 972, 83, 937, 63, 194, 237, 537, 980, 802, 916, 959, 688, 839, 350, ++ 917, 650, 545, 615, 151, 352, 686, 726, 266, 509, 439, 491, 935, 608, ++ 518, 653, 339, 609, 277, 635, 836, 88, 407, 440, 642, 927, 229, 727, ++ 360, 477, 846, 413, 454, 616, 28, 598, 567, 540, 790, 424, 247, 317, ++ 746, 911, 798, 321, 547, 248, 734, 829, 220, 138, 756, 500, 691, 196, ++ 740, 930, 843, 733, 221, 827, 50, 813, 949, 525, 349, 474, 134, 875, ++ 695, 513, 414, 515, 638, 99, 366, 490, 975, 246, 465, 206, 281, 583, ++ 256, 587, 749, 2, 951, 679, 215, 364, 458, 402, 646, 991, 335, 982, ++ 835, 300, 900, 703, 994, 983, 234, 888, 532, 804, 584, 305, 792, 442, ++ 291, 964, 158, 370, 452, 250, 521, 166, 948, 812, 794, 272, 699, 205, ++ 183, 507, 301, 920, 781, 233, 824, 137, 489, 833, 887, 966, 856, 78, ++ 830, 153, 359, 696, 526, 216, 66, 701, 403, 891, 849, 571, 308, 483, ++ 164, 293, 928, 677, 320, 837, 441, 639, 564, 510, 648, 274, 336, 661, ++ 878, 777, 816, 976, 493, 810, 67, 87, 91, 187, 882, 986, 80, 22, 499, ++ 90, 705, 139, 136, 122, 708, 716, 886, 572, 127, 40, 721, 764, 16, ++ 379, 692, 645, 456, 710, 460, 783, 97, 776, 713, 884, 115, 466, 596, ++ 374, 406, 110, 568, 68, 214, 622, 470, 107, 504, 682, 31, 421, 576, ++ 654, 605, 788, 799, 280, 338, 931, 873, 204, 287, 459, 755, 939, 599, ++ 431, 796, 235, 42, 750, 262, 318, 393, 202, 822, 879, 820, 728, 337, ++}; ++ ++static void fill_bindings_random(struct strbuf *buf, int start, int end, ++ const char *prefix) ++{ ++ int i; ++ ++ for (i = start; i < end; i++) { ++ print_strbuf(buf, "%s", prefix); ++ format_devname(buf, random_numbers[i]); ++ print_strbuf(buf, " WWID%d\n", random_numbers[i]); ++ } ++} ++ ++struct random_aliases { ++ int start; ++ int end; ++ const char *prefix; ++}; ++ ++static void order_test(int n, const struct random_aliases ra[], bool conflict_ok) ++{ ++ STRBUF_ON_STACK(buf); ++ int i, j, prev, curr, tmp; ++ struct binding *bdg; ++ Bindings *bindings = &global_bindings; ++ ++ for (j = 0; j < n; j++) ++ fill_bindings_random(&buf, ra[j].start, ra[j].end, ra[j].prefix); ++ __mock_bindings_file(get_strbuf_str(&buf), conflict_ok); ++ ++ for (j = 0; j < n; j++) { ++ bdg = VECTOR_SLOT(bindings, 0); ++ if (ALIAS_DEBUG && j == 0) ++ printf("%d: %s\n", 0, bdg->alias); ++ prev = scan_devname(bdg->alias, ra[j].prefix); ++ i = 1; ++ vector_foreach_slot_after(bindings, bdg, i) { ++ if (ALIAS_DEBUG && j == 0) ++ printf("%d: %s\n", i, bdg->alias); ++ tmp = scan_devname(bdg->alias, ra[j].prefix); ++ if (tmp == -1) ++ continue; ++ curr = tmp; ++ if (prev > 0) { ++ if (curr <= prev) ++ printf("ERROR: %d (%s) %d >= %d\n", ++ i, bdg->alias, prev, curr); ++ assert_true(curr > prev); ++ } ++ prev = curr; ++ } ++ } ++} ++ ++static void order_01(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 1000, "MPATH" }, ++ }; ++ ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_02(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 500, "MPATH" }, ++ { 200, 700, "mpath" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_03(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 500, 1000, "MPTH" }, ++ { 0, 500, "MPATH" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_04(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 500, "mpa" }, ++ { 250, 750, "mp" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, true); ++} ++ ++static void order_05(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 100, "A" }, ++ { 0, 100, "B" }, ++ { 0, 100, "C" }, ++ { 0, 100, "D" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, false); ++} ++ ++static void order_06(void **state) ++{ ++ const struct random_aliases ra[] = { ++ { 0, 100, "" }, ++ { 0, 100, "a" }, ++ { 0, 100, "aa" }, ++ { 0, 100, "ab" }, ++ { 0, 100, "aaa" }, ++ }; ++ order_test(ARRAY_SIZE(ra), ra, true); ++} ++ ++static int test_bindings_order() ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_teardown(order_01, teardown_bindings), ++ cmocka_unit_test_teardown(order_02, teardown_bindings), ++ cmocka_unit_test_teardown(order_03, teardown_bindings), ++ cmocka_unit_test_teardown(order_04, teardown_bindings), ++ cmocka_unit_test_teardown(order_05, teardown_bindings), ++ cmocka_unit_test_teardown(order_06, teardown_bindings), ++ }; ++ ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ + int main(void) + { + int ret = 0; +@@ -1755,6 +1960,7 @@ int main(void) + ret += test_rlookup_binding(); + ret += test_allocate_binding(); + ret += test_get_user_friendly_alias(); ++ ret += test_bindings_order(); + + return ret; + } diff --git a/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch b/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch new file mode 100644 index 0000000..af21b74 --- /dev/null +++ b/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch @@ -0,0 +1,597 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 7 Sep 2023 22:22:43 +0200 +Subject: [PATCH] multipathd: watch bindings file with inotify + timestamp + +Since "libmultipath: keep bindings in memory", we don't re-read the +bindings file after every modification. Add a notification mechanism +that makes multipathd aware of changes to the bindings file. Because +multipathd itself will change the bindings file, it must compare +timestamps in order to avoid reading the file repeatedly. + +Because select_alias() can be called from multiple thread contexts (uxlsnr, +uevent handler), we need to add locking for the bindings file. The +timestamp must also be protected by a lock, because it can't be read +or written atomically. + +Note: The notification mechanism expects the bindings file to be +atomically replaced by rename(2). Changes must be made in a temporary file and +applied using rename(2), as in update_bindings_file(). The inotify +mechanism deliberately does not listen to close-after-write events +that would be generated by editing the bindings file directly. This + +Note also: new bindings will only be read from add_map_with_path(), +i.e. either during reconfigure(), or when a new map is created during +runtime. Existing maps will not be renamed if the binding file changes, +unless the user runs "multipathd reconfigure". This is not a change +wrt the previous code, but it should be mentioned anyway. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 256 +++++++++++++++++++++++++----- + libmultipath/alias.h | 3 +- + libmultipath/libmultipath.version | 5 + + multipathd/uxlsnr.c | 36 ++++- + tests/alias.c | 3 + + 5 files changed, 256 insertions(+), 47 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 66e34e31..964b8a7b 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "debug.h" + #include "util.h" +@@ -22,6 +23,7 @@ + #include "config.h" + #include "devmapper.h" + #include "strbuf.h" ++#include "time-util.h" + + /* + * significant parts of this file were taken from iscsi-bindings.c of the +@@ -50,6 +52,12 @@ + "# alias wwid\n" \ + "#\n" + ++/* uatomic access only */ ++static int bindings_file_changed = 1; ++ ++static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; ++static struct timespec bindings_last_updated; ++ + struct binding { + char *alias; + char *wwid; +@@ -60,6 +68,9 @@ struct binding { + * an abstract type. + */ + typedef struct _vector Bindings; ++ ++/* Protect global_bindings */ ++static pthread_mutex_t bindings_mutex = PTHREAD_MUTEX_INITIALIZER; + static Bindings global_bindings = { .allocated = 0 }; + + enum { +@@ -78,6 +89,27 @@ static void _free_binding(struct binding *bdg) + free(bdg); + } + ++static void free_bindings(Bindings *bindings) ++{ ++ struct binding *bdg; ++ int i; ++ ++ vector_foreach_slot(bindings, bdg, i) ++ _free_binding(bdg); ++ vector_reset(bindings); ++} ++ ++static void set_global_bindings(Bindings *bindings) ++{ ++ Bindings old_bindings; ++ ++ pthread_mutex_lock(&bindings_mutex); ++ old_bindings = global_bindings; ++ global_bindings = *bindings; ++ pthread_mutex_unlock(&bindings_mutex); ++ free_bindings(&old_bindings); ++} ++ + static const struct binding *get_binding_for_alias(const Bindings *bindings, + const char *alias) + { +@@ -199,7 +231,8 @@ static int delete_binding(Bindings *bindings, const char *wwid) + return BINDING_DELETED; + } + +-static int write_bindings_file(const Bindings *bindings, int fd) ++static int write_bindings_file(const Bindings *bindings, int fd, ++ struct timespec *ts) + { + struct binding *bnd; + STRBUF_ON_STACK(content); +@@ -227,9 +260,56 @@ static int write_bindings_file(const Bindings *bindings, int fd) + } + len -= n; + } ++ fsync(fd); ++ if (ts) { ++ struct stat st; ++ ++ if (fstat(fd, &st) == 0) ++ *ts = st.st_mtim; ++ else ++ clock_gettime(CLOCK_REALTIME_COARSE, ts); ++ } + return 0; + } + ++void handle_bindings_file_inotify(const struct inotify_event *event) ++{ ++ struct config *conf; ++ const char *base; ++ bool changed = false; ++ struct stat st; ++ struct timespec ts = { 0, 0 }; ++ int ret; ++ ++ if (!(event->mask & IN_MOVED_TO)) ++ return; ++ ++ conf = get_multipath_config(); ++ base = strrchr(conf->bindings_file, '/'); ++ changed = base && base > conf->bindings_file && ++ !strcmp(base + 1, event->name); ++ ret = stat(conf->bindings_file, &st); ++ put_multipath_config(conf); ++ ++ if (!changed) ++ return; ++ ++ pthread_mutex_lock(×tamp_mutex); ++ if (ret == 0) { ++ ts = st.st_mtim; ++ changed = timespeccmp(&ts, &bindings_last_updated) > 0; ++ } ++ pthread_mutex_unlock(×tamp_mutex); ++ ++ if (changed) { ++ uatomic_xchg(&bindings_file_changed, 1); ++ condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", ++ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); ++ } else ++ condlog(3, "%s: bindings file is up-to-date, timestamp: %ld.%06ld", ++ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); ++} ++ + static int update_bindings_file(const Bindings *bindings, + const char *bindings_file) + { +@@ -237,6 +317,7 @@ static int update_bindings_file(const Bindings *bindings, + int fd = -1; + char tempname[PATH_MAX]; + mode_t old_umask; ++ struct timespec ts; + + if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) + return -1; +@@ -248,7 +329,7 @@ static int update_bindings_file(const Bindings *bindings, + } + umask(old_umask); + pthread_cleanup_push(cleanup_fd_ptr, &fd); +- rc = write_bindings_file(bindings, fd); ++ rc = write_bindings_file(bindings, fd, &ts); + pthread_cleanup_pop(1); + if (rc == -1) { + condlog(1, "failed to write new bindings file"); +@@ -257,8 +338,12 @@ static int update_bindings_file(const Bindings *bindings, + } + if ((rc = rename(tempname, bindings_file)) == -1) + condlog(0, "%s: rename: %m", __func__); +- else ++ else { ++ pthread_mutex_lock(×tamp_mutex); ++ bindings_last_updated = ts; ++ pthread_mutex_unlock(×tamp_mutex); + condlog(1, "updated bindings file %s", bindings_file); ++ } + return rc; + } + +@@ -387,6 +472,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww + return id; + } + ++/* Called with binding_mutex held */ + static char * + allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) + { +@@ -423,6 +509,30 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre + return alias; + } + ++enum { ++ BINDINGS_FILE_UP2DATE, ++ BINDINGS_FILE_READ, ++ BINDINGS_FILE_ERROR, ++ BINDINGS_FILE_BAD, ++}; ++ ++static int _read_bindings_file(const struct config *conf, Bindings *bindings, ++ bool force); ++ ++static void read_bindings_file(void) ++{ ++ struct config *conf; ++ Bindings bindings = {.allocated = 0, }; ++ int rc; ++ ++ conf = get_multipath_config(); ++ pthread_cleanup_push(put_multipath_config, conf); ++ rc = _read_bindings_file(conf, &bindings, false); ++ pthread_cleanup_pop(1); ++ if (rc == BINDINGS_FILE_READ) ++ set_global_bindings(&bindings); ++} ++ + /* + * get_user_friendly_alias() action table + * +@@ -463,6 +573,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al + bool new_binding = false; + const struct binding *bdg; + ++ read_bindings_file(); ++ ++ pthread_mutex_lock(&bindings_mutex); ++ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); ++ + if (!*alias_old) + goto new_alias; + +@@ -514,40 +629,40 @@ new_alias: + alias, wwid); + + out: ++ /* unlock bindings_mutex */ ++ pthread_cleanup_pop(1); + return alias; + } + + int get_user_friendly_wwid(const char *alias, char *buff) + { + const struct binding *bdg; ++ int rc = -1; + + if (!alias || *alias == '\0') { + condlog(3, "Cannot find binding for empty alias"); + return -1; + } + ++ read_bindings_file(); ++ ++ pthread_mutex_lock(&bindings_mutex); ++ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); + bdg = get_binding_for_alias(&global_bindings, alias); +- if (!bdg) { ++ if (bdg) { ++ strlcpy(buff, bdg->wwid, WWID_SIZE); ++ rc = 0; ++ } else + *buff = '\0'; +- return -1; +- } +- strlcpy(buff, bdg->wwid, WWID_SIZE); +- return 0; +-} +- +-static void free_bindings(Bindings *bindings) +-{ +- struct binding *bdg; +- int i; +- +- vector_foreach_slot(bindings, bdg, i) +- _free_binding(bdg); +- vector_reset(bindings); ++ pthread_cleanup_pop(1); ++ return rc; + } + + void cleanup_bindings(void) + { ++ pthread_mutex_lock(&bindings_mutex); + free_bindings(&global_bindings); ++ pthread_mutex_unlock(&bindings_mutex); + } + + enum { +@@ -595,7 +710,20 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + char *line = NULL; + size_t line_len = 0; + ssize_t n; +- ++ char header[sizeof(BINDINGS_FILE_HEADER)]; ++ ++ header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; ++ if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { ++ condlog(2, "%s: failed to read header from %s", __func__, ++ conf->bindings_file); ++ fseek(file, 0, SEEK_SET); ++ rc = -1; ++ } else if (strcmp(header, BINDINGS_FILE_HEADER)) { ++ condlog(2, "%s: invalid header in %s", __func__, ++ conf->bindings_file); ++ fseek(file, 0, SEEK_SET); ++ rc = -1; ++ } + pthread_cleanup_push(cleanup_free_ptr, &line); + while ((n = getline(&line, &line_len, file)) >= 0) { + char *alias, *wwid; +@@ -643,6 +771,68 @@ static int mp_alias_compar(const void *p1, const void *p2) + &((*(struct mpentry * const *)p2)->alias)); + } + ++static int _read_bindings_file(const struct config *conf, Bindings *bindings, ++ bool force) ++{ ++ int can_write; ++ int rc = 0, ret, fd; ++ FILE *file; ++ struct stat st; ++ int has_changed = uatomic_xchg(&bindings_file_changed, 0); ++ ++ if (!force) { ++ if (!has_changed) { ++ condlog(4, "%s: bindings are unchanged", __func__); ++ return BINDINGS_FILE_UP2DATE; ++ } ++ } ++ ++ fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); ++ if (fd == -1) ++ return BINDINGS_FILE_ERROR; ++ ++ file = fdopen(fd, "r"); ++ if (file != NULL) { ++ condlog(3, "%s: reading %s", __func__, conf->bindings_file); ++ ++ pthread_cleanup_push(cleanup_fclose, file); ++ ret = _check_bindings_file(conf, file, bindings); ++ if (ret == 0) { ++ struct timespec ts; ++ ++ rc = BINDINGS_FILE_READ; ++ ret = fstat(fd, &st); ++ if (ret == 0) ++ ts = st.st_mtim; ++ else { ++ condlog(1, "%s: fstat failed (%m), using current time", __func__); ++ clock_gettime(CLOCK_REALTIME_COARSE, &ts); ++ } ++ pthread_mutex_lock(×tamp_mutex); ++ bindings_last_updated = ts; ++ pthread_mutex_unlock(×tamp_mutex); ++ } else if (ret == -1 && can_write && !conf->bindings_read_only) { ++ ret = update_bindings_file(bindings, conf->bindings_file); ++ if (ret == 0) ++ rc = BINDINGS_FILE_READ; ++ else ++ rc = BINDINGS_FILE_BAD; ++ } else { ++ condlog(0, "ERROR: bad settings in read-only bindings file %s", ++ conf->bindings_file); ++ rc = BINDINGS_FILE_BAD; ++ } ++ pthread_cleanup_pop(1); ++ } else { ++ condlog(1, "failed to fdopen %s: %m", ++ conf->bindings_file); ++ close(fd); ++ rc = BINDINGS_FILE_ERROR; ++ } ++ ++ return rc; ++} ++ + /* + * check_alias_settings(): test for inconsistent alias configuration + * +@@ -661,8 +851,7 @@ static int mp_alias_compar(const void *p1, const void *p2) + */ + int check_alias_settings(const struct config *conf) + { +- int can_write; +- int rc = 0, i, fd; ++ int i, rc; + Bindings bindings = {.allocated = 0, }; + vector mptable = NULL; + struct mpentry *mpe; +@@ -695,27 +884,12 @@ int check_alias_settings(const struct config *conf) + pthread_cleanup_pop(1); + pthread_cleanup_pop(1); + +- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); +- if (fd != -1) { +- FILE *file = fdopen(fd, "r"); +- +- if (file != NULL) { +- pthread_cleanup_push(cleanup_fclose, file); +- rc = _check_bindings_file(conf, file, &bindings); +- pthread_cleanup_pop(1); +- if (rc == -1 && can_write && !conf->bindings_read_only) +- rc = update_bindings_file(&bindings, conf->bindings_file); +- else if (rc == -1) +- condlog(0, "ERROR: bad settings in read-only bindings file %s", +- conf->bindings_file); +- } else { +- condlog(1, "failed to fdopen %s: %m", +- conf->bindings_file); +- close(fd); +- } ++ rc = _read_bindings_file(conf, &bindings, true); ++ ++ if (rc == BINDINGS_FILE_READ) { ++ set_global_bindings(&bindings); ++ rc = 0; + } + +- cleanup_bindings(); +- global_bindings = bindings; + return rc; + } +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index 5ef6720b..ca8911f4 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -10,5 +10,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, + struct config; + int check_alias_settings(const struct config *); + void cleanup_bindings(void); +- ++struct inotify_event; ++void handle_bindings_file_inotify(const struct inotify_event *event); + #endif /* _ALIAS_H */ +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index ddd302f5..57e50c12 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -238,3 +238,8 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_20.1.0 { ++global: ++ handle_bindings_file_inotify; ++}; +diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c +index 02e89fb4..d1f8f234 100644 +--- a/multipathd/uxlsnr.c ++++ b/multipathd/uxlsnr.c +@@ -41,6 +41,7 @@ + #include "cli.h" + #include "uxlsnr.h" + #include "strbuf.h" ++#include "alias.h" + + /* state of client connection */ + enum { +@@ -190,6 +191,7 @@ void wakeup_cleanup(void *arg) + struct watch_descriptors { + int conf_wd; + int dir_wd; ++ int mp_wd; /* /etc/multipath; for bindings file */ + }; + + /* failing to set the watch descriptor is o.k. we just miss a warning +@@ -200,6 +202,8 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + struct config *conf; + int dir_reset = 0; + int conf_reset = 0; ++ int mp_reset = 0; ++ char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; + + if (notify_fd == -1) + return; +@@ -214,7 +218,10 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + conf_reset = 1; + if (wds->dir_wd == -1) + dir_reset = 1; ++ if (wds->mp_wd == -1) ++ mp_reset = 1; + } ++ bindings_file = strdup(conf->bindings_file); + put_multipath_config(conf); + + if (dir_reset) { +@@ -235,7 +242,18 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + if (wds->conf_wd == -1) + condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); + } +- return; ++ if (mp_reset && bindings_file) { ++ char *slash = strrchr(bindings_file, '/'); ++ ++ if (slash && slash > bindings_file) { ++ *slash = '\0'; ++ wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, ++ IN_MOVED_TO|IN_ONLYDIR); ++ if (wds->mp_wd == -1) ++ condlog(3, "didn't set up notifications on %s: %m", ++ bindings_file); ++ } ++ } + } + + static void handle_inotify(int fd, struct watch_descriptors *wds) +@@ -256,12 +274,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) + inotify_rm_watch(fd, wds->conf_wd); + if (wds->dir_wd != -1) + inotify_rm_watch(fd, wds->dir_wd); +- wds->conf_wd = wds->dir_wd = -1; ++ if (wds->mp_wd != -1) ++ inotify_rm_watch(fd, wds->mp_wd); ++ wds->conf_wd = wds->dir_wd = wds->mp_wd = -1; + } + break; + } + +- got_notify = 1; + for (ptr = buff; ptr < buff + len; + ptr += sizeof(struct inotify_event) + event->len) { + event = (const struct inotify_event *) ptr; +@@ -273,7 +292,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) + wds->conf_wd = inotify_add_watch(notify_fd, DEFAULT_CONFIGFILE, IN_CLOSE_WRITE); + else if (wds->dir_wd == event->wd) + wds->dir_wd = -1; ++ else if (wds->mp_wd == event->wd) ++ wds->mp_wd = -1; + } ++ if (wds->mp_wd != -1 && wds->mp_wd == event->wd) ++ handle_bindings_file_inotify(event); ++ else ++ got_notify = 1; + } + } + if (got_notify) +@@ -599,7 +624,7 @@ void *uxsock_listen(long ux_sock, void *trigger_data) + int max_pfds = MIN_POLLS + POLLFDS_BASE; + /* conf->sequence_nr will be 1 when uxsock_listen is first called */ + unsigned int sequence_nr = 0; +- struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 }; ++ struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1, .mp_wd = -1, }; + struct vectors *vecs = trigger_data; + + condlog(3, "uxsock: startup listener"); +@@ -666,7 +691,8 @@ void *uxsock_listen(long ux_sock, void *trigger_data) + + reset_watch(notify_fd, &wds, &sequence_nr); + polls[POLLFD_NOTIFY].fd = notify_fd; +- if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1)) ++ if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1 ++ && wds.mp_wd == -1)) + polls[POLLFD_NOTIFY].events = 0; + else + polls[POLLFD_NOTIFY].events = POLLIN; +diff --git a/tests/alias.c b/tests/alias.c +index 7f3ff38a..9ae27567 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -1954,6 +1954,9 @@ int main(void) + int ret = 0; + init_test_verbosity(3); + ++ /* avoid open_file() call in _read_bindings_file */ ++ bindings_file_changed = 0; ++ + ret += test_format_devname(); + ret += test_scan_devname(); + ret += test_lookup_binding(); diff --git a/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch b/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch new file mode 100644 index 0000000..bba92f3 --- /dev/null +++ b/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 19:54:07 +0200 +Subject: [PATCH] multipath-tools tests: mock pthread_mutex_{lock,unlock} + +If some test fails with a lock held, cmocka doesn't deal well with +pthread_cleanup_pop(). Such tests can cause deadlock with the locking +primitives in the alias code, because locks don't get properly unlocked. Just +mock the lock/unlock functions and generate an error if they weren't paired at +the end of the test. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 1 + + tests/alias.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 47 insertions(+) + +diff --git a/tests/Makefile b/tests/Makefile +index c777d07a..7dac8a8f 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -52,6 +52,7 @@ blacklist-test_LIBDEPS := -ludev + vpd-test_OBJDEPS := $(multipathdir)/discovery.o + vpd-test_LIBDEPS := -ludev -lpthread -ldl + alias-test_TESTDEPS := test-log.o ++alias-test_OBJDEPS := $(mpathutildir)/util.o + alias-test_LIBDEPS := -lpthread -ldl + valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o + valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl +diff --git a/tests/alias.c b/tests/alias.c +index 9ae27567..94df36d8 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -89,6 +89,47 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) + return ret; + } + ++static int lock_errors; ++static int bindings_locked; ++static int timestamp_locked; ++int __wrap_pthread_mutex_lock(pthread_mutex_t *mutex) ++{ ++ if (mutex == &bindings_mutex) { ++ if (bindings_locked) { ++ fprintf(stderr, "%s: bindings_mutex LOCKED\n", __func__); ++ lock_errors++; ++ } ++ bindings_locked = 1; ++ } else if (mutex == ×tamp_mutex) { ++ if (timestamp_locked) { ++ fprintf(stderr, "%s: timestamp_mutex LOCKED\n", __func__); ++ lock_errors++; ++ } ++ timestamp_locked = 1; ++ } else ++ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); ++ return 0; ++} ++ ++int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex) ++{ ++ if (mutex == &bindings_mutex) { ++ if (!bindings_locked) { ++ fprintf(stderr, "%s: bindings_mutex UNLOCKED\n", __func__); ++ lock_errors++; ++ } ++ bindings_locked = 0; ++ } else if (mutex == ×tamp_mutex) { ++ if (!timestamp_locked) { ++ fprintf(stderr, "%s: timestamp_mutex UNLOCKED\n", __func__); ++ lock_errors++; ++ } ++ timestamp_locked = 0; ++ } else ++ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); ++ return 0; ++} ++ + #define TEST_FDNO 1234 + #define TEST_FPTR ((FILE *) 0xaffe) + +@@ -1718,6 +1759,10 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { + free(alias); + } + ++static void gufa_check_locking(void **state) { ++ assert_int_equal(lock_errors, 0); ++} ++ + static int test_get_user_friendly_alias() + { + const struct CMUnitTest tests[] = { +@@ -1743,6 +1788,7 @@ static int test_get_user_friendly_alias() + cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), + cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), + cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), ++ cmocka_unit_test(gufa_check_locking), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch b/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch new file mode 100644 index 0000000..26b79a8 --- /dev/null +++ b/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 22:13:51 +0200 +Subject: [PATCH] multipath-tools Makefile: sanitize paths for configuration + files + +Make the path to multipath.conf configurable, and use the same prefix +by default for multipath.conf and multipath/conf.d. For "usr-merged" +distributions with immutable /usr, we'll want to have the configuration +under a different prefix. This can be achieved by using e.g. + + make prefix=/usr etc_prefix="" + +Note that with prefix=/usr, before this patch the code would use +/usr/etc/multipath/conf.d, but /etc/multipath.conf. If this (rather +inconsistent) behavior is desired, use the following command line: + + make prefix=/usr configfile=/etc/multipath.conf + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 9 ++++++--- + libmultipath/defaults.h | 1 - + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 502cd0f1..39972d93 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -37,6 +37,8 @@ prefix := + exec_prefix := $(prefix) + # Prefix for non-essential libraries (libdmmp) + usr_prefix := $(prefix) ++# Prefix for configfuration files (multipath.conf) ++etc_prefix := $(prefix) + # Where to install systemd-related files. systemd is usually installed under /usr + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) +@@ -54,7 +56,8 @@ usrlibdir := $(usr_prefix)/$(LIB) + includedir := $(usr_prefix)/include + pkgconfdir := $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath +-configdir := $(prefix)/etc/multipath/conf.d ++configdir := $(etc_prefix)/etc/multipath/conf.d ++configfile := $(etc_prefix)/etc/multipath.conf + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) + libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) +@@ -84,8 +87,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) + CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ +- -DRUNTIME_DIR=\"$(runtimedir)\" \ +- -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP ++ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ ++ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index b3f11d4c..bc2d6388 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -66,7 +66,6 @@ + #define MAX_DEV_LOSS_TMO UINT_MAX + #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" + #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" +-#define DEFAULT_CONFIGFILE "/etc/multipath.conf" + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" + #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" + #define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" diff --git a/0030-multipath-tools-add-compile-time-configuration-for-e.patch b/0030-multipath-tools-add-compile-time-configuration-for-e.patch new file mode 100644 index 0000000..afdf833 --- /dev/null +++ b/0030-multipath-tools-add-compile-time-configuration-for-e.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 22:26:22 +0200 +Subject: [PATCH] multipath-tools: add compile time configuration for + "/etc/multipath" + +Instead of hard-conding "/etc/multipath" as the path for the state +files "bindings", "prkeys", and "wwids", make this path configurable +via the "statedir" compile-time option. The default is currently still +/etc, it might change to /var/lib or similar in the future. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 4 +++- + libmultipath/defaults.h | 6 +++--- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 39972d93..96206b2f 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -58,6 +58,7 @@ pkgconfdir := $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(etc_prefix)/etc/multipath/conf.d + configfile := $(etc_prefix)/etc/multipath.conf ++statedir := $(etc_prefix)/etc/multipath + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) + libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) +@@ -88,7 +89,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ +- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP ++ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ ++ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index bc2d6388..d01f9712 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -66,9 +66,9 @@ + #define MAX_DEV_LOSS_TMO UINT_MAX + #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" + #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" +-#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" +-#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" +-#define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" ++#define DEFAULT_BINDINGS_FILE STATE_DIR "/bindings" ++#define DEFAULT_WWIDS_FILE STATE_DIR "/wwids" ++#define DEFAULT_PRKEYS_FILE STATE_DIR "/prkeys" + #define MULTIPATH_SHM_BASE RUNTIME_DIR "/multipath/" + + diff --git a/0031-multipath-tools-man-pages-generate-with-correct-path.patch b/0031-multipath-tools-man-pages-generate-with-correct-path.patch new file mode 100644 index 0000000..65fc077 --- /dev/null +++ b/0031-multipath-tools-man-pages-generate-with-correct-path.patch @@ -0,0 +1,366 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Sep 2023 22:48:16 +0200 +Subject: [PATCH] multipath-tools man pages: generate with correct paths + +Generate the man pages using the compile-time settings for paths +to multipath.conf etc. + +Add a paragraph about the CONFIGDIR (/etc/multipath/conf.d) +and the drop-in configuration files in the multipath.conf man page. + +Also, make sure all generated man pages and other files are correctly +removed by "make clean". + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + .gitignore | 4 +++ + Makefile.inc | 3 +++ + mpathpersist/Makefile | 5 ++-- + .../{mpathpersist.8 => mpathpersist.8.in} | 2 +- + multipath/Makefile | 13 +++++---- + multipath/{multipath.8 => multipath.8.in} | 10 +++---- + .../{multipath.conf.5 => multipath.conf.5.in} | 27 ++++++++++++------- + multipathd/Makefile | 9 ++++--- + multipathd/{multipathd.8 => multipathd.8.in} | 8 +++--- + 9 files changed, 49 insertions(+), 32 deletions(-) + rename mpathpersist/{mpathpersist.8 => mpathpersist.8.in} (99%) + rename multipath/{multipath.8 => multipath.8.in} (97%) + rename multipath/{multipath.conf.5 => multipath.conf.5.in} (98%) + rename multipathd/{multipathd.8 => multipathd.8.in} (97%) + +diff --git a/.gitignore b/.gitignore +index 535353e5..2986578f 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -13,11 +13,15 @@ cscope.files + cscope.out + kpartx/kpartx + multipath/multipath ++multipath/multipath.8 ++multipath/multipath.conf.5 + multipath/multipath.rules + multipath/tmpfiles.conf + multipathd/multipathd ++multipathd/multipathd.8 + multipathd/multipathc + mpathpersist/mpathpersist ++mpathpersist/mpathpersist.8 + abi.tar.gz + abi + abi-test +diff --git a/Makefile.inc b/Makefile.inc +index 96206b2f..79e521e1 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -133,3 +133,6 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ + @printf 'local:\n\t*;\n};\n' >>$@ + ++%: %.in ++ @echo creating $@ ++ $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g' $< >$@ +diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile +index f57c105c..f3749467 100644 +--- a/mpathpersist/Makefile ++++ b/mpathpersist/Makefile +@@ -8,10 +8,11 @@ LIBDEPS += -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath \ + -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ludev + + EXEC = mpathpersist ++MANPAGES := mpathpersist.8 + + OBJS = main.o + +-all: $(EXEC) ++all: $(EXEC) $(MANPAGES) + + $(EXEC): $(OBJS) + $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) +@@ -23,7 +24,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + + clean: dep_clean +- $(Q)$(RM) core *.o $(EXEC) ++ $(Q)$(RM) core *.o $(EXEC) $(MANPAGES) + + include $(wildcard $(OBJS:.o=.d)) + +diff --git a/mpathpersist/mpathpersist.8 b/mpathpersist/mpathpersist.8.in +similarity index 99% +rename from mpathpersist/mpathpersist.8 +rename to mpathpersist/mpathpersist.8.in +index 8d26b37c..fecef0d6 100644 +--- a/mpathpersist/mpathpersist.8 ++++ b/mpathpersist/mpathpersist.8.in +@@ -31,7 +31,7 @@ mpathpersist \- Manages SCSI persistent reservations on dm multipath devices. + . + This utility is used to manage SCSI persistent reservations on Device Mapper + Multipath devices. To be able to use this functionality, the \fIreservation_key\fR +-attribute must be defined in the \fI/etc/multipath.conf\fR file. Otherwise the ++attribute must be defined in the \fI@CONFIGFILE@\fR file. Otherwise the + \fBmultipathd\fR daemon will not check for persistent reservation for newly + discovered paths or reinstated paths. + . +diff --git a/multipath/Makefile b/multipath/Makefile +index 73db991a..68cb5ce7 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -3,7 +3,9 @@ + # + include ../Makefile.inc + +-EXEC := multipath ++EXEC := multipath ++MANPAGES := multipath.8 multipath.conf.5 ++GENERATED := $(MANPAGES) multipath.rules tmpfiles.conf + + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) + CFLAGS += $(BIN_CFLAGS) +@@ -13,7 +15,7 @@ LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ + + OBJS := main.o + +-all: $(EXEC) multipath.rules tmpfiles.conf ++all: $(EXEC) $(GENERATED) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so + @echo building $@ because of $? +@@ -47,15 +49,12 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 ++ $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf + + clean: dep_clean +- $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf ++ $(Q)$(RM) core *.o $(EXEC) $(GENERATED) + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: + $(Q)$(RM) $(OBJS:.o=.d) +- +-%: %.in +- @echo creating $@ +- $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ +diff --git a/multipath/multipath.8 b/multipath/multipath.8.in +similarity index 97% +rename from multipath/multipath.8 +rename to multipath/multipath.8.in +index 5fed6df7..348eb220 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8.in +@@ -185,7 +185,7 @@ Display the currently used multipathd configuration. + .B \-T + Display the currently used multipathd configuration, limiting the output to + those devices actually present in the system. This can be used a template for +-creating \fImultipath.conf\fR. ++creating \fI@CONFIGFILE@\fR. + . + .\" ---------------------------------------------------------------------------- + .SH OPTIONS +@@ -233,11 +233,11 @@ option from \fBmultipath.conf(5)\fR. + .B \-i + Ignore WWIDs file when processing devices. If + \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in +-\fImultipath.conf\fR, multipath only considers devices that are ++\fI@CONFIGFILE@\fR, multipath only considers devices that are + listed in the WWIDs file. This option overrides that behavior. For other values + of \fIfind_multipaths\fR, this option has no effect. See the description of + \fIfind_multipaths\fR in +-.BR multipath.conf (5). ++.BR @CONFIGFILE@ (5). + This option should only be used in rare circumstances. + . + .TP +@@ -246,8 +246,8 @@ Treat the bindings file as read only. + . + .TP + .BI \-b " file" +-Set \fIuser_friendly_names\fR bindings file location. The default is +-\fI/etc/multipath/bindings\fR. ++(\fBdeprecated, do not use\fR) Set \fIuser_friendly_names\fR bindings file location. The default is ++\fI@STATE_DIR@/bindings\fR. + . + .TP + .B \-q +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5.in +similarity index 98% +rename from multipath/multipath.conf.5 +rename to multipath/multipath.conf.5.in +index 93af17db..20df2232 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5.in +@@ -13,14 +13,14 @@ + .SH NAME + .\" ---------------------------------------------------------------------------- + . +-multipath.conf \- multipath daemon configuration file. ++@CONFIGFILE@, @CONFIGDIR@/*.conf \- multipath daemon configuration file. + . + . + .\" ---------------------------------------------------------------------------- + .SH DESCRIPTION + .\" ---------------------------------------------------------------------------- + . +-.B "/etc/multipath.conf" ++.B "@CONFIGFILE@" + is the configuration file for the multipath daemon. It is used to + overwrite the built-in configuration table of \fBmultipathd\fP. + Any line whose first non-white-space character is a '#' is considered +@@ -29,6 +29,15 @@ a comment line. Empty lines are ignored. + Currently used multipathd configuration can be displayed with the \fBmultipath -t\fR + or \fBmultipathd show config\fR command. + . ++.PP ++Additional configuration can be made in drop-in files under ++.B @CONFIGDIR@. ++Files ending in \fI.conf\fR in this directory are read ++in alphabetical order, after reading \fI@CONFIGFILE@\fR. ++They use the same syntax as \fI@CONFIGFILE@\fR itself, ++and support all sections and keywords. If a keyword occurs in the same section ++in multiple files, the last occurence will take precedence over all others. ++. + . + .\" ---------------------------------------------------------------------------- + .SH SYNTAX +@@ -85,7 +94,7 @@ not mandatory. + . + .LP + .B Note on regular expressions: +-The \fImultipath.conf\fR syntax allows many attribute values to be specified as POSIX ++The \fI@CONFIGFILE@\fR syntax allows many attribute values to be specified as POSIX + Extended Regular Expressions (see \fBregex\fR(7)). These regular expressions + are \fBcase sensitive\fR and \fBnot anchored\fR, thus the expression "bar" matches "barbie", + "rhabarber", and "wunderbar", but not "Barbie". To avoid unwanted substring +@@ -711,7 +720,7 @@ The default is: \fBno\fR + .B user_friendly_names + If set to + .I yes +-, using the bindings file \fI/etc/multipath/bindings\fR to assign a persistent ++, using the bindings file \fI@STATE_DIR@/bindings\fR to assign a persistent + and unique alias to the multipath, in the form of mpath. If set to + .I no + use the WWID as the alias. In either case this be will +@@ -790,7 +799,7 @@ The full pathname of the binding file to be used when the user_friendly_names + option is set. + .RS + .TP +-The default is: \fB/etc/multipath/bindings\fR ++The default is: \fB@STATE_DIR@/bindings\fR + .RE + . + . +@@ -801,7 +810,7 @@ The full pathname of the WWIDs file, which is used by multipath to keep track + of the WWIDs for LUNs it has created multipath devices on in the past. + .RS + .TP +-The default is: \fB/etc/multipath/wwids\fR ++The default is: \fB@STATE_DIR@/wwids\fR + .RE + . + . +@@ -813,7 +822,7 @@ track of the persistent reservation key used for a specific WWID, when + \fIreservation_key\fR is set to \fBfile\fR. + .RS + .TP +-The default is: \fB/etc/multipath/prkeys\fR ++The default is: \fB@STATE_DIR@/prkeys\fR + .RE + . + . +@@ -872,7 +881,7 @@ The default is: \fBno\fR + .I yes + and the SCSI layer has already attached a hardware_handler to the device, + multipath will not force the device to use the hardware_handler specified by +-multipath.conf. If the SCSI layer has not attached a hardware handler, ++@CONFIGFILE@. If the SCSI layer has not attached a hardware handler, + multipath will continue to use its configured hardware handler. + .RS + .PP +@@ -1559,7 +1568,7 @@ given device, the attributes of all matching entries are applied to it. + If an attribute is specified in several matching device subsections, + later entries take precedence. Thus, entries in files under \fIconfig_dir\fR (in + reverse alphabetical order) have the highest precedence, followed by entries +-in \fImultipath.conf\fR; the built-in hardware table has the lowest ++in \fI@CONFIGFILE@\fR; the built-in hardware table has the lowest + precedence. Inside a configuration file, later entries have higher precedence + than earlier ones. + .LP +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 0d0146c5..cdba3db1 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -1,7 +1,8 @@ + include ../Makefile.inc + +-EXEC := multipathd +-CLI := multipathc ++EXEC := multipathd ++CLI := multipathc ++MANPAGES := multipathd.8 + + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ + $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ +@@ -42,7 +43,7 @@ ifeq ($(FPIN_SUPPORT),1) + OBJS += fpin_handlers.o + endif + +-all : $(EXEC) $(CLI) ++all : $(EXEC) $(CLI) $(MANPAGES) + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so + @echo building $@ because of $? +@@ -79,7 +80,7 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket + + clean: dep_clean +- $(Q)$(RM) core *.o $(EXEC) $(CLI) ++ $(Q)$(RM) core *.o $(EXEC) $(CLI) $(MANPAGES) + + include $(wildcard $(OBJS:.o=.d) $(CLI_OBJS:.o=.d)) + +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8.in +similarity index 97% +rename from multipathd/multipathd.8 +rename to multipathd/multipathd.8.in +index cc72b775..e98c27fd 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8.in +@@ -155,7 +155,7 @@ Show the format wildcards used in interactive commands taking $format. + .TP + .B list|show config + Show the currently used configuration, derived from default values and values +-specified within the configuration file \fI/etc/multipath.conf\fR. ++specified within the configuration file \fI@CONFIGFILE@\fR. + . + .TP + .B list|show config local +@@ -165,7 +165,7 @@ the devices section to those devices that are actually present in the system. + .TP + .B list|show blacklist + Show the currently used blacklist rules, derived from default values and values +-specified within the configuration file \fI/etc/multipath.conf\fR. ++specified within the configuration file \fI@CONFIGFILE@\fR. + . + .TP + .B list|show devices +@@ -290,13 +290,13 @@ Get the current persistent reservation key associated with $map. + .B map|multipath $map setprkey key $key + Set the persistent reservation key associated with $map to $key in the + \fIprkeys_file\fR. This key will only be used by multipathd if +-\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. ++\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. + . + .TP + .B map|multipath $map unsetprkey + Remove the persistent reservation key associated with $map from the + \fIprkeys_file\fR. This will only unset the key used by multipathd if +-\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. ++\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. + . + .TP + .B path $path setmarginal diff --git a/0032-libdmmp-Makefile-fix-bug-in-install-section.patch b/0032-libdmmp-Makefile-fix-bug-in-install-section.patch new file mode 100644 index 0000000..a3f2470 --- /dev/null +++ b/0032-libdmmp-Makefile-fix-bug-in-install-section.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 09:30:13 +0200 +Subject: [PATCH] libdmmp/Makefile: fix bug in install section + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libdmmp/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libdmmp/Makefile b/libdmmp/Makefile +index 078eca8f..172ba045 100644 +--- a/libdmmp/Makefile ++++ b/libdmmp/Makefile +@@ -44,7 +44,7 @@ install: + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) + $(Q)sed -i 's|__INCLUDEDIR__|$(includedir)|g' \ + $(DESTDIR)$(pkgconfdir)/$(PKGFILE) +- $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 ++ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 + $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 + + uninstall: diff --git a/0033-multipath-tools-README.md-improve-documentation-for-.patch b/0033-multipath-tools-README.md-improve-documentation-for-.patch new file mode 100644 index 0000000..3c7edd0 --- /dev/null +++ b/0033-multipath-tools-README.md-improve-documentation-for-.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 10:22:13 +0200 +Subject: [PATCH] multipath-tools: README.md: improve documentation for + compile-time options + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + README.md | 38 ++++++++++++++++++++++++++------------ + 1 file changed, 26 insertions(+), 12 deletions(-) + +diff --git a/README.md b/README.md +index a7f994ae..679e55bf 100644 +--- a/README.md ++++ b/README.md +@@ -89,9 +89,17 @@ The following variables can be passed to the `make` command line: + * `plugindir="/some/path"`: directory where libmultipath plugins (path + checkers, prioritizers, and foreign multipath support) will be looked up. + This used to be the run-time option `multipath_dir` in earlier versions. +- * `configdir="/some/path"` : directory to search for configuration files. ++ The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on ++ systems that have `/lib64`, and `lib` otherwise. ++ * `configfile="/some/path`": The path to the main configuration file. ++ The defalt is `$(etc_prefix)/etc/multipath.conf`. ++ * `configdir="/some/path"` : directory to search for additional configuration files. + This used to be the run-time option `config_dir` in earlier versions. +- The default is `/etc/multipath/conf.d`. ++ The default is `$(etc_prefix)/etc/multipath/conf.d`. ++ * `statedir="/some/path"`: The path of the directory where multipath-tools ++ stores run-time settings that need persist between reboots, such as known ++ WWIDs, user-friendly names, and persistent reservation keys. ++ The default is `$(etc_prefix)/etc/multipath`. + * `READLINE=libedit` or `READLINE=libreadline`: enable command line history + and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. + The respective development package will be required for building. +@@ -119,21 +127,27 @@ The following variables can be passed to the `make` command line: + ### Installation Paths + + * `prefix`: The directory prefix for (almost) all files to be installed. +- Distributions may want to set this to `/usr`. +- **Note**: for multipath-tools, unlike many other packages, `prefix` +- defaults to the empty string, which resolves to the root directory (`/`). ++ "Usr-merged" distributions[^systemd] may want to set this to `/usr`. The ++ default is empty (`""`). + * `usr_prefix`: where to install those parts of the code that aren't necessary +- for booting. You may want to set this to `/usr` if `prefix` is empty. +- * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. +- Some systemd installations use separate `prefix` and `rootprefix`. On such +- a distribution, set `prefix`, and override `unitdir` to use systemd's +- `rootprefix`. ++ for booting. Non-usr-merged distributions[^systemd] may want to set this to ++ `/usr`. The default is `$(prefix)`. ++ * `systemd_prefix`: Prefix for systemd-related files[^systemd]. The default is `/usr`. ++ * `etc_prefix`: The prefix for configuration files. "Usr-merged" ++ distributions with immutable `/usr`[^systemd] may want to set this to ++ `/etc`. The default is `$(prefix)`. + * `LIB`: the subdirectory under `prefix` where shared libraries will be + installed. By default, the makefile uses `/lib64` if this directory is + found on the build system, and `/lib` otherwise. + +-See also `configdir` and `plugindir` above. See `Makefile.inc` for more +-fine-grained control. ++The options `configdir`, `plugindir`, `configfile`, and `statedir` above can ++be used for setting indvidual paths where the `prefix` variables don't provide ++sufficient control. See `Makefile.inc` for even more fine-grained control. ++ ++[^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. ++ On such a distribution, set `prefix`, and override `unitdir` to use systemd's ++ `rootprefix`. Recent systemd releases generally require everything to be ++ installed under `/usr` (so-called "usr-merged" distribution). On "usr- + + ### Compiler Options + diff --git a/0034-libmultipath-print-built-in-values-for-deprecated-op.patch b/0034-libmultipath-print-built-in-values-for-deprecated-op.patch new file mode 100644 index 0000000..45e7874 --- /dev/null +++ b/0034-libmultipath-print-built-in-values-for-deprecated-op.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 11:36:25 +0200 +Subject: [PATCH] libmultipath: print built-in values for deprecated options + +In the error messages we print when a deprecated option is encountered, +print the compile-time value of the option. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index f81c84aa..dace343d 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -314,14 +314,16 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + static int deprecated_handler(struct config *conf, vector strvec, const char *file, + int line_nr); + +-#define declare_deprecated_handler(option) \ ++#define declare_deprecated_handler(option, default) \ + static int \ + deprecated_ ## option ## _handler (struct config *conf, vector strvec, \ + const char *file, int line_nr) \ + { \ + static bool warned; \ + if (!warned) { \ +- condlog(1, "%s line %d: ignoring deprecated option \"" #option "\"", file, line_nr); \ ++ condlog(1, "%s line %d: ignoring deprecated option \"" \ ++ #option "\", using built-in value: \"%s\"", \ ++ file, line_nr, default); \ + warned = true; \ + } \ + return deprecated_handler(conf, strvec, file, line_nr); \ +@@ -2057,11 +2059,11 @@ snprint_deprecated (struct config *conf, struct strbuf *buff, const void * data) + } + + // Deprecated keywords +-declare_deprecated_handler(config_dir) +-declare_deprecated_handler(disable_changed_wwids) +-declare_deprecated_handler(getuid_callout) +-declare_deprecated_handler(multipath_dir) +-declare_deprecated_handler(pg_timeout) ++declare_deprecated_handler(config_dir, CONFIG_DIR) ++declare_deprecated_handler(disable_changed_wwids, "yes") ++declare_deprecated_handler(getuid_callout, "(not set)") ++declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) ++declare_deprecated_handler(pg_timeout, "(not set)") + + /* + * If you add or remove a keyword also update multipath/multipath.conf.5 diff --git a/0035-multipath-add-a-missing-newline.patch b/0035-multipath-add-a-missing-newline.patch new file mode 100644 index 0000000..706b7d3 --- /dev/null +++ b/0035-multipath-add-a-missing-newline.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 11:37:37 +0200 +Subject: [PATCH] multipath: add a missing newline + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 45e9745f..b91289e8 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -1025,7 +1025,7 @@ main (int argc, char *argv[]) + } + + if (check_alias_settings(conf)) { +- fprintf(stderr, "fatal configuration error, aborting"); ++ fprintf(stderr, "fatal configuration error, aborting\n"); + exit(RTVL_FAIL); + } + diff --git a/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch b/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch new file mode 100644 index 0000000..c48240b --- /dev/null +++ b/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 16:03:34 +0200 +Subject: [PATCH] multipath-tools: allow prefixes with and w/o trailing slash + +Add some logic to Makefile.inc that leads to the same result +for "prefix=" and "prefix=/", or "prefix=/usr" and "prefix=/usr/". +The logic does not work for multiple trailing slashes. It applies +to all XYZ_prefix variables in Makefile.inc. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 35 ++++++++++++++++++++++------------- + 1 file changed, 22 insertions(+), 13 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 79e521e1..6e384e68 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -43,22 +43,31 @@ etc_prefix := $(prefix) + # Note: some systemd installations use separate "prefix" and "rootprefix". + # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) + systemd_prefix := /usr +-unitdir := $(systemd_prefix)/lib/systemd/system +-tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d +-modulesloaddir := $(systemd_prefix)/lib/modules-load.d +-libudevdir := $(systemd_prefix)/lib/udev ++ ++# Make sure all prefix variables end in "/" ++append-slash = $(1)$(if $(filter %/,$(1)),,/) ++override prefix := $(call append-slash,$(prefix)) ++override exec_prefix := $(call append-slash,$(exec_prefix)) ++override usr_prefix := $(call append-slash,$(usr_prefix)) ++override etc_prefix := $(call append-slash,$(etc_prefix)) ++override systemd_prefix := $(call append-slash,$(systemd_prefix)) ++ ++unitdir := $(systemd_prefix)lib/systemd/system ++tmpfilesdir := $(systemd_prefix)lib/tmpfiles.d ++modulesloaddir := $(systemd_prefix)lib/modules-load.d ++libudevdir := $(systemd_prefix)lib/udev + udevrulesdir := $(libudevdir)/rules.d +-bindir := $(exec_prefix)/sbin +-mandir := $(usr_prefix)/share/man ++bindir := $(exec_prefix)sbin ++mandir := $(usr_prefix)share/man + LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) +-syslibdir := $(prefix)/$(LIB) +-usrlibdir := $(usr_prefix)/$(LIB) +-includedir := $(usr_prefix)/include ++syslibdir := $(prefix)$(LIB) ++usrlibdir := $(usr_prefix)$(LIB) ++includedir := $(usr_prefix)include + pkgconfdir := $(usrlibdir)/pkgconfig +-plugindir := $(prefix)/$(LIB)/multipath +-configdir := $(etc_prefix)/etc/multipath/conf.d +-configfile := $(etc_prefix)/etc/multipath.conf +-statedir := $(etc_prefix)/etc/multipath ++plugindir := $(prefix)$(LIB)/multipath ++configdir := $(etc_prefix)etc/multipath/conf.d ++configfile := $(etc_prefix)etc/multipath.conf ++statedir := $(etc_prefix)etc/multipath + runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) + devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) + libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) diff --git a/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch b/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch new file mode 100644 index 0000000..6e066ee --- /dev/null +++ b/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch @@ -0,0 +1,897 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 11 Sep 2023 17:58:13 +0200 +Subject: [PATCH] libmultipath: deprecate bindings_file, wwids_file, + prkeys_file + +The options bindings_file, wwids_file, and prkeys_file have been +deprecated since cb4d6db ("libmultipath: deprecate file and directory config +options") (multipath-tools 0.8.8). Deprecate and ignore them now. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/alias.c | 43 +++++++++---------- + libmultipath/alias.h | 3 +- + libmultipath/config.c | 18 -------- + libmultipath/config.h | 3 -- + libmultipath/dict.c | 39 +++--------------- + libmultipath/libmultipath.version | 8 +--- + libmultipath/prkey.c | 7 ++-- + libmultipath/prkey.h | 7 ++-- + libmultipath/propsel.c | 5 +-- + libmultipath/wwids.c | 18 ++------ + multipath/main.c | 2 +- + multipath/multipath.conf.5.in | 23 +++++------ + multipathd/uxlsnr.c | 17 +++----- + tests/alias.c | 68 +++++++++++++++---------------- + 14 files changed, 90 insertions(+), 171 deletions(-) + +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index 964b8a7b..e5d3f151 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -55,6 +55,8 @@ + /* uatomic access only */ + static int bindings_file_changed = 1; + ++static const char bindings_file_path[] = DEFAULT_BINDINGS_FILE; ++ + static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; + static struct timespec bindings_last_updated; + +@@ -274,7 +276,6 @@ static int write_bindings_file(const Bindings *bindings, int fd, + + void handle_bindings_file_inotify(const struct inotify_event *event) + { +- struct config *conf; + const char *base; + bool changed = false; + struct stat st; +@@ -284,12 +285,9 @@ void handle_bindings_file_inotify(const struct inotify_event *event) + if (!(event->mask & IN_MOVED_TO)) + return; + +- conf = get_multipath_config(); +- base = strrchr(conf->bindings_file, '/'); +- changed = base && base > conf->bindings_file && +- !strcmp(base + 1, event->name); +- ret = stat(conf->bindings_file, &st); +- put_multipath_config(conf); ++ base = strrchr(bindings_file_path, '/'); ++ changed = base && !strcmp(base + 1, event->name); ++ ret = stat(bindings_file_path, &st); + + if (!changed) + return; +@@ -310,8 +308,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) + __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); + } + +-static int update_bindings_file(const Bindings *bindings, +- const char *bindings_file) ++static int update_bindings_file(const Bindings *bindings) + { + int rc; + int fd = -1; +@@ -319,7 +316,7 @@ static int update_bindings_file(const Bindings *bindings, + mode_t old_umask; + struct timespec ts; + +- if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) ++ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file_path)) + return -1; + /* coverity: SECURE_TEMP */ + old_umask = umask(0077); +@@ -336,13 +333,13 @@ static int update_bindings_file(const Bindings *bindings, + unlink(tempname); + return rc; + } +- if ((rc = rename(tempname, bindings_file)) == -1) ++ if ((rc = rename(tempname, bindings_file_path)) == -1) + condlog(0, "%s: rename: %m", __func__); + else { + pthread_mutex_lock(×tamp_mutex); + bindings_last_updated = ts; + pthread_mutex_unlock(×tamp_mutex); +- condlog(1, "updated bindings file %s", bindings_file); ++ condlog(1, "updated bindings file %s", bindings_file_path); + } + return rc; + } +@@ -474,7 +471,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww + + /* Called with binding_mutex held */ + static char * +-allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) ++allocate_binding(const char *wwid, int id, const char *prefix) + { + STRBUF_ON_STACK(buf); + char *alias; +@@ -498,7 +495,7 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre + return NULL; + } + +- if (update_bindings_file(&global_bindings, filename) == -1) { ++ if (update_bindings_file(&global_bindings) == -1) { + condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); + delete_binding(&global_bindings, wwid); + free(alias); +@@ -565,7 +562,7 @@ static void read_bindings_file(void) + * that the mpvec corrcectly represents kernel state. + */ + +-char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, ++char *get_user_friendly_alias(const char *wwid, const char *alias_old, + const char *prefix, bool bindings_read_only) + { + char *alias = NULL; +@@ -622,7 +619,7 @@ new_alias: + } + + if (!bindings_read_only && id > 0) +- alias = allocate_binding(file, wwid, id, prefix); ++ alias = allocate_binding(wwid, id, prefix); + + if (alias && !new_binding) + condlog(2, "Allocated existing binding [%s] for WWID [%s]", +@@ -715,12 +712,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, + header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; + if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { + condlog(2, "%s: failed to read header from %s", __func__, +- conf->bindings_file); ++ bindings_file_path); + fseek(file, 0, SEEK_SET); + rc = -1; + } else if (strcmp(header, BINDINGS_FILE_HEADER)) { + condlog(2, "%s: invalid header in %s", __func__, +- conf->bindings_file); ++ bindings_file_path); + fseek(file, 0, SEEK_SET); + rc = -1; + } +@@ -787,13 +784,13 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, + } + } + +- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); ++ fd = open_file(bindings_file_path, &can_write, BINDINGS_FILE_HEADER); + if (fd == -1) + return BINDINGS_FILE_ERROR; + + file = fdopen(fd, "r"); + if (file != NULL) { +- condlog(3, "%s: reading %s", __func__, conf->bindings_file); ++ condlog(3, "%s: reading %s", __func__, bindings_file_path); + + pthread_cleanup_push(cleanup_fclose, file); + ret = _check_bindings_file(conf, file, bindings); +@@ -812,20 +809,20 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, + bindings_last_updated = ts; + pthread_mutex_unlock(×tamp_mutex); + } else if (ret == -1 && can_write && !conf->bindings_read_only) { +- ret = update_bindings_file(bindings, conf->bindings_file); ++ ret = update_bindings_file(bindings); + if (ret == 0) + rc = BINDINGS_FILE_READ; + else + rc = BINDINGS_FILE_BAD; + } else { + condlog(0, "ERROR: bad settings in read-only bindings file %s", +- conf->bindings_file); ++ bindings_file_path); + rc = BINDINGS_FILE_BAD; + } + pthread_cleanup_pop(1); + } else { + condlog(1, "failed to fdopen %s: %m", +- conf->bindings_file); ++ bindings_file_path); + close(fd); + rc = BINDINGS_FILE_ERROR; + } +diff --git a/libmultipath/alias.h b/libmultipath/alias.h +index ca8911f4..629e8d56 100644 +--- a/libmultipath/alias.h ++++ b/libmultipath/alias.h +@@ -3,8 +3,7 @@ + + int valid_alias(const char *alias); + int get_user_friendly_wwid(const char *alias, char *buff); +-char *get_user_friendly_alias(const char *wwid, const char *file, +- const char *alias_old, ++char *get_user_friendly_alias(const char *wwid, const char *alias_old, + const char *prefix, bool bindings_read_only); + + struct config; +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 7b207590..b7dbc6f5 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -752,15 +752,6 @@ static void _uninit_config(struct config *conf) + if (conf->hwhandler) + free(conf->hwhandler); + +- if (conf->bindings_file) +- free(conf->bindings_file); +- +- if (conf->wwids_file) +- free(conf->wwids_file); +- +- if (conf->prkeys_file) +- free(conf->prkeys_file); +- + if (conf->prio_name) + free(conf->prio_name); + +@@ -922,9 +913,6 @@ int _init_config (const char *file, struct config *conf) + * internal defaults + */ + get_sys_max_fds(&conf->max_fds); +- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); +- conf->wwids_file = set_default(DEFAULT_WWIDS_FILE); +- conf->prkeys_file = set_default(DEFAULT_PRKEYS_FILE); + conf->attribute_flags = 0; + conf->reassign_maps = DEFAULT_REASSIGN_MAPS; + conf->checkint = CHECKINT_UNDEF; +@@ -1078,12 +1066,6 @@ int _init_config (const char *file, struct config *conf) + merge_blacklist(conf->elist_wwid); + merge_blacklist_device(conf->elist_device); + +- if (conf->bindings_file == NULL) +- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); +- +- if (!conf->bindings_file || !conf->wwids_file || !conf->prkeys_file) +- goto out; +- + libmp_verbosity = conf->verbosity; + return 0; + out: +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 0a2c297b..8c22ce75 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -207,9 +207,6 @@ struct config { + char * uid_attribute; + char * features; + char * hwhandler; +- char * bindings_file; +- char * wwids_file; +- char * prkeys_file; + char * prio_name; + char * prio_args; + char * checker_name; +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index dace343d..044067af 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -168,27 +168,6 @@ fail: + return 0; + } + +-static int +-set_path(vector strvec, void *ptr, const char *file, int line_nr) +-{ +- char **str_ptr = (char **)ptr; +- char *old_str = *str_ptr; +- +- *str_ptr = set_value(strvec); +- if (!*str_ptr) { +- free(old_str); +- return 1; +- } +- if ((*str_ptr)[0] != '/'){ +- condlog(1, "%s line %d, %s is not an absolute path. Ignoring", +- file, line_nr, *str_ptr); +- free(*str_ptr); +- *str_ptr = old_str; +- } else +- free(old_str); +- return 0; +-} +- + static int + set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) + { +@@ -831,15 +810,6 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_warn_handler(bindings_file, set_path) +-declare_def_snprint(bindings_file, print_str) +- +-declare_def_warn_handler(wwids_file, set_path) +-declare_def_snprint(wwids_file, print_str) +- +-declare_def_warn_handler(prkeys_file, set_path) +-declare_def_snprint(prkeys_file, print_str) +- + declare_def_handler(retain_hwhandler, set_yes_no_undef) + declare_def_snprint_defint(retain_hwhandler, print_yes_no_undef, + DEFAULT_RETAIN_HWHANDLER) +@@ -2064,6 +2034,9 @@ declare_deprecated_handler(disable_changed_wwids, "yes") + declare_deprecated_handler(getuid_callout, "(not set)") + declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) + declare_deprecated_handler(pg_timeout, "(not set)") ++declare_deprecated_handler(bindings_file, DEFAULT_BINDINGS_FILE) ++declare_deprecated_handler(wwids_file, DEFAULT_WWIDS_FILE) ++declare_deprecated_handler(prkeys_file, DEFAULT_PRKEYS_FILE) + + /* + * If you add or remove a keyword also update multipath/multipath.conf.5 +@@ -2106,9 +2079,9 @@ init_keywords(vector keywords) + install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); + install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); + install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline); +- install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file); +- install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file); +- install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); ++ install_keyword("bindings_file", &deprecated_bindings_file_handler, &snprint_deprecated); ++ install_keyword("wwids_file", &deprecated_wwids_file_handler, &snprint_deprecated); ++ install_keyword("prkeys_file", &deprecated_prkeys_file_handler, &snprint_deprecated); + install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err); + install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key); + install_keyword("all_tg_pt", &def_all_tg_pt_handler, &snprint_def_all_tg_pt); +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 57e50c12..8368ef7a 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { + put_multipath_config; + }; + +-LIBMULTIPATH_20.0.0 { ++LIBMULTIPATH_21.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; +@@ -121,6 +121,7 @@ global: + get_used_hwes; + get_vpd_sgio; + group_by_prio; ++ handle_bindings_file_inotify; + has_dm_info; + init_checkers; + init_config; +@@ -238,8 +239,3 @@ global: + local: + *; + }; +- +-LIBMULTIPATH_20.1.0 { +-global: +- handle_bindings_file_inotify; +-}; +diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c +index a215499d..c66d293b 100644 +--- a/libmultipath/prkey.c ++++ b/libmultipath/prkey.c +@@ -157,8 +157,7 @@ static int do_prkey(int fd, char *wwid, char *keystr, int cmd) + return 0; + } + +-int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, +- uint8_t *sa_flags) ++int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags) + { + int fd; + int unused; +@@ -168,7 +167,7 @@ int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, + if (!strlen(mpp->wwid)) + goto out; + +- fd = open_file(conf->prkeys_file, &unused, PRKEYS_FILE_HEADER); ++ fd = open_file(DEFAULT_PRKEYS_FILE, &unused, PRKEYS_FILE_HEADER); + if (fd < 0) + goto out; + ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ); +@@ -201,7 +200,7 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, + sa_flags &= MPATH_F_APTPL_MASK; + } + +- fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER); ++ fd = open_file(DEFAULT_PRKEYS_FILE, &can_write, PRKEYS_FILE_HEADER); + if (fd < 0) + goto out; + if (!can_write) { +diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h +index a16de106..43afd5e4 100644 +--- a/libmultipath/prkey.h ++++ b/libmultipath/prkey.h +@@ -16,9 +16,8 @@ + int print_reservation_key(struct strbuf *buff, + struct be64 key, uint8_t flags, int source); + int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); +-int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, +- uint8_t sa_flags); +-int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, +- uint8_t *sa_flags); ++int set_prkey(struct config *conf, struct multipath *mpp, ++ uint64_t prkey, uint8_t sa_flags); ++int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags); + + #endif /* _PRKEY_H */ +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 354e883f..44241e2a 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -401,8 +401,7 @@ int select_alias(struct config *conf, struct multipath * mp) + + select_alias_prefix(conf, mp); + +- mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, +- mp->alias_old, mp->alias_prefix, ++ mp->alias = get_user_friendly_alias(mp->wwid, mp->alias_old, mp->alias_prefix, + conf->bindings_read_only); + + if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) +@@ -992,7 +991,7 @@ int select_reservation_key(struct config *conf, struct multipath *mp) + out: + if (mp->prkey_source == PRKEY_SOURCE_FILE) { + from_file = " (from prkeys file)"; +- if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0) ++ if (get_prkey(mp, &prkey, &mp->sa_flags) != 0) + put_be64(mp->reservation_key, 0); + else + put_be64(mp->reservation_key, prkey); +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 89bb60ca..591cd09b 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -94,12 +94,8 @@ replace_wwids(vector mp) + struct multipath * mpp; + size_t len; + int ret = -1; +- struct config *conf; + +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); +- pthread_cleanup_pop(1); ++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); + if (fd < 0) + goto out; + +@@ -200,7 +196,6 @@ remove_wwid(char *wwid) { + int len, can_write; + char *str; + int ret = -1; +- struct config *conf; + + len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */ + str = malloc(len); +@@ -216,10 +211,7 @@ remove_wwid(char *wwid) { + goto out; + } + condlog(3, "removing line '%s' from wwids file", str); +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); +- pthread_cleanup_pop(1); ++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); + + if (fd < 0) { + ret = -1; +@@ -244,12 +236,8 @@ check_wwids_file(char *wwid, int write_wwid) + { + int fd, can_write, found, ret; + FILE *f; +- struct config *conf; + +- conf = get_multipath_config(); +- pthread_cleanup_push(put_multipath_config, conf); +- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); +- pthread_cleanup_pop(1); ++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); + if (fd < 0) + return -1; + +diff --git a/multipath/main.c b/multipath/main.c +index b91289e8..9e1c5052 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -856,7 +856,7 @@ main (int argc, char *argv[]) + libmp_verbosity = atoi(optarg); + break; + case 'b': +- conf->bindings_file = strdup(optarg); ++ condlog(1, "option -b ignored"); + break; + case 'B': + conf->bindings_read_only = 1; +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 20df2232..d320a88f 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -794,35 +794,28 @@ The default is: \fB\fR + . + .TP + .B bindings_file +-(Deprecated) This option is deprecated, and will be removed in a future release. +-The full pathname of the binding file to be used when the user_friendly_names +-option is set. ++(Deprecated) This option is not supported any more, and will be ignored. + .RS + .TP +-The default is: \fB@STATE_DIR@/bindings\fR ++The compiled-in value is: \fB@STATE_DIR@/bindings\fR + .RE + . + . + .TP + .B wwids_file +-(Deprecated) This option is deprecated, and will be removed in a future release. +-The full pathname of the WWIDs file, which is used by multipath to keep track +-of the WWIDs for LUNs it has created multipath devices on in the past. ++(Deprecated) This option is not supported any more, and will be ignored. + .RS + .TP +-The default is: \fB@STATE_DIR@/wwids\fR ++The compiled-in value is: \fB@STATE_DIR@/wwids\fR + .RE + . + . + .TP + .B prkeys_file +-(Deprecated) This option is deprecated, and will be removed in a future release. +-The full pathname of the prkeys file, which is used by multipathd to keep +-track of the persistent reservation key used for a specific WWID, when +-\fIreservation_key\fR is set to \fBfile\fR. ++(Deprecated) This option is not supported any more, and will be ignored. + .RS + .TP +-The default is: \fB@STATE_DIR@/prkeys\fR ++The compiled-in value is: \fB@STATE_DIR@/prkeys\fR + .RE + . + . +@@ -989,6 +982,10 @@ The default is: \fB\fR + .TP + .B config_dir + (Deprecated) This option is not supported any more, and the value is ignored. ++.RS ++.TP ++The compiled-in value is: \fB@CONFIGDIR@\fR ++.RE + . + . + .TP +diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c +index d1f8f234..4d6f258c 100644 +--- a/multipathd/uxlsnr.c ++++ b/multipathd/uxlsnr.c +@@ -203,7 +203,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + int dir_reset = 0; + int conf_reset = 0; + int mp_reset = 0; +- char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; + + if (notify_fd == -1) + return; +@@ -221,7 +220,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + if (wds->mp_wd == -1) + mp_reset = 1; + } +- bindings_file = strdup(conf->bindings_file); + put_multipath_config(conf); + + if (dir_reset) { +@@ -242,17 +240,12 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, + if (wds->conf_wd == -1) + condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); + } +- if (mp_reset && bindings_file) { +- char *slash = strrchr(bindings_file, '/'); +- +- if (slash && slash > bindings_file) { +- *slash = '\0'; +- wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, +- IN_MOVED_TO|IN_ONLYDIR); +- if (wds->mp_wd == -1) ++ if (mp_reset) { ++ wds->mp_wd = inotify_add_watch(notify_fd, STATE_DIR, ++ IN_MOVED_TO|IN_ONLYDIR); ++ if (wds->mp_wd == -1) + condlog(3, "didn't set up notifications on %s: %m", +- bindings_file); +- } ++ STATE_DIR); + } + } + +diff --git a/tests/alias.c b/tests/alias.c +index 94df36d8..f893d174 100644 +--- a/tests/alias.c ++++ b/tests/alias.c +@@ -1264,10 +1264,10 @@ static void al_a(void **state) + will_return(__wrap_write, ln); + will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); + will_return(__wrap_rename, 0); +- expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); + expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); + check_bindings_size(1); +@@ -1283,10 +1283,10 @@ static void al_zz(void **state) + will_return(__wrap_write, ln); + will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); + will_return(__wrap_rename, 0); +- expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); + expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); + +- alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); ++ alias = allocate_binding("WWIDzz", 26*26 + 26, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHzz"); + check_bindings_size(1); +@@ -1298,7 +1298,7 @@ static void al_0(void **state) + char *alias; + + expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); +- alias = allocate_binding(0, "WWIDa", 0, "MPATH"); ++ alias = allocate_binding("WWIDa", 0, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1308,7 +1308,7 @@ static void al_m2(void **state) + char *alias; + + expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); +- alias = allocate_binding(0, "WWIDa", -2, "MPATH"); ++ alias = allocate_binding("WWIDa", -2, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1325,10 +1325,10 @@ static void al_write_partial(void **state) + will_return(__wrap_write, ln + sizeof(ln) - 2); + will_return(__wrap_write, 1); + will_return(__wrap_rename, 0); +- expect_condlog(1, "updated bindings file foo"); ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); + expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); + check_bindings_size(1); +@@ -1350,7 +1350,7 @@ static void al_write_short(void **state) + expect_condlog(1, "failed to write new bindings file"); + expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1366,7 +1366,7 @@ static void al_write_err(void **state) + expect_condlog(1, "failed to write new bindings file"); + expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); + +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1383,7 +1383,7 @@ static void al_rename_err(void **state) + + expect_condlog(0, "update_bindings_file: rename: Read-only file system"); + expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); +- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); ++ alias = allocate_binding("WWIDa", 1, "MPATH"); + assert_ptr_equal(alias, NULL); + check_bindings_size(0); + } +@@ -1415,7 +1415,7 @@ static int test_allocate_binding(void) + strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ + will_return(__wrap_rename, err); \ + if (err == 0) { \ +- expect_condlog(1, "updated bindings file x\n"); \ ++ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); \ + expect_condlog(3, NEW_STR(alias, wwid)); \ + } else { \ + expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ +@@ -1441,7 +1441,7 @@ static void gufa_empty_new_rw(void **state) { + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + + mock_allocate_binding("MPATHa", "WWID0"); +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1454,7 +1454,7 @@ static void gufa_empty_new_ro_1(void **state) { + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); + assert_ptr_equal(alias, NULL); + } + +@@ -1465,7 +1465,7 @@ static void gufa_empty_new_ro_2(void **state) { + expect_condlog(3, NOMATCH_WWID_STR("WWID0")); + mock_unused_alias("MPATHa"); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_ptr_equal(alias, NULL); + } + +@@ -1477,7 +1477,7 @@ static void gufa_match_a_unused(void **state) { + mock_unused_alias("MPATHa"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1490,7 +1490,7 @@ static void gufa_match_a_self(void **state) { + mock_self_alias("MPATHa", "WWID0"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1503,7 +1503,7 @@ static void gufa_match_a_used(void **state) { + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); + assert_ptr_equal(alias, NULL); + } + +@@ -1518,7 +1518,7 @@ static void gufa_nomatch_a_c(void **state) { + + mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); + +- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); + } +@@ -1534,7 +1534,7 @@ static void gufa_nomatch_c_a(void **state) { + + mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); + } +@@ -1550,7 +1550,7 @@ static void gufa_nomatch_c_b(void **state) { + + mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1567,7 +1567,7 @@ static void gufa_nomatch_c_b_used(void **state) { + + mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID4", "", "MPATH", false); + assert_string_equal(alias, "MPATHd"); + free(alias); + } +@@ -1584,7 +1584,7 @@ static void gufa_nomatch_b_f_a(void **state) { + + mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); + assert_string_equal(alias, "MPATHc"); + free(alias); + } +@@ -1599,7 +1599,7 @@ static void gufa_nomatch_b_aa_a(void **state) { + mock_unused_alias("MPATHab"); + mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); + +- alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID28", "", "MPATH", false); + assert_string_equal(alias, "MPATHab"); + free(alias); + } +@@ -1616,7 +1616,7 @@ static void gufa_nomatch_b_f_a_sorted(void **state) { + + mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); ++ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); + assert_string_equal(alias, "MPATHc"); + free(alias); + } +@@ -1632,7 +1632,7 @@ static void gufa_old_empty(void **state) { + mock_allocate_binding("MPATHz", "WWID0"); + expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHz"); + free(alias); + } +@@ -1644,7 +1644,7 @@ static void gufa_old_match(void **state) { + "MPATHz WWID0"); + expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHz"); + free(alias); + } +@@ -1661,7 +1661,7 @@ static void gufa_old_match_other(void **state) { + + mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1678,7 +1678,7 @@ static void gufa_old_match_other_used(void **state) { + mock_unused_alias("MPATHb"); + + mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHb"); + free(alias); + } +@@ -1695,7 +1695,7 @@ static void gufa_old_match_other_wwidmatch(void **state) { + mock_unused_alias("MPATHc"); + expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); + +- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHc"); + free(alias); + } +@@ -1711,7 +1711,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { + expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); + mock_used_alias("MPATHc", "WWID2"); + +- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); + } + +@@ -1725,7 +1725,7 @@ static void gufa_old_nomatch_wwidmatch(void **state) { + mock_unused_alias("MPATHa"); + expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHa"); + free(alias); + } +@@ -1739,7 +1739,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { + expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); + mock_used_alias("MPATHa", "WWID0"); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_ptr_equal(alias, NULL); + } + +@@ -1754,7 +1754,7 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { + mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); + expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); + +- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); ++ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); + assert_string_equal(alias, "MPATHz"); + free(alias); + } diff --git a/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch b/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch new file mode 100644 index 0000000..269efcf --- /dev/null +++ b/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch @@ -0,0 +1,158 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 Sep 2023 11:54:47 +0200 +Subject: [PATCH] libmultipath: avoid -Warray-bounds error in uatomic + operations + +The use of uatomic_xchg() in alias.c causes a -Warray-bounds error +on distributions using gcc 12, such as Fedora 37. This is a similar +error to 2534c4f ("libmultipath: avoid -Warray-bounds error with gcc +12 and musl libc"). This happens only with liburcu 0.13 and earlier, +and only with certain gcc versions. See liburcu commit 835b9ab +("Fix: x86 and s390 uatomic: __hp() macro warning with gcc 11"). + +Enhance the fix for 2534c4f by a adding a workaround for uatomic_xchg(), +and introduce the macro URCU_VERSION (originally only used for multipathd) +globally. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + create-config.mk | 5 +++++ + libmultipath/alias.c | 5 +++-- + libmultipath/lock.h | 21 +++++++++++++-------- + multipathd/Makefile | 2 -- + 5 files changed, 22 insertions(+), 13 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 6e384e68..04bfa56e 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -95,7 +95,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 + WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ ++CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ + -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ +diff --git a/create-config.mk b/create-config.mk +index d1255971..4d318b96 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -73,6 +73,10 @@ TEST_URCU_TYPE_LIMITS = $(shell \ + $(CC) -c -Werror=type-limits -o /dev/null -xc - 2>/dev/null \ + || echo -Wno-type-limits ) + ++URCU_VERSION = $(shell \ ++ $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ ++ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') ++ + DEFINES := + + ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) +@@ -168,6 +172,7 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h + @echo creating $@ + @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ + @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ ++ @echo "D_URCU_VERSION := $(call URCU_VERSION)" >>$@ + @echo "SYSTEMD := $(SYSTEMD)" >>$@ + @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ + @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ +diff --git a/libmultipath/alias.c b/libmultipath/alias.c +index e5d3f151..74431f3f 100644 +--- a/libmultipath/alias.c ++++ b/libmultipath/alias.c +@@ -24,6 +24,7 @@ + #include "devmapper.h" + #include "strbuf.h" + #include "time-util.h" ++#include "lock.h" + + /* + * significant parts of this file were taken from iscsi-bindings.c of the +@@ -300,7 +301,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) + pthread_mutex_unlock(×tamp_mutex); + + if (changed) { +- uatomic_xchg(&bindings_file_changed, 1); ++ uatomic_xchg_int(&bindings_file_changed, 1); + condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", + __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); + } else +@@ -775,7 +776,7 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, + int rc = 0, ret, fd; + FILE *file; + struct stat st; +- int has_changed = uatomic_xchg(&bindings_file_changed, 0); ++ int has_changed = uatomic_xchg_int(&bindings_file_changed, 0); + + if (!force) { + if (!has_changed) { +diff --git a/libmultipath/lock.h b/libmultipath/lock.h +index 9814be76..ac80d1d8 100644 +--- a/libmultipath/lock.h ++++ b/libmultipath/lock.h +@@ -13,15 +13,20 @@ struct mutex_lock { + int waiters; /* uatomic access only */ + }; + +-#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 ++static inline void init_lock(struct mutex_lock *a) ++{ ++ pthread_mutex_init(&a->mutex, NULL); ++ uatomic_set(&a->waiters, 0); ++} ++ ++#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + #endif + +-static inline void init_lock(struct mutex_lock *a) ++static inline int uatomic_xchg_int(int *ptr, int val) + { +- pthread_mutex_init(&a->mutex, NULL); +- uatomic_set(&a->waiters, 0); ++ return uatomic_xchg(ptr, val); + } + + static inline void lock(struct mutex_lock *a) +@@ -31,6 +36,10 @@ static inline void lock(struct mutex_lock *a) + uatomic_dec(&a->waiters); + } + ++#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 ++#pragma GCC diagnostic pop ++#endif ++ + static inline int trylock(struct mutex_lock *a) + { + return pthread_mutex_trylock(&a->mutex); +@@ -51,10 +60,6 @@ static inline bool lock_has_waiters(struct mutex_lock *a) + return (uatomic_read(&a->waiters) > 0); + } + +-#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 +-#pragma GCC diagnostic pop +-#endif +- + #define lock_cleanup_pop(a) pthread_cleanup_pop(1) + + void cleanup_lock (void * data); +diff --git a/multipathd/Makefile b/multipathd/Makefile +index cdba3db1..0ba6ecb7 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -5,8 +5,6 @@ CLI := multipathc + MANPAGES := multipathd.8 + + CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ +- $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ +- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ + -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) + + # diff --git a/0039-multipath-tools-fix-spelling.patch b/0039-multipath-tools-fix-spelling.patch new file mode 100644 index 0000000..c0c86f9 --- /dev/null +++ b/0039-multipath-tools-fix-spelling.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Fri, 15 Sep 2023 22:22:06 +0200 +Subject: [PATCH] multipath-tools: fix spelling + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 4 ++-- + multipath/multipath.conf.5.in | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/README.md b/README.md +index 679e55bf..524c9fb1 100644 +--- a/README.md ++++ b/README.md +@@ -92,7 +92,7 @@ The following variables can be passed to the `make` command line: + The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on + systems that have `/lib64`, and `lib` otherwise. + * `configfile="/some/path`": The path to the main configuration file. +- The defalt is `$(etc_prefix)/etc/multipath.conf`. ++ The default is `$(etc_prefix)/etc/multipath.conf`. + * `configdir="/some/path"` : directory to search for additional configuration files. + This used to be the run-time option `config_dir` in earlier versions. + The default is `$(etc_prefix)/etc/multipath/conf.d`. +@@ -141,7 +141,7 @@ The following variables can be passed to the `make` command line: + found on the build system, and `/lib` otherwise. + + The options `configdir`, `plugindir`, `configfile`, and `statedir` above can +-be used for setting indvidual paths where the `prefix` variables don't provide ++be used for setting individual paths where the `prefix` variables don't provide + sufficient control. See `Makefile.inc` for even more fine-grained control. + + [^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index d320a88f..226d0019 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -36,7 +36,7 @@ Files ending in \fI.conf\fR in this directory are read + in alphabetical order, after reading \fI@CONFIGFILE@\fR. + They use the same syntax as \fI@CONFIGFILE@\fR itself, + and support all sections and keywords. If a keyword occurs in the same section +-in multiple files, the last occurence will take precedence over all others. ++in multiple files, the last occurrence will take precedence over all others. + . + . + .\" ---------------------------------------------------------------------------- diff --git a/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch b/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch new file mode 100644 index 0000000..7ed50a3 --- /dev/null +++ b/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch @@ -0,0 +1,300 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Muneendra +Date: Wed, 20 Sep 2023 20:41:15 -0700 +Subject: [PATCH] multipathd: Added support to handle FPIN-Li events for + FC-NVMe + + This patch adds the support to handle FPIN-Li for FC-NVMe. + On receiving the FPIN-Li events this patch moves the devices paths + which are affected due to link integrity to marginal path groups. + The paths which are set to marginal path group will be unset + on receiving the RSCN events + +(mwilck: minor compile fix for 32-bit architectures) + +Signed-off-by: Muneendra +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/fpin_handlers.c | 206 +++++++++++++++++++++++++++---------- + 1 file changed, 151 insertions(+), 55 deletions(-) + +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +index aa0f63c9..be087ca0 100644 +--- a/multipathd/fpin_handlers.c ++++ b/multipathd/fpin_handlers.c +@@ -60,18 +60,15 @@ static void _udev_device_unref(void *p) + + + /*set/unset the path state to marginal*/ +-static int fpin_set_pathstate(struct path *pp, bool set) ++static void fpin_set_pathstate(struct path *pp, bool set) + { + const char *action = set ? "set" : "unset"; + +- if (!pp || !pp->mpp || !pp->mpp->alias) +- return -1; +- +- condlog(3, "\n%s: %s marginal path %s (fpin)", +- action, pp->mpp->alias, pp->dev_t); ++ condlog(3, "%s: %s marginal path %s (fpin)", ++ pp->mpp ? pp->mpp->alias : "orphan", action, pp->dev_t); + pp->marginal = set; +- pp->mpp->fpin_must_reload = true; +- return 0; ++ if (pp->mpp) ++ pp->mpp->fpin_must_reload = true; + } + + /* This will unset marginal state of a device*/ +@@ -82,14 +79,14 @@ static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs) + pp = find_path_by_dev(vecs->pathvec, devname); + if (!pp) + pp = find_path_by_devt(vecs->pathvec, devname); +- +- fpin_set_pathstate(pp, false); ++ if (pp) ++ fpin_set_pathstate(pp, false); + } + + /*This will set the marginal state of a device*/ +-static int fpin_path_setmarginal(struct path *pp) ++static void fpin_path_setmarginal(struct path *pp) + { +- return fpin_set_pathstate(pp, true); ++ fpin_set_pathstate(pp, true); + } + + /* Unsets all the devices in the list from marginal state */ +@@ -183,8 +180,8 @@ static void fpin_set_rport_marginal(struct udev_device *rport_dev) + udev_device_get_syspath(rport_dev)); + } + +-/*Add the marginal devices info into the list*/ +-static void ++/*Add the marginal devices info into the list and return 0 on success*/ ++static int + fpin_add_marginal_dev_info(uint32_t host_num, char *devname) + { + struct marginal_dev_list *newdev = NULL; +@@ -199,65 +196,160 @@ fpin_add_marginal_dev_info(uint32_t host_num, char *devname) + list_add_tail(&(newdev->node), + &fpin_li_marginal_dev_list_head); + pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); +- } ++ } else ++ return -ENOMEM; ++ return 0; + } + + /* +- * This function goes through the vecs->pathvec, and for +- * each path, check that the host number, +- * the target WWPN associated with the path matches +- * with the els wwpn and sets the path and port state to ++ * This function compares Transport Address Controller Port pn, ++ * Host Transport Address Controller Port pn with the els wwpn ,attached_wwpn ++ * and return 1 (match) or 0 (no match) or a negative error code ++ */ ++static int extract_nvme_addresses_chk_path_pwwn(const char *address, ++ uint64_t els_wwpn, uint64_t els_attached_wwpn) ++ ++{ ++ uint64_t traddr; ++ uint64_t host_traddr; ++ ++ /* ++ * Find the position of "traddr=" and "host_traddr=" ++ * and the address will be in the below format ++ * "traddr=nn-0x200400110dff9400:pn-0x200400110dff9400, ++ * host_traddr=nn-0x200400110dff9400:pn-0x200400110dff9400" ++ */ ++ const char *traddr_start = strstr(address, "traddr="); ++ const char *host_traddr_start = strstr(address, "host_traddr="); ++ ++ if (!traddr_start || !host_traddr_start) ++ return -EINVAL; ++ ++ /* Extract traddr pn */ ++ if (sscanf(traddr_start, "traddr=nn-%*[^:]:pn-%" SCNx64, &traddr) != 1) ++ return -EINVAL; ++ ++ /* Extract host_traddr pn*/ ++ if (sscanf(host_traddr_start, "host_traddr=nn-%*[^:]:pn-%" SCNx64, ++ &host_traddr) != 1) ++ return -EINVAL; ++ condlog(4, "traddr 0x%" PRIx64 " hosttraddr 0x%" PRIx64 " els_wwpn 0x%" ++ PRIx64" els_host_traddr 0x%" PRIx64, ++ traddr, host_traddr, ++ els_wwpn, els_attached_wwpn); ++ if ((host_traddr == els_attached_wwpn) && (traddr == els_wwpn)) ++ return 1; ++ return 0; ++} ++ ++/* ++ * This function check that the Transport Address Controller Port pn, ++ * Host Transport Address Controller Port pn associated with the path matches ++ * with the els wwpn ,attached_wwpn and sets the path state to + * Marginal + */ +-static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, ++static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp, ++ uint64_t els_wwpn, uint64_t attached_wwpn) ++{ ++ struct udev_device *ctl = NULL; ++ const char *address = NULL; ++ int ret = 0; ++ ++ ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL); ++ if (ctl == NULL) { ++ condlog(2, "%s: No parent device for ", pp->dev); ++ return; ++ } ++ address = udev_device_get_sysattr_value(ctl, "address"); ++ if (!address) { ++ condlog(2, "%s: unable to get the address ", pp->dev); ++ return; ++ } ++ condlog(4, "\n address %s: dev :%s\n", address, pp->dev); ++ ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn); ++ if (ret <= 0) ++ return; ++ ret = fpin_add_marginal_dev_info(host_num, pp->dev); ++ if (ret < 0) ++ return; ++ fpin_path_setmarginal(pp); ++} ++ ++/* ++ * This function check the host number, the target WWPN ++ * associated with the path matches with the els wwpn and ++ * sets the path and port state to Marginal ++ */ ++static void fpin_check_set_scsi_path_marginal(uint16_t host_num, struct path *pp, + uint64_t els_wwpn) + { +- struct path *pp; +- struct multipath *mpp; +- int i, k; + char rport_id[42]; + const char *value = NULL; + struct udev_device *rport_dev = NULL; + uint64_t wwpn; + int ret = 0; ++ sprintf(rport_id, "rport-%d:%d-%d", ++ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); ++ rport_dev = udev_device_new_from_subsystem_sysname(udev, ++ "fc_remote_ports", rport_id); ++ if (!rport_dev) { ++ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, ++ rport_id); ++ return; ++ } ++ pthread_cleanup_push(_udev_device_unref, rport_dev); ++ value = udev_device_get_sysattr_value(rport_dev, "port_name"); ++ if (!value) ++ goto unref; ++ ++ wwpn = strtol(value, NULL, 16); ++ /* ++ * If the port wwpn matches sets the path and port state ++ * to marginal ++ */ ++ if (wwpn == els_wwpn) { ++ ret = fpin_add_marginal_dev_info(host_num, pp->dev); ++ if (ret < 0) ++ goto unref; ++ fpin_path_setmarginal(pp); ++ fpin_set_rport_marginal(rport_dev); ++ } ++unref: ++ pthread_cleanup_pop(1); ++ return; ++ ++} ++ ++/* ++ * This function goes through the vecs->pathvec, and for ++ * each path, it checks and sets the path state to marginal ++ * if the path's associated port wwpn ,hostnum matches with ++ * els wwnpn ,attached_wwpn ++ */ ++static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, ++ uint64_t els_wwpn, uint64_t attached_wwpn) ++{ ++ struct path *pp; ++ struct multipath *mpp; ++ int i, k; ++ int ret = 0; + + pthread_cleanup_push(cleanup_lock, &vecs->lock); + lock(&vecs->lock); + pthread_testcancel(); + + vector_foreach_slot(vecs->pathvec, pp, k) { +- /* Checks the host number and also for the SCSI FCP */ +- if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) ++ if (!pp->mpp) + continue; +- sprintf(rport_id, "rport-%d:%d-%d", +- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); +- rport_dev = udev_device_new_from_subsystem_sysname(udev, +- "fc_remote_ports", rport_id); +- if (!rport_dev) { +- condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, +- rport_id); +- continue; +- } +- pthread_cleanup_push(_udev_device_unref, rport_dev); +- value = udev_device_get_sysattr_value(rport_dev, "port_name"); +- if (!value) +- goto unref; +- +- if (value) +- wwpn = strtol(value, NULL, 16); +- /* +- * If the port wwpn matches sets the path and port state +- * to marginal +- */ +- if (wwpn == els_wwpn) { +- ret = fpin_path_setmarginal(pp); +- if (ret < 0) +- goto unref; +- fpin_set_rport_marginal(rport_dev); +- fpin_add_marginal_dev_info(host_num, pp->dev); ++ /*checks if the bus type is nvme and the protocol is FC-NVMe*/ ++ if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) { ++ fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn); ++ } else if ((pp->bus == SYSFS_BUS_SCSI) && ++ (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) && ++ (host_num == pp->sg_id.host_no)) { ++ /* Checks the host number and also for the SCSI FCP */ ++ fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn); + } +-unref: +- pthread_cleanup_pop(1); + } + /* walk backwards because reload_and_sync_map() can remove mpp */ + vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { +@@ -286,14 +378,18 @@ fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv, + struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; + int count = 0; + int ret = 0; ++ uint64_t attached_wwpn; + + /* Update the wwn to list */ + wwn_count = be32_to_cpu(li_desc->pname_count); +- condlog(4, "Got wwn count as %d\n", wwn_count); ++ attached_wwpn = be64_to_cpu(li_desc->attached_wwpn); ++ condlog(4, "Got wwn count as %d detecting wwn 0x%" PRIx64 ++ " attached_wwpn 0x%" PRIx64 "\n", ++ wwn_count, be64_to_cpu(li_desc->detecting_wwpn), attached_wwpn); + + for (iter = 0; iter < wwn_count; iter++) { + wwpn = be64_to_cpu(li_desc->pname_list[iter]); +- ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn); ++ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn, attached_wwpn); + if (ret < 0) + condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn); + diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0041-RH-fixup-udev-rules-for-redhat.patch similarity index 89% rename from 0001-RH-fixup-udev-rules-for-redhat.patch rename to 0041-RH-fixup-udev-rules-for-redhat.patch index 618603c..e96c1e7 100644 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ b/0041-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 2e25d2ea..540e1dfc 100644 +index 04bfa56e..62d3d5cc 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,9 +34,9 @@ endif @@ -27,9 +27,9 @@ index 2e25d2ea..540e1dfc 100644 # Prefix for non-essential libraries (libdmmp) -usr_prefix := $(prefix) +usr_prefix := $(prefix)/usr + # Prefix for configfuration files (multipath.conf) + etc_prefix := $(prefix) # Where to install systemd-related files. systemd is usually installed under /usr - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules index 1969dee0..d2b28233 100644 --- a/kpartx/kpartx.rules @@ -43,10 +43,10 @@ index 1969dee0..d2b28233 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 73db991a..b3c2cc81 100644 +index 68cb5ce7..f70e64ec 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -24,7 +24,7 @@ install: +@@ -26,7 +26,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) @@ -55,7 +55,7 @@ index 73db991a..b3c2cc81 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -@@ -44,7 +44,7 @@ uninstall: +@@ -46,7 +46,7 @@ uninstall: $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf @@ -63,4 +63,4 @@ index 73db991a..b3c2cc81 100644 + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 - + $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0042-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 79% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0042-RH-Remove-the-property-blacklist-exception-builtin.patch index cbd2480..61e8943 100644 --- a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0042-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -13,26 +13,25 @@ it. Signed-off-by: Benjamin Marzinski --- - libmultipath/blacklist.c | 6 ++---- - multipath/multipath.conf.5 | 11 ++++++----- - tests/blacklist.c | 7 ++----- - 3 files changed, 10 insertions(+), 14 deletions(-) + libmultipath/blacklist.c | 5 ++--- + multipath/multipath.conf.5.in | 11 ++++++----- + tests/blacklist.c | 7 ++----- + 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 8d15d2ea..eff690fd 100644 +index 75100b20..0b212078 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf) - if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) - return 1; - +@@ -230,8 +230,6 @@ setup_default_blist (struct config * conf) + ORIGIN_DEFAULT)) + return 1; + } - if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT)) - return 1; -- + vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { - if (find_blacklist_device(conf->blist_device, -@@ -409,7 +406,8 @@ filter_property(const struct config *conf, struct udev_device *udev, +@@ -438,7 +436,8 @@ filter_property(const struct config *conf, struct udev_device *udev, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -42,11 +41,11 @@ index 8d15d2ea..eff690fd 100644 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev)) { -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index b4dccd1b..284282c6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1367,9 +1367,14 @@ keywords. Both are regular expressions. For a full description of these keywords +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 226d0019..bae4168f 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1402,9 +1402,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -62,7 +61,7 @@ index b4dccd1b..284282c6 100644 . .RS .PP -@@ -1380,10 +1385,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1415,10 +1420,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -74,10 +73,10 @@ index b4dccd1b..284282c6 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index 882aa3a1..6a22b660 100644 +index ba8dfd07..693db3fa 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -375,9 +375,8 @@ static void test_property_missing(void **state) +@@ -384,9 +384,8 @@ static void test_property_missing(void **state) { static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; conf.blist_property = blist_property_wwn; @@ -88,7 +87,7 @@ index 882aa3a1..6a22b660 100644 assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state) +@@ -478,9 +477,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0043-RH-don-t-start-without-a-config-file.patch similarity index 71% rename from 0003-RH-don-t-start-without-a-config-file.patch rename to 0043-RH-don-t-start-without-a-config-file.patch index e6e03b4..ef9415d 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0043-RH-don-t-start-without-a-config-file.patch @@ -14,17 +14,18 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 13 +++++++++++++ libmultipath/config.h | 1 + + multipath/main.c | 6 ++++++ multipath/multipath.rules.in | 1 + - multipathd/multipathd.8 | 2 ++ + multipathd/multipathd.8.in | 2 ++ multipathd/multipathd.service | 1 + multipathd/multipathd.socket | 1 + - 6 files changed, 19 insertions(+) + 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 5c5c0726..183b319d 100644 +index b7dbc6f5..3a374b3d 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -966,6 +966,19 @@ int _init_config (const char *file, struct config *conf) +@@ -958,6 +958,19 @@ int _init_config (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -45,7 +46,7 @@ index 5c5c0726..183b319d 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 87947469..0dc89c16 100644 +index 8c22ce75..92f3a0df 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -56,6 +57,35 @@ index 87947469..0dc89c16 100644 enum devtypes { DEV_NONE, +diff --git a/multipath/main.c b/multipath/main.c +index 9e1c5052..46944589 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -829,11 +829,14 @@ main (int argc, char *argv[]) + struct config *conf; + int retries = -1; + bool enable_foreign = false; ++ bool have_config; ++ struct stat buf; + + libmultipath_init(); + if (atexit(dm_lib_exit) || atexit(libmultipath_exit)) + condlog(1, "failed to register cleanup handler for libmultipath: %m"); + logsink = LOGSINK_STDERR_WITH_TIME; ++ have_config = (stat(DEFAULT_CONFIGFILE, &buf) == 0); + if (init_config(DEFAULT_CONFIGFILE)) + exit(RTVL_FAIL); + if (atexit(uninit_config)) +@@ -1081,6 +1084,9 @@ main (int argc, char *argv[]) + while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) + condlog(3, "restart multipath configuration process"); + ++ if (!have_config && r == RTVL_OK && ++ (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG)) ++ r = RTVL_FAIL; + out: + put_multipath_config(conf); + if (dev) diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in index 6f123760..70b69a06 100644 --- a/multipath/multipath.rules.in @@ -68,11 +98,11 @@ index 6f123760..70b69a06 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" -diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index bdf102eb..a16a0bd5 100644 ---- a/multipathd/multipathd.8 -+++ b/multipathd/multipathd.8 -@@ -48,6 +48,8 @@ map regains its maximum performance and redundancy. +diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in +index e98c27fd..fd2061e5 100644 +--- a/multipathd/multipathd.8.in ++++ b/multipathd/multipathd.8.in +@@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. With the \fB-k\fR option, \fBmultipathd\fR acts as a client utility that sends commands to a running instance of the multipathd daemon (see \fBCOMMANDS\fR below). diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0044-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0044-RH-Fix-nvme-function-missing-argument.patch diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0045-RH-use-rpm-optflags-if-present.patch similarity index 83% rename from 0005-RH-use-rpm-optflags-if-present.patch rename to 0045-RH-use-rpm-optflags-if-present.patch index 6a7fdea..1ad6b40 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0045-RH-use-rpm-optflags-if-present.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 540e1dfc..748911e2 100644 +index 62d3d5cc..72fd8d57 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -78,11 +78,23 @@ ORIG_LDFLAGS := $(LDFLAGS) +@@ -91,11 +91,23 @@ ORIG_LDFLAGS := $(LDFLAGS) SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) @@ -38,13 +38,13 @@ index 540e1dfc..748911e2 100644 +WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) --CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes -+CPPFLAGS := $(CPPFLAGS) \ ++CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" \ - -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -@@ -90,7 +102,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ + -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ +@@ -104,7 +116,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0006-RH-add-mpathconf.patch b/0046-RH-add-mpathconf.patch similarity index 98% rename from 0006-RH-add-mpathconf.patch rename to 0046-RH-add-mpathconf.patch index e279822..01bc8d2 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0046-RH-add-mpathconf.patch @@ -21,10 +21,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 183b319d..01f36a4f 100644 +index 3a374b3d..4544f484 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -968,6 +968,8 @@ int _init_config (const char *file, struct config *conf) +@@ -960,6 +960,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -34,10 +34,10 @@ index 183b319d..01f36a4f 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index b3c2cc81..413294ef 100644 +index f70e64ec..9942d1a9 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -22,6 +22,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +@@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so install: $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ @@ -45,7 +45,7 @@ index b3c2cc81..413294ef 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -31,6 +32,7 @@ install: +@@ -33,6 +34,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 @@ -53,7 +53,7 @@ index b3c2cc81..413294ef 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 ifneq ($(SCSI_DH_MODULES_PRELOAD),) -@@ -41,11 +43,13 @@ endif +@@ -43,11 +45,13 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) @@ -65,8 +65,8 @@ index b3c2cc81..413294ef 100644 $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/mpathconf.8 $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf - clean: dep_clean diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 index 00000000..319664b1 diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 87% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 714a1bb..7714825 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -15,12 +15,12 @@ multipathd.service Signed-off-by: Benjamin Marzinski --- multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- - multipath/multipath.8 | 7 ++++- + multipath/multipath.8.in | 7 ++++- multipathd/multipathd.service | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 90f940f1..3549740a 100644 +index 46944589..47f89a0a 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index 90f940f1..3549740a 100644 " -c check if a device should be a path in a multipath device\n" " -C check if a multipath device has usable paths\n" " -q allow queue_if_no_path when multipathd is not running\n" -@@ -447,6 +449,50 @@ static void cleanup_vecs(void) +@@ -448,6 +450,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,16 +92,16 @@ index 90f940f1..3549740a 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -842,7 +888,7 @@ main (int argc, char *argv[]) - conf->force_sync = 1; - if (atexit(cleanup_vecs)) +@@ -848,7 +894,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); + if (atexit(cleanup_bindings)) + condlog(1, "failed to register cleanup handler for bindings: %m"); - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -913,6 +959,10 @@ main (int argc, char *argv[]) +@@ -919,6 +965,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -112,11 +112,11 @@ index 90f940f1..3549740a 100644 case 'h': usage(argv[0]); exit(RTVL_OK); -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 88149d53..072a03ee 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. +diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in +index 348eb220..82a7e68e 100644 +--- a/multipath/multipath.8.in ++++ b/multipath/multipath.8.in +@@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig. .B multipath .RB [\| \-v\ \c .IR level \|] @@ -125,7 +125,7 @@ index 88149d53..072a03ee 100644 . .LP .B multipath -@@ -145,6 +145,11 @@ device mapper, path checkers ...). +@@ -146,6 +146,11 @@ device mapper, path checkers ...). Add the WWID for the specified device to the WWIDs file. . .TP diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0048-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 96% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0048-RH-reset-default-find_mutipaths-value-to-off.patch index ea12464..432b070 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0048-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index a5e9ea0c..514fd880 100644 +index d01f9712..ee2e13a9 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 95% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 06233ff..1f94eb3 100644 --- a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index b5c7873d..e139360c 100644 +index e9827dca..80a32aa3 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c @@ -24,6 +24,7 @@ @@ -68,7 +68,7 @@ index b5c7873d..e139360c 100644 static int get_ana_info(struct path * pp) { int rc; -@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, +@@ -209,8 +233,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) if (pp->fd < 0) rc = -ANA_ERR_NO_INFORMATION; diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 98% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 4e0b116..1906258 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 6865cd92..72825829 100644 +index 84ce5fe7..104fdd5a 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch index 26b0d06..407b621 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 748911e2..c07bcb0c 100644 +index 72fd8d57..a49e9f5a 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0052-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0012-RH-compile-with-libreadline-support.patch rename to 0052-RH-compile-with-libreadline-support.patch index df99295..c78d5c0 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0052-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index c07bcb0c..e59313c6 100644 +index a49e9f5a..51b55196 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0053-RH-Add-mpathcleanup.patch b/0053-RH-Add-mpathcleanup.patch new file mode 100644 index 0000000..9278829 --- /dev/null +++ b/0053-RH-Add-mpathcleanup.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 7 Jul 2023 15:25:59 -0500 +Subject: [PATCH] RH: Add mpathcleanup + +mpathcleanup is a program that will remove a multipath device as well as +all of the scsi path devices that make it up. + +Signed-off-by: Benjamin Marzinski +--- + multipath/Makefile | 2 + + multipath/mpathcleanup | 145 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 147 insertions(+) + create mode 100755 multipath/mpathcleanup + +diff --git a/multipath/Makefile b/multipath/Makefile +index 9942d1a9..d281b501 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -25,6 +25,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -m 755 mpathcleanup $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules +@@ -46,6 +47,7 @@ endif + uninstall: + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf ++ $(Q)$(RM) $(DESTDIR)$(bindir)/mpathcleanup + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +diff --git a/multipath/mpathcleanup b/multipath/mpathcleanup +new file mode 100755 +index 00000000..6fd921e4 +--- /dev/null ++++ b/multipath/mpathcleanup +@@ -0,0 +1,145 @@ ++#!/bin/bash ++# ++# Copyright (C) 2023 Red Hat, Inc. All rights reserved. ++# ++# This file is part of the device-mapper-multipath package. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++unset PROGRAM FLUSH DEVICE DEVNAME MAJOR MINOR PATHDEVS PATHDEV HAVE_MULTIPATHD QUEUEING ++ ++function usage ++{ ++ echo "usage: $PROGRAM [-h] [--flush] " ++ echo "" ++ echo "remove a multipath device and its scsi path devices" ++ echo "" ++ echo "options:" ++ echo " -h, --help show this help message and exit" ++ echo " --flush disable queuing on the multipath device and" ++ echo " flush the path devices before removing" ++} ++ ++function parse_args ++{ ++ while [ -n "$1" ]; do ++ case $1 in ++ --flush) ++ FLUSH=1 ++ shift ++ ;; ++ --help | -h) ++ usage ++ exit 1 ++ ;; ++ *) ++ if [ -n "$DEVICE" ]; then ++ usage ++ exit 1 ++ fi ++ DEVICE=$1 ++ shift ++ ;; ++ esac ++ done ++} ++ ++function validate_device ++{ ++ if [ -z "$DEVICE" ]; then ++ usage ++ exit 1 ++ fi ++ if [[ "$DEVICE" =~ ^[[:digit:]]+:[[:digit:]]+$ ]]; then ++ MAJOR=${DEVICE%%:*} ++ MINOR=${DEVICE##*:} ++ DEVNAME=`dmsetup ls --target multipath | grep "($MAJOR, $MINOR)$" | awk '{print $1}'` ++ else ++ DEVNAME=`dmsetup ls --target multipath | awk '{print $1}' | grep "^$DEVICE$"` ++ fi ++ if [ -z "$DEVNAME" ]; then ++ DEVNAME=`multipath -v 1 -l $DEVICE 2>/dev/null` ++ if [ -z "$DEVNAME" ]; then ++ echo "$DEVICE is not a multipath device" ++ exit 1 ++ fi ++ # verify that this is not a native nvme multipath device ++ dmsetup ls --target multipath | awk '{print $1}' | grep -q "^$DEVNAME$" ++ if test $? -eq 1; then ++ echo "$DEVICE is not a device-mapper multipath device" ++ exit 1 ++ fi ++ fi ++ if [ -z "$MINOR" ]; then ++ MINOR=`dmsetup info -c --noheadings -o minor $DEVNAME` ++ fi ++} ++ ++function get_paths ++{ ++ PATHDEVS=`ls /sys/block/dm-$MINOR/slaves` ++ for PATHDEV in $PATHDEVS; do ++ if [[ ! "$PATHDEV" =~ ^sd[a-z]+$ ]]; then ++ echo "$PATHDEV is not a scsi device. $PROGRAM only works with scsi devices" ++ exit 1 ++ fi ++ done ++} ++ ++function remove_devs ++{ ++ pidof multipathd > /dev/null ++ HAVE_MULTIPATHD=$? ++ multipath -v2 -l "$DEVNAME" | grep features | grep -q queue_if_no_path ++ QUEUEING=$? ++ if [ -n "$FLUSH" ] && [ "$QUEUEING" -eq 0 ]; then ++ if test $HAVE_MULTIPATHD -eq 0; then ++ multipathd disablequeueing map "$DEVNAME" > /dev/null ++ else ++ dmsetup message "$DEVNAME" 0 fail_if_no_path ++ fi ++ sleep 1 ++ fi ++ if test $HAVE_MULTIPATHD -eq 0; then ++ multipath -f "$DEVNAME" ++ else ++ multipathd -Df "$DEVNAME" ++ fi ++ if test $? -eq 1; then ++ echo "$DEVICE cannot be removed" ++ exit 1 ++ fi ++ for PATHDEV in $PATHDEVS; do ++ if [ -n "$FLUSH" ]; then ++ blockdev --flushbufs /dev/"$PATHDEV" ++ fi ++ echo 1 > /sys/block/"$PATHDEV"/device/delete ++ done ++} ++ ++function verify_removal ++{ ++ multipath -v 1 -d $DEVNAME | grep -q "^$DEVNAME$" ++ if test $? -eq 0; then ++ echo "$DEVICE removed but path devices still exist" ++ exit 1 ++ fi ++ multipath -v 1 -l $DEVNAME | grep -q "^$DEVNAME$" ++ if test $? -eq 0; then ++ echo "$DEVICE removal succeeded, but device still exists" ++ exit 1 ++ fi ++} ++ ++PROGRAM="$0" ++parse_args "$@" ++validate_device ++get_paths ++remove_devs ++verify_removal diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 268e4b9..30c0bbf 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,27 +1,68 @@ Name: device-mapper-multipath -Version: 0.9.5 -Release: 2%{?dist} +Version: 0.9.6 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.5.tar.gz -o multipath-tools-0.9.5.tgz -Source0: multipath-tools-0.9.5.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.6.tar.gz -o multipath-tools-0.9.6.tgz +Source0: multipath-tools-0.9.6.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0001: 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch +Patch0002: 0002-libmultipath-add-alias_already_taken.patch +Patch0003: 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch +Patch0004: 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch +Patch0005: 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch +Patch0006: 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch +Patch0007: 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch +Patch0008: 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch +Patch0009: 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch +Patch0010: 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch +Patch0011: 0011-libmultipath-add-global-variable-for-current-binding.patch +Patch0012: 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch +Patch0013: 0013-libmultipath-alias.c-move-bindings-related-code-up.patch +Patch0014: 0014-libmultipath-update_bindings_file-take-filename-argu.patch +Patch0015: 0015-libmultipath-update_bindings_file-use-a-single-write.patch +Patch0016: 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch +Patch0017: 0017-libmultipath-alias.c-factor-out-read_binding.patch +Patch0018: 0018-libmultipath-keep-bindings-in-memory.patch +Patch0019: 0019-multipath-tools-tests-fix-alias-tests.patch +Patch0020: 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch +Patch0021: 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch +Patch0022: 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch +Patch0023: 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch +Patch0024: 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch +Patch0025: 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch +Patch0026: 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch +Patch0027: 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch +Patch0028: 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch +Patch0029: 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch +Patch0030: 0030-multipath-tools-add-compile-time-configuration-for-e.patch +Patch0031: 0031-multipath-tools-man-pages-generate-with-correct-path.patch +Patch0032: 0032-libdmmp-Makefile-fix-bug-in-install-section.patch +Patch0033: 0033-multipath-tools-README.md-improve-documentation-for-.patch +Patch0034: 0034-libmultipath-print-built-in-values-for-deprecated-op.patch +Patch0035: 0035-multipath-add-a-missing-newline.patch +Patch0036: 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch +Patch0037: 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch +Patch0038: 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch +Patch0039: 0039-multipath-tools-fix-spelling.patch +Patch0040: 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch +Patch0041: 0041-RH-fixup-udev-rules-for-redhat.patch +Patch0042: 0042-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0043: 0043-RH-don-t-start-without-a-config-file.patch +Patch0044: 0044-RH-Fix-nvme-function-missing-argument.patch +Patch0045: 0045-RH-use-rpm-optflags-if-present.patch +Patch0046: 0046-RH-add-mpathconf.patch +Patch0047: 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0048: 0048-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0049: 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0050: 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0051: 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0052: 0052-RH-compile-with-libreadline-support.patch +Patch0053: 0053-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -108,7 +149,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.5 -p1 +%autosetup -n multipath-tools-0.9.6 -p1 cp %{SOURCE1} . %build @@ -158,6 +199,7 @@ fi %{_sbindir}/multipathd %{_sbindir}/multipathc %{_sbindir}/mpathconf +%{_sbindir}/mpathcleanup %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service %{_unitdir}/multipathd.socket @@ -230,6 +272,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Sep 22 2023 Benjamin Marzinski - 0.9.6-1 +- Update to the head of the upstream staging branch +- Rename redhat patches + * Previous patches 0001-0012 are now patches 0041-0052 +- Add 0053-RH-Add-mpathcleanup.patch + * add mpathcleanup program + * Wed Jul 19 2023 Fedora Release Engineering - 0.9.5-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild diff --git a/sources b/sources index ece6ffe..5d41f65 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.5.tgz) = 39c2e5d45542c6076eb3b17b9994629b4c1f74347aa43e0119001fa2d07d3a606fd5e617962906a11b313afb37a115bd8eec2ef24447e980e61b5900625f9146 +SHA512 (multipath-tools-0.9.6.tgz) = 17d2b46ead9df6826b3266035bc077a2f4d4bea01e2cd59e32d3917cda40c320f11bc8572da7ba66251e312b46d9be317737069193d481d202d49f9aa5fd71b9 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 748e0a08b6e2efb771d80e644047f0ad856e8b0d Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 21 Nov 2023 16:11:29 -0500 Subject: [PATCH 08/33] device-mapper-mulitpath-0.9.7-1 Update source to upstream version 0.9.7 * Previous patches 0001-0040 are included in the source tarball Rename redhat patches * Previous patches 0041-0053 are now patches 0001-0013 Remove /usr/lib/modules-load.d/multipath.conf * has been replaced with modprobe@dm_multipath.service unit Wants. --- .gitignore | 1 + ... 0001-RH-fixup-udev-rules-for-redhat.patch | 21 +- ...fs_set_scsi_tmo-do-nothing-for-ACT_D.patch | 51 - ...property-blacklist-exception-builtin.patch | 6 +- ...libmultipath-add-alias_already_taken.patch | 75 - ...RH-don-t-start-without-a-config-file.patch | 28 +- ...fy-use_existing_alias-and-get_user_f.patch | 207 -- ...H-Fix-nvme-function-missing-argument.patch | 0 ...er-allocate-an-alias-that-s-already-.patch | 101 - ... 0005-RH-use-rpm-optflags-if-present.patch | 10 +- ...kup_binding-add-comment-about-the-al.patch | 61 - ...hconf.patch => 0006-RH-add-mpathconf.patch | 8 +- ...test-simplify-debugging-for-condlog-.patch | 35 - ...om-kernel-cmdline-mpath.wwids-with-A.patch | 14 +- ...tests-add-tests-for-get_user_friendl.patch | 493 ----- ...-default-find_mutipaths-value-to-off.patch | 2 +- ...test-consistent-use-of-macros-in-ali.patch | 365 ---- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...tests-convert-mock_-failed-used-_ali.patch | 246 --- ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...test-use-mock_bindings_file-consiste.patch | 500 ----- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-global-variable-for-current-binding.patch | 109 -- ...-RH-compile-with-libreadline-support.patch | 2 +- ...ame-fix_bindings_file-to-update_bind.patch | 40 - ...up.patch => 0013-RH-Add-mpathcleanup.patch | 4 +- ...lias.c-move-bindings-related-code-up.patch | 285 --- ...ate_bindings_file-take-filename-argu.patch | 61 - ...ate_bindings_file-use-a-single-write.patch | 59 - ...ate_bindings_file-don-t-log-temp-fil.patch | 29 - ...path-alias.c-factor-out-read_binding.patch | 94 - ...libmultipath-keep-bindings-in-memory.patch | 545 ------ ...ultipath-tools-tests-fix-alias-tests.patch | 1698 ----------------- ...get_uuid-return-emtpy-UUID-for-non-e.patch | 53 - ...dapt-to-new-semantics-of-dm_get_uuid.patch | 158 -- ...th-sort-aliases-by-length-and-strcmp.patch | 98 - ...tests-fix-alias-test-after-sort-orde.patch | 90 - ...plify-get_free_id-assuming-total-ord.patch | 122 -- ...tests-adapt-alias-tests-for-total-or.patch | 203 -- ...tests-add-test-for-ordering-of-bindi.patch | 275 --- ...-bindings-file-with-inotify-timestam.patch | 597 ------ ...tests-mock-pthread_mutex_-lock-unloc.patch | 102 - ...Makefile-sanitize-paths-for-configur.patch | 73 - ...add-compile-time-configuration-for-e.patch | 58 - ...man-pages-generate-with-correct-path.patch | 366 ---- ...-Makefile-fix-bug-in-install-section.patch | 25 - ...README.md-improve-documentation-for-.patch | 75 - ...nt-built-in-values-for-deprecated-op.patch | 55 - 0035-multipath-add-a-missing-newline.patch | 25 - ...allow-prefixes-with-and-w-o-trailing.patch | 66 - ...recate-bindings_file-wwids_file-prke.patch | 897 --------- ...id-Warray-bounds-error-in-uatomic-op.patch | 158 -- 0039-multipath-tools-fix-spelling.patch | 52 - ...-support-to-handle-FPIN-Li-events-fo.patch | 300 --- device-mapper-multipath.spec | 83 +- sources | 2 +- 56 files changed, 77 insertions(+), 9014 deletions(-) rename 0041-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (81%) delete mode 100644 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch rename 0042-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) delete mode 100644 0002-libmultipath-add-alias_already_taken.patch rename 0043-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (87%) delete mode 100644 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch rename 0044-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch rename 0045-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (87%) delete mode 100644 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch rename 0046-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (99%) delete mode 100644 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch rename 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (93%) delete mode 100644 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch rename 0048-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (96%) delete mode 100644 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch rename 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch rename 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) delete mode 100644 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch rename 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) delete mode 100644 0011-libmultipath-add-global-variable-for-current-binding.patch rename 0052-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (96%) delete mode 100644 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch rename 0053-RH-Add-mpathcleanup.patch => 0013-RH-Add-mpathcleanup.patch (98%) delete mode 100644 0013-libmultipath-alias.c-move-bindings-related-code-up.patch delete mode 100644 0014-libmultipath-update_bindings_file-take-filename-argu.patch delete mode 100644 0015-libmultipath-update_bindings_file-use-a-single-write.patch delete mode 100644 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch delete mode 100644 0017-libmultipath-alias.c-factor-out-read_binding.patch delete mode 100644 0018-libmultipath-keep-bindings-in-memory.patch delete mode 100644 0019-multipath-tools-tests-fix-alias-tests.patch delete mode 100644 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch delete mode 100644 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch delete mode 100644 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch delete mode 100644 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch delete mode 100644 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch delete mode 100644 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch delete mode 100644 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch delete mode 100644 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch delete mode 100644 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch delete mode 100644 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch delete mode 100644 0030-multipath-tools-add-compile-time-configuration-for-e.patch delete mode 100644 0031-multipath-tools-man-pages-generate-with-correct-path.patch delete mode 100644 0032-libdmmp-Makefile-fix-bug-in-install-section.patch delete mode 100644 0033-multipath-tools-README.md-improve-documentation-for-.patch delete mode 100644 0034-libmultipath-print-built-in-values-for-deprecated-op.patch delete mode 100644 0035-multipath-add-a-missing-newline.patch delete mode 100644 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch delete mode 100644 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch delete mode 100644 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch delete mode 100644 0039-multipath-tools-fix-spelling.patch delete mode 100644 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch diff --git a/.gitignore b/.gitignore index 75c4abc..f698d08 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.4.tgz /multipath-tools-0.9.5.tgz /multipath-tools-0.9.6.tgz +/multipath-tools-0.9.7.tgz diff --git a/0041-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 81% rename from 0041-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch index e96c1e7..02efadd 100644 --- a/0041-RH-fixup-udev-rules-for-redhat.patch +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -9,27 +9,24 @@ different naming scheme for partitions than SuSE. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 4 ++-- + Makefile.inc | 2 +- kpartx/kpartx.rules | 2 +- multipath/Makefile | 4 ++-- - 3 files changed, 5 insertions(+), 5 deletions(-) + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 04bfa56e..62d3d5cc 100644 +index 6b454303..0b0e3ad2 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -34,9 +34,9 @@ endif +@@ -34,7 +34,7 @@ endif # Paths. All these can be overridden on the "make" command line. prefix := # Prefix for binaries -exec_prefix := $(prefix) +exec_prefix := $(prefix)/usr # Prefix for non-essential libraries (libdmmp) --usr_prefix := $(prefix) -+usr_prefix := $(prefix)/usr + usr_prefix := $(if $(prefix),$(prefix),/usr) # Prefix for configfuration files (multipath.conf) - etc_prefix := $(prefix) - # Where to install systemd-related files. systemd is usually installed under /usr diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules index 1969dee0..d2b28233 100644 --- a/kpartx/kpartx.rules @@ -43,7 +40,7 @@ index 1969dee0..d2b28233 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 68cb5ce7..f70e64ec 100644 +index 0efb9b26..504d6892 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -26,7 +26,7 @@ install: @@ -52,10 +49,10 @@ index 68cb5ce7..f70e64ec 100644 $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules - $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) - $(Q)$(INSTALL_PROGRAM) -m 644 modules-load.conf $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -@@ -46,7 +46,7 @@ uninstall: + $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +@@ -48,7 +48,7 @@ uninstall: $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf diff --git a/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch b/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch deleted file mode 100644 index 9b8a486..0000000 --- a/0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 16:21:43 +0200 -Subject: [PATCH] libmultipath: sysfs_set_scsi_tmo: do nothing for ACT_DRY_RUN - -"multipath -d" might change sysfs timeouts of SCSI devices. -Make sure it doesn't. - -Signed-off-by: Martin Wilck -Cc: Jehan Singh -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 4 ++-- - libmultipath/discovery.c | 3 +++ - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 9513baae..029fbbd2 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1193,13 +1193,13 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - - if (cmpp) - mpp->queue_mode = cmpp->queue_mode; -+ if (cmd == CMD_DRY_RUN && mpp->action == ACT_UNDEF) -+ mpp->action = ACT_DRY_RUN; - if (setup_map(mpp, ¶ms, vecs)) { - remove_map(mpp, vecs->pathvec, NULL); - continue; - } - -- if (cmd == CMD_DRY_RUN) -- mpp->action = ACT_DRY_RUN; - if (mpp->action == ACT_UNDEF) - select_action(mpp, curmp, - force_reload == FORCE_RELOAD_YES ? 1 : 0); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e4de48e7..84ce5fe7 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -857,6 +857,9 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) - bool warn_dev_loss = false; - bool warn_fast_io_fail = false; - -+ if (mpp->action == ACT_DRY_RUN || mpp->action == ACT_REJECT) -+ return 0; -+ - if (mpp->no_path_retry > 0) { - uint64_t no_path_retry_tmo = - (uint64_t)mpp->no_path_retry * conf->checkint; diff --git a/0042-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0042-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch index 61e8943..bc259d4 100644 --- a/0042-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -42,10 +42,10 @@ index 75100b20..0b212078 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 226d0019..bae4168f 100644 +index 683bdb72..87b3b2a5 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1402,9 +1402,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1431,9 +1431,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index 226d0019..bae4168f 100644 . .RS .PP -@@ -1415,10 +1420,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1444,10 +1449,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0002-libmultipath-add-alias_already_taken.patch b/0002-libmultipath-add-alias_already_taken.patch deleted file mode 100644 index 8ed3c7b..0000000 --- a/0002-libmultipath-add-alias_already_taken.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 21:36:11 +0200 -Subject: [PATCH] libmultipath: add alias_already_taken() - -Factor out a trivial helper function. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 32 +++++++++++++++++++------------- - 1 file changed, 19 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index c0139a2e..83ded886 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "util.h" -@@ -109,30 +110,35 @@ scan_devname(const char *alias, const char *prefix) - return n; - } - --static int --id_already_taken(int id, const char *prefix, const char *map_wwid) -+static bool alias_already_taken(const char *alias, const char *map_wwid) - { -- STRBUF_ON_STACK(buf); -- const char *alias; -- -- if (append_strbuf_str(&buf, prefix) < 0 || -- format_devname(&buf, id) < 0) -- return 0; - -- alias = get_strbuf_str(&buf); - if (dm_map_present(alias)) { - char wwid[WWID_SIZE]; - - /* If both the name and the wwid match, then it's fine.*/ - if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && - strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -- return 0; -- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias); -- return 1; -+ return false; -+ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", -+ map_wwid, alias); -+ return true; - } -- return 0; -+ return false; - } - -+static bool id_already_taken(int id, const char *prefix, const char *map_wwid) -+{ -+ STRBUF_ON_STACK(buf); -+ const char *alias; -+ -+ if (append_strbuf_str(&buf, prefix) < 0 || -+ format_devname(&buf, id) < 0) -+ return false; -+ -+ alias = get_strbuf_str(&buf); -+ return alias_already_taken(alias, map_wwid); -+} - - /* - * Returns: 0 if matching entry in WWIDs file found diff --git a/0043-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 87% rename from 0043-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index ef9415d..fa304dc 100644 --- a/0043-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -12,13 +12,13 @@ simple way to disable multipath. Simply removing or renaming Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 13 +++++++++++++ - libmultipath/config.h | 1 + - multipath/main.c | 6 ++++++ - multipath/multipath.rules.in | 1 + - multipathd/multipathd.8.in | 2 ++ - multipathd/multipathd.service | 1 + - multipathd/multipathd.socket | 1 + + libmultipath/config.c | 13 +++++++++++++ + libmultipath/config.h | 1 + + multipath/main.c | 6 ++++++ + multipath/multipath.rules.in | 1 + + multipathd/multipathd.8.in | 2 ++ + multipathd/multipathd.service.in | 1 + + multipathd/multipathd.socket | 1 + 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c @@ -46,7 +46,7 @@ index b7dbc6f5..3a374b3d 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 8c22ce75..92f3a0df 100644 +index 384193ab..158cebf0 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -111,12 +111,12 @@ index e98c27fd..fd2061e5 100644 . . .\" ---------------------------------------------------------------------------- -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 5a9cde12..311f49c7 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket - After=systemd-udevd-kernel.socket +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 6d03ff71..0965d6f9 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ + After=systemd-udevd-kernel.socket @MODPROBE_UNIT@ After=multipathd.socket systemd-remount-fs.service Before=initrd-cleanup.service +ConditionPathExists=/etc/multipath.conf diff --git a/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch b/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch deleted file mode 100644 index 5beb1fe..0000000 --- a/0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 22:00:58 +0200 -Subject: [PATCH] libmultipath: unify use_existing_alias() and - get_user_friendly_alias() - -These functions are only called from select_alias(). The logic -is more obvious when unified in a single function. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 82 ++++++++++++------------------------------ - libmultipath/alias.h | 9 ++--- - libmultipath/propsel.c | 19 +++++----- - 3 files changed, 34 insertions(+), 76 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 83ded886..68f5d848 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -329,13 +329,13 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) - return alias; - } - --char * --use_existing_alias (const char *wwid, const char *file, const char *alias_old, -- const char *prefix, int bindings_read_only) -+char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, -+ const char *prefix, bool bindings_read_only) - { - char *alias = NULL; - int id = 0; - int fd, can_write; -+ bool new_binding = false; - char buff[WWID_SIZE]; - FILE *f; - -@@ -349,6 +349,10 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - close(fd); - return NULL; - } -+ -+ if (!strlen(alias_old)) -+ goto new_alias; -+ - /* lookup the binding. if it exists, the wwid will be in buff - * either way, id contains the id for the alias - */ -@@ -358,14 +362,14 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - /* if buff is our wwid, it's already - * allocated correctly - */ -- if (strcmp(buff, wwid) == 0) -+ if (strcmp(buff, wwid) == 0) { - alias = strdup(alias_old); -- else { -- alias = NULL; -+ goto out; -+ } else { - condlog(0, "alias %s already bound to wwid %s, cannot reuse", - alias_old, buff); -+ goto new_alias; - } -- goto out; - } - - id = lookup_binding(f, wwid, &alias, NULL, 0); -@@ -377,8 +381,15 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - - /* allocate the existing alias in the bindings file */ - id = scan_devname(alias_old, prefix); -- if (id <= 0) -- goto out; -+ -+new_alias: -+ if (id <= 0) { -+ id = lookup_binding(f, wwid, &alias, prefix, 1); -+ if (id <= 0) -+ goto out; -+ else -+ new_binding = true; -+ } - - if (fflush(f) != 0) { - condlog(0, "cannot fflush bindings file stream : %s", -@@ -388,8 +399,9 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - - if (can_write && !bindings_read_only) { - alias = allocate_binding(fd, wwid, id, prefix); -- condlog(0, "Allocated existing binding [%s] for WWID [%s]", -- alias, wwid); -+ if (alias && !new_binding) -+ condlog(2, "Allocated existing binding [%s] for WWID [%s]", -+ alias, wwid); - } - - out: -@@ -399,54 +411,6 @@ out: - return alias; - } - --char * --get_user_friendly_alias(const char *wwid, const char *file, const char *prefix, -- int bindings_read_only) --{ -- char *alias; -- int fd, id; -- FILE *f; -- int can_write; -- -- if (!wwid || *wwid == '\0') { -- condlog(3, "Cannot find binding for empty WWID"); -- return NULL; -- } -- -- fd = open_file(file, &can_write, bindings_file_header); -- if (fd < 0) -- return NULL; -- -- f = fdopen(fd, "r"); -- if (!f) { -- condlog(0, "cannot fdopen on bindings file descriptor : %s", -- strerror(errno)); -- close(fd); -- return NULL; -- } -- -- id = lookup_binding(f, wwid, &alias, prefix, 1); -- if (id < 0) { -- fclose(f); -- return NULL; -- } -- -- pthread_cleanup_push(free, alias); -- -- if (fflush(f) != 0) { -- condlog(0, "cannot fflush bindings file stream : %s", -- strerror(errno)); -- free(alias); -- alias = NULL; -- } else if (can_write && !bindings_read_only && !alias) -- alias = allocate_binding(fd, wwid, id, prefix); -- -- fclose(f); -- -- pthread_cleanup_pop(0); -- return alias; --} -- - int - get_user_friendly_wwid(const char *alias, char *buff, const char *file) - { -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index dbc950c4..fa332233 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -2,13 +2,10 @@ - #define _ALIAS_H - - int valid_alias(const char *alias); --char *get_user_friendly_alias(const char *wwid, const char *file, -- const char *prefix, -- int bindings_readonly); - int get_user_friendly_wwid(const char *alias, char *buff, const char *file); --char *use_existing_alias (const char *wwid, const char *file, -- const char *alias_old, -- const char *prefix, int bindings_read_only); -+char *get_user_friendly_alias(const char *wwid, const char *file, -+ const char *alias_old, -+ const char *prefix, bool bindings_read_only); - - struct config; - int check_alias_settings(const struct config *); -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d6bce129..354e883f 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -401,19 +401,16 @@ int select_alias(struct config *conf, struct multipath * mp) - - select_alias_prefix(conf, mp); - -- if (strlen(mp->alias_old) > 0) { -- mp->alias = use_existing_alias(mp->wwid, conf->bindings_file, -- mp->alias_old, mp->alias_prefix, -- conf->bindings_read_only); -- memset (mp->alias_old, 0, WWID_SIZE); -- origin = "(setting: using existing alias)"; -- } -+ mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, -+ mp->alias_old, mp->alias_prefix, -+ conf->bindings_read_only); - -- if (mp->alias == NULL) { -- mp->alias = get_user_friendly_alias(mp->wwid, -- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); -+ if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) -+ origin = "(setting: using existing alias)"; -+ else if (mp->alias) - origin = "(setting: user_friendly_name)"; -- } -+ memset (mp->alias_old, 0, WWID_SIZE); -+ - out: - if (mp->alias == NULL) { - mp->alias = strdup(mp->wwid); diff --git a/0044-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0044-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch diff --git a/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch b/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch deleted file mode 100644 index 3d05b85..0000000 --- a/0004-libmultipath-never-allocate-an-alias-that-s-already-.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 22:23:29 +0200 -Subject: [PATCH] libmultipath: never allocate an alias that's already taken - -If the bindings file is changed in a way that multipathd can't handle -(e.g. by swapping the aliases of two maps), multipathd must not try -to re-use an alias that is already used by another map. Creating -or renaming a map with such an alias will fail. We already avoid -this for some cases, but not for all. Fix it. - -Signed-off-by: Martin Wilck -Cc: David Bond -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 31 +++++++++++++++++++++++-------- - tests/alias.c | 2 +- - 2 files changed, 24 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 68f5d848..3e3dfe98 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -120,7 +120,7 @@ static bool alias_already_taken(const char *alias, const char *map_wwid) - if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && - strncmp(map_wwid, wwid, sizeof(wwid)) == 0) - return false; -- condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", -+ condlog(3, "%s: alias '%s' already taken, reselecting alias", - map_wwid, alias); - return true; - } -@@ -359,12 +359,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al - rlookup_binding(f, buff, alias_old); - - if (strlen(buff) > 0) { -- /* if buff is our wwid, it's already -- * allocated correctly -- */ -+ /* If buff is our wwid, it's already allocated correctly. */ - if (strcmp(buff, wwid) == 0) { - alias = strdup(alias_old); - goto out; -+ - } else { - condlog(0, "alias %s already bound to wwid %s, cannot reuse", - alias_old, buff); -@@ -372,19 +371,35 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al - } - } - -- id = lookup_binding(f, wwid, &alias, NULL, 0); -+ /* -+ * Look for an existing alias in the bindings file. -+ * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. -+ */ -+ lookup_binding(f, wwid, &alias, NULL, 0); - if (alias) { -- condlog(3, "Use existing binding [%s] for WWID [%s]", -- alias, wwid); -+ if (alias_already_taken(alias, wwid)) { -+ free(alias); -+ alias = NULL; -+ } else -+ condlog(3, "Use existing binding [%s] for WWID [%s]", -+ alias, wwid); - goto out; - } - -- /* allocate the existing alias in the bindings file */ -+ /* alias_old is already taken by our WWID, update bindings file. */ - id = scan_devname(alias_old, prefix); - - new_alias: - if (id <= 0) { -+ /* -+ * no existing alias was provided, or allocating it -+ * failed. Try a new one. -+ */ - id = lookup_binding(f, wwid, &alias, prefix, 1); -+ if (id == 0 && alias_already_taken(alias, wwid)) { -+ free(alias); -+ alias = NULL; -+ } - if (id <= 0) - goto out; - else -diff --git a/tests/alias.c b/tests/alias.c -index 3ca6c28b..11f209e0 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -398,7 +398,7 @@ static void mock_self_alias(const char *alias, const char *wwid) - will_return(__wrap_dm_get_uuid, wwid); - } - --#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, but not in bindings file. reselecting alias\n" -+#define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" - - static void mock_failed_alias(const char *alias, char *msg) - { diff --git a/0045-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 87% rename from 0045-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch index 1ad6b40..6352c23 100644 --- a/0045-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -13,12 +13,12 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 62d3d5cc..72fd8d57 100644 +index 0b0e3ad2..3d80d224 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -91,11 +91,23 @@ ORIG_LDFLAGS := $(LDFLAGS) - SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD)) - SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon)) +@@ -95,11 +95,23 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo + MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ + echo "modprobe@dm_multipath.service") -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ @@ -44,7 +44,7 @@ index 62d3d5cc..72fd8d57 100644 -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -@@ -104,7 +116,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe +@@ -108,7 +120,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch b/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch deleted file mode 100644 index 71d077a..0000000 --- a/0005-libmultipath-lookup_binding-add-comment-about-the-al.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 22:30:16 +0200 -Subject: [PATCH] libmultipath: lookup_binding: add comment about the algorithm - -When I read this code, I always get confused. Adding comments to -explain the algorithm. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 35 +++++++++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 3e3dfe98..9e9ac563 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -172,6 +172,41 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - alias = strtok_r(buf, " \t", &saveptr); - if (!alias) /* blank line */ - continue; -+ -+ /* -+ * Find an unused index - explanation of the algorithm -+ * -+ * ID: 1 = mpatha, 2 = mpathb, ... -+ * -+ * We assume the bindings are unsorted. The only constraint -+ * is that no ID occurs more than once. IDs that occur in the -+ * bindings are called "used". -+ * -+ * We call the list 1,2,3,..., exactly in this order, the list -+ * of "expected" IDs. The variable "id" always holds the next -+ * "expected" ID, IOW the last "expected" ID encountered plus 1. -+ * Thus all IDs below "id" are known to be used. However, at the -+ * end of the loop, the value of "id" isn't necessarily unused. -+ * -+ * "smallest_bigger_id" is the smallest used ID that was -+ * encountered while it was larger than the next "expected" ID -+ * at that iteration. Let X be some used ID. If all IDs below X -+ * are used and encountered in the right sequence before X, "id" -+ * will be > X when the loop ends. Otherwise, X was encountered -+ * "out of order", the condition (X > id) holds when X is -+ * encountered, and "smallest_bigger_id" will be set to X; i.e. -+ * it will be less or equal than X when the loop ends. -+ * -+ * At the end of the loop, (id < smallest_bigger_id) means that -+ * the value of "id" had been encountered neither in order nor -+ * out of order, and is thus unused. (id >= smallest_bigger_id) -+ * means that "id"'s value is in use. In this case, we play safe -+ * and use "biggest_id + 1" as the next value to try. -+ * -+ * biggest_id is always > smallest_bigger_id, except in the -+ * "perfectly ordered" case. -+ */ -+ - curr_id = scan_devname(alias, prefix); - if (curr_id == id) { - if (id < INT_MAX) diff --git a/0046-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 99% rename from 0046-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch index 01bc8d2..7782f65 100644 --- a/0046-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -34,7 +34,7 @@ index 3a374b3d..4544f484 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index f70e64ec..9942d1a9 100644 +index 504d6892..9f14036c 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so @@ -45,15 +45,15 @@ index f70e64ec..9942d1a9 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -33,6 +34,7 @@ install: +@@ -31,6 +32,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 - ifneq ($(SCSI_DH_MODULES_PRELOAD),) -@@ -43,11 +45,13 @@ endif + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) +@@ -45,11 +47,13 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) diff --git a/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch b/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch deleted file mode 100644 index a206358..0000000 --- a/0006-multipath-tools-test-simplify-debugging-for-condlog-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Aug 2023 22:56:41 +0200 -Subject: [PATCH] multipath-tools test: simplify debugging for condlog mismatch - -If there's a mismatch between expected and actual log message, -print both messages. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/test-log.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/tests/test-log.c b/tests/test-log.c -index c1745872..63516999 100644 ---- a/tests/test-log.c -+++ b/tests/test-log.c -@@ -16,12 +16,14 @@ void __wrap_dlog (int prio, const char * fmt, ...) - va_list ap; - char *expected; - -- check_expected(prio); - va_start(ap, fmt); - vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); - va_end(ap); - fprintf(stderr, "%s(%d): %s", __func__, prio, buff); - expected = mock_ptr_type(char *); -+ if (memcmp(expected, buff, strlen(expected))) -+ fprintf(stderr, "%s(expected): %s", __func__, expected); -+ check_expected(prio); - assert_memory_equal(buff, expected, strlen(expected)); - } - diff --git a/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 93% rename from 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 7714825..a3c4e9d 100644 --- a/0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -14,9 +14,9 @@ multipathd.service Signed-off-by: Benjamin Marzinski --- - multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- - multipath/multipath.8.in | 7 ++++- - multipathd/multipathd.service | 1 + + multipath/main.c | 54 ++++++++++++++++++++++++++++++-- + multipath/multipath.8.in | 7 ++++- + multipathd/multipathd.service.in | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c @@ -137,10 +137,10 @@ index 348eb220..82a7e68e 100644 .B \-w Remove the WWID for the specified device from the WWIDs file. . -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 311f49c7..5324f4bc 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 0965d6f9..c964eb1b 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in @@ -17,6 +17,7 @@ ConditionVirtualization=!container [Service] Type=notify diff --git a/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch b/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch deleted file mode 100644 index f829db4..0000000 --- a/0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch +++ /dev/null @@ -1,493 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 23 Aug 2023 22:57:29 +0200 -Subject: [PATCH] multipath-tools tests: add tests for - get_user_friendly_alias() - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 441 insertions(+) - -diff --git a/tests/alias.c b/tests/alias.c -index 11f209e0..7e443b06 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -81,6 +81,35 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - return ret; - } - -+#define TEST_FDNO 1234 -+#define TEST_FPTR ((FILE *) 0xaffe) -+ -+int __wrap_open_file(const char *file, int *can_write, const char *header) -+{ -+ int cw = mock_type(int); -+ -+ *can_write = cw; -+ return TEST_FDNO; -+} -+ -+FILE *__wrap_fdopen(int fd, const char *mode) -+{ -+ assert_int_equal(fd, TEST_FDNO); -+ return TEST_FPTR; -+} -+ -+int __wrap_fflush(FILE *f) -+{ -+ assert_ptr_equal(f, TEST_FPTR); -+ return 0; -+} -+ -+int __wrap_fclose(FILE *f) -+{ -+ assert_ptr_equal(f, TEST_FPTR); -+ return 0; -+} -+ - /* strbuf wrapper for the old format_devname() */ - static int __format_devname(char *name, int id, size_t len, const char *prefix) - { -@@ -399,6 +428,22 @@ static void mock_self_alias(const char *alias, const char *wwid) - } - - #define USED_STR(alias_str, wwid_str) wwid_str ": alias '" alias_str "' already taken, reselecting alias\n" -+#define NOMATCH_STR(alias_str) ("No matching alias [" alias_str "] in bindings file.\n") -+#define FOUND_STR(alias_str, wwid_str) \ -+ "Found matching wwid [" wwid_str "] in bindings file." \ -+ " Setting alias to " alias_str "\n" -+#define FOUND_ALIAS_STR(alias_str, wwid_str) \ -+ "Found matching alias [" alias_str "] in bindings file." \ -+ " Setting wwid to " wwid_str "\n" -+#define NOMATCH_WWID_STR(wwid_str) ("No matching wwid [" wwid_str "] in bindings file.\n") -+#define NEW_STR(alias_str, wwid_str) ("Created new binding [" alias_str "] for WWID [" wwid_str "]\n") -+#define EXISTING_STR(alias_str, wwid_str) ("Use existing binding [" alias_str "] for WWID [" wwid_str "]\n") -+#define ALLOC_STR(alias_str, wwid_str) ("Allocated existing binding [" alias_str "] for WWID [" wwid_str "]\n") -+#define BINDING_STR(alias_str, wwid_str) (alias_str " " wwid_str "\n") -+#define BOUND_STR(alias_str, wwid_str) ("alias "alias_str " already bound to wwid " wwid_str ", cannot reuse") -+#define ERR_STR(alias_str, wwid_str) ("ERROR: old alias [" alias_str "] for wwid [" wwid_str "] is used by other map\n") -+#define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") -+#define NOMORE_STR "no more available user_friendly_names\n" - - static void mock_failed_alias(const char *alias, char *msg) - { -@@ -421,6 +466,24 @@ static void mock_used_alias(const char *alias, char *msg) - expect_condlog(3, msg); - } - -+static void mock_bindings_file(const char *content, int match_line) -+{ -+ static char cnt[1024]; -+ char *token; -+ int i; -+ -+ assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); -+ -+ for (token = strtok(cnt, "\n"), i = 0; -+ token && *token; -+ token = strtok(NULL, "\n"), i++) { -+ will_return(__wrap_fgets, token); -+ if (match_line == i) -+ return; -+ } -+ will_return(__wrap_fgets, NULL); -+} -+ - static void lb_empty(void **state) - { - int rc; -@@ -1147,6 +1210,382 @@ static int test_allocate_binding(void) - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+#define mock_allocate_binding(alias, wwid) \ -+ do { \ -+ static const char ln[] = BINDING_STR(alias, wwid); \ -+ \ -+ will_return(__wrap_lseek, 0); \ -+ expect_value(__wrap_write, count, strlen(ln)); \ -+ expect_string(__wrap_write, buf, ln); \ -+ will_return(__wrap_write, strlen(ln)); \ -+ expect_condlog(3, NEW_STR(alias, wwid)); \ -+ } while (0) -+ -+static void gufa_empty_new_rw(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHa", "WWID0"); -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_empty_new_ro_1(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, false); -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_empty_new_ro_2(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, NULL); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_match_a_unused(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_unused_alias("MPATHa"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_match_a_self(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_self_alias("MPATHa", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_match_a_used(void **state) { -+ char *alias; -+ -+ will_return(__wrap_open_file, true); -+ -+ will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_nomatch_a_c(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHc WWID2", -+ -1); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); -+ -+ mock_allocate_binding("MPATHb", "WWID1"); -+ -+ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHb"); -+ free(alias); -+} -+ -+static void gufa_nomatch_c_a(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHc WWID2\n" -+ "MPATHa WWID0", -+ -1); -+ mock_unused_alias("MPATHb"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); -+ -+ mock_allocate_binding("MPATHb", "WWID1"); -+ -+ alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHb"); -+ free(alias); -+} -+ -+static void gufa_nomatch_c_b(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHc WWID2\n" -+ "MPATHb WWID1\n", -+ -1); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHa", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_nomatch_c_b_used(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHc WWID2\n" -+ "MPATHb WWID1", -+ -1); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID4")); -+ mock_unused_alias("MPATHd"); -+ -+ mock_allocate_binding("MPATHd", "WWID4"); -+ -+ alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHd"); -+ free(alias); -+} -+ -+static void gufa_nomatch_b_f_a(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHf WWID6\n" -+ "MPATHa WWID0\n", -+ -1); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); -+ mock_unused_alias("MPATHg"); -+ -+ mock_allocate_binding("MPATHg", "WWID7"); -+ -+ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHg"); -+ free(alias); -+} -+ -+static void gufa_old_empty(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ /* rlookup_binding for ALIAS */ -+ will_return(__wrap_fgets, NULL); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ /* lookup_binding */ -+ will_return(__wrap_fgets, NULL); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHz", "WWID0"); -+ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHz"); -+ free(alias); -+} -+ -+static void gufa_old_match(void **state) { -+ char *alias; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHz WWID0", -+ 1); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHz"); -+ free(alias); -+} -+ -+static void gufa_old_match_other(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHz WWID9"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHa"); -+ -+ mock_allocate_binding("MPATHa", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_old_match_other_used(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHz WWID9"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, -1); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHb"); -+ -+ mock_allocate_binding("MPATHb", "WWID0"); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHb"); -+ free(alias); -+} -+ -+static void gufa_old_match_other_wwidmatch(void **state) { -+ char *alias; -+ static const char bindings[] = ("MPATHz WWID9\n" -+ "MPATHc WWID2"); -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, 1); -+ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); -+ mock_unused_alias("MPATHc"); -+ -+ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHc"); -+ free(alias); -+} -+ -+static void gufa_old_match_other_wwidmatch_used(void **state) { -+ char *alias; -+ static const char bindings[] = ("MPATHz WWID9\n" -+ "MPATHc WWID2"); -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); -+ expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -+ -+ mock_bindings_file(bindings, 1); -+ expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); -+ mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ -+ alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_old_nomatch_wwidmatch(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHa WWID0"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_unused_alias("MPATHa"); -+ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHa"); -+ free(alias); -+} -+ -+static void gufa_old_nomatch_wwidmatch_used(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHa WWID0"; -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ mock_bindings_file(bindings, 0); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void gufa_old_nomatch_nowwidmatch(void **state) { -+ char *alias; -+ static const char bindings[] = "MPATHb WWID1"; -+ -+ will_return(__wrap_open_file, true); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_STR("MPATHz")); -+ -+ mock_bindings_file(bindings, -1); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ -+ mock_allocate_binding("MPATHz", "WWID0"); -+ expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); -+ -+ alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ assert_string_equal(alias, "MPATHz"); -+ free(alias); -+} -+ -+static int test_get_user_friendly_alias() -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(gufa_empty_new_rw), -+ cmocka_unit_test(gufa_empty_new_ro_1), -+ cmocka_unit_test(gufa_empty_new_ro_2), -+ cmocka_unit_test(gufa_match_a_unused), -+ cmocka_unit_test(gufa_match_a_self), -+ cmocka_unit_test(gufa_match_a_used), -+ cmocka_unit_test(gufa_nomatch_a_c), -+ cmocka_unit_test(gufa_nomatch_c_a), -+ cmocka_unit_test(gufa_nomatch_c_b), -+ cmocka_unit_test(gufa_nomatch_c_b_used), -+ cmocka_unit_test(gufa_nomatch_b_f_a), -+ cmocka_unit_test(gufa_old_empty), -+ cmocka_unit_test(gufa_old_match), -+ cmocka_unit_test(gufa_old_match_other), -+ cmocka_unit_test(gufa_old_match_other_used), -+ cmocka_unit_test(gufa_old_match_other_wwidmatch), -+ cmocka_unit_test(gufa_old_match_other_wwidmatch_used), -+ cmocka_unit_test(gufa_old_nomatch_wwidmatch), -+ cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), -+ cmocka_unit_test(gufa_old_nomatch_nowwidmatch), -+ }; -+ -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ - int main(void) - { - int ret = 0; -@@ -1157,6 +1596,8 @@ int main(void) - ret += test_lookup_binding(); - ret += test_rlookup_binding(); - ret += test_allocate_binding(); -+ ret += test_allocate_binding(); -+ ret += test_get_user_friendly_alias(); - - return ret; - } diff --git a/0048-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 96% rename from 0048-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch index 432b070..4e1253c 100644 --- a/0048-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index d01f9712..ee2e13a9 100644 +index 64b633f2..5bda9f93 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ diff --git a/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch b/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch deleted file mode 100644 index 430ceaf..0000000 --- a/0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch +++ /dev/null @@ -1,365 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 10:40:32 +0200 -Subject: [PATCH] multipath-tools test: consistent use of macros in alias test - -Use the macros introduced with the tests for get_user_friendly_alias() -also in the previously existing tests. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 80 ++++++++++++++++++++++++--------------------------- - 1 file changed, 38 insertions(+), 42 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index 7e443b06..427b2814 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -490,7 +490,7 @@ static void lb_empty(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); -@@ -503,7 +503,7 @@ static void lb_empty_unused(void **state) - - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHa"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); -@@ -518,7 +518,7 @@ static void lb_empty_failed(void **state) - will_return(__wrap_fgets, NULL); - mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -533,7 +533,7 @@ static void lb_empty_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -548,7 +548,7 @@ static void lb_empty_1_used_self(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); - mock_self_alias("MPATHb", "WWID0"); -- expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -561,8 +561,7 @@ static void lb_match_a(void **state) - char *alias; - - will_return(__wrap_fgets, "MPATHa WWID0\n"); -- expect_condlog(3, "Found matching wwid [WWID0] in bindings file." -- " Setting alias to MPATHa\n"); -+ expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); -@@ -577,7 +576,7 @@ static void lb_nomatch_a(void **state) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -590,7 +589,7 @@ static void lb_nomatch_a_bad_check(void **state) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -604,7 +603,7 @@ static void lb_nomatch_a_unused(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -622,7 +621,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); - mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); - mock_self_alias("MPATHf", "WWID1"); -- expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); -@@ -635,8 +634,7 @@ static void do_lb_match_c(void **state, int check_if_taken) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHc WWID1\n"); -- expect_condlog(3, "Found matching wwid [WWID1] in bindings file." -- " Setting alias to MPATHc\n"); -+ expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); -@@ -662,7 +660,7 @@ static void lb_nomatch_a_c(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHc WWID1\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -677,7 +675,7 @@ static void lb_nomatch_a_d_unused(void **state) - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -693,7 +691,7 @@ static void lb_nomatch_a_d_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); - mock_unused_alias("MPATHc"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -710,7 +708,7 @@ static void lb_nomatch_a_d_2_used(void **state) - mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); - mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); - mock_unused_alias("MPATHe"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -728,7 +726,7 @@ static void lb_nomatch_a_d_3_used(void **state) - mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); - mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); - mock_unused_alias("MPATHf"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); -@@ -742,7 +740,7 @@ static void lb_nomatch_c_a(void **state) - will_return(__wrap_fgets, "MPATHc WWID1\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -758,7 +756,7 @@ static void lb_nomatch_d_a_unused(void **state) - will_return(__wrap_fgets, "MPATHd WWID0\n"); - will_return(__wrap_fgets, NULL); - mock_unused_alias("MPATHb"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -775,7 +773,7 @@ static void lb_nomatch_d_a_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); - mock_unused_alias("MPATHe"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -790,7 +788,7 @@ static void lb_nomatch_a_b(void **state) - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -806,7 +804,7 @@ static void lb_nomatch_a_b_bad(void **state) - will_return(__wrap_fgets, "MPATHb\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -823,7 +821,7 @@ static void lb_nomatch_a_b_bad_self(void **state) - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - mock_self_alias("MPATHc", "WWID2"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -838,7 +836,7 @@ static void lb_nomatch_b_a(void **state) - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 27); - assert_ptr_equal(alias, NULL); -@@ -857,7 +855,7 @@ static void lb_nomatch_b_a_3_used(void **state) - mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); - mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); - mock_unused_alias("MPATHad"); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 30); - assert_ptr_equal(alias, NULL); -@@ -873,7 +871,7 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -898,7 +896,7 @@ static void lb_nomatch_int_max_used(void **state) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -913,7 +911,7 @@ static void lb_nomatch_int_max_m1(void **state) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); -@@ -929,7 +927,7 @@ static void lb_nomatch_int_max_m1_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -945,7 +943,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -- expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); -@@ -961,7 +959,7 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - will_return(__wrap_fgets, NULL); - mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -- expect_condlog(0, "no more available user_friendly_names\n"); -+ expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -1017,7 +1015,7 @@ static void rl_empty(void **state) - - buf[0] = '\0'; - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1030,8 +1028,7 @@ static void rl_match_a(void **state) - - buf[0] = '\0'; - will_return(__wrap_fgets, "MPATHa WWID0\n"); -- expect_condlog(3, "Found matching alias [MPATHa] in bindings file. " -- "Setting wwid to WWID0\n"); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, 0); - assert_string_equal(buf, "WWID0"); -@@ -1045,7 +1042,7 @@ static void rl_nomatch_a(void **state) - buf[0] = '\0'; - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- expect_condlog(3, "No matching alias [MPATHb] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHb")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1060,7 +1057,7 @@ static void rl_malformed_a(void **state) - will_return(__wrap_fgets, "MPATHa \n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); -- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1080,7 +1077,7 @@ static void rl_overlong_a(void **state) - will_return(__wrap_fgets, line); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); -- expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); -+ expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); - assert_string_equal(buf, ""); -@@ -1095,8 +1092,7 @@ static void rl_match_b(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHb WWID2\n"); -- expect_condlog(3, "Found matching alias [MPATHb] in bindings file. " -- "Setting wwid to WWID2\n"); -+ expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, 0); - assert_string_equal(buf, "WWID2"); -@@ -1125,7 +1121,7 @@ static void al_a(void **state) - expect_value(__wrap_write, count, strlen(ln)); - expect_string(__wrap_write, buf, ln); - will_return(__wrap_write, strlen(ln)); -- expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); -+ expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); - - alias = allocate_binding(0, "WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); -@@ -1142,7 +1138,7 @@ static void al_zz(void **state) - expect_value(__wrap_write, count, strlen(ln)); - expect_string(__wrap_write, buf, ln); - will_return(__wrap_write, strlen(ln)); -- expect_condlog(3, "Created new binding [MPATHzz] for WWID [WWIDzz]\n"); -+ expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); - - alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); - assert_ptr_not_equal(alias, NULL); diff --git a/0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch b/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch deleted file mode 100644 index 9d71adf..0000000 --- a/0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 10:49:32 +0200 -Subject: [PATCH] multipath-tools tests: convert mock_{failed,used}_alias to - macros - -This way we can further improve readability of the individual test -cases. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 92 +++++++++++++++++++++++++-------------------------- - 1 file changed, 46 insertions(+), 46 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index 427b2814..a32b43e8 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -445,26 +445,26 @@ static void mock_self_alias(const char *alias, const char *wwid) - #define REUSE_STR(alias_str, wwid_str) ("alias " alias_str " already bound to wwid " wwid_str ", cannot reuse\n") - #define NOMORE_STR "no more available user_friendly_names\n" - --static void mock_failed_alias(const char *alias, char *msg) --{ -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 1); -- expect_string(__wrap_dm_get_uuid, name, alias); -- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -- will_return(__wrap_dm_get_uuid, 1); -- expect_condlog(3, msg); --} -+#define mock_failed_alias(alias, wwid) \ -+ do { \ -+ expect_string(__wrap_dm_map_present, str, alias); \ -+ will_return(__wrap_dm_map_present, 1); \ -+ expect_string(__wrap_dm_get_uuid, name, alias); \ -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ -+ will_return(__wrap_dm_get_uuid, 1); \ -+ expect_condlog(3, USED_STR(alias, wwid)); \ -+ } while (0) - --static void mock_used_alias(const char *alias, char *msg) --{ -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 1); -- expect_string(__wrap_dm_get_uuid, name, alias); -- expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -- will_return(__wrap_dm_get_uuid, 0); -- will_return(__wrap_dm_get_uuid, "WWID_USED"); -- expect_condlog(3, msg); --} -+#define mock_used_alias(alias, wwid) \ -+ do { \ -+ expect_string(__wrap_dm_map_present, str, alias); \ -+ will_return(__wrap_dm_map_present, 1); \ -+ expect_string(__wrap_dm_get_uuid, name, alias); \ -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ -+ will_return(__wrap_dm_get_uuid, 0); \ -+ will_return(__wrap_dm_get_uuid, "WWID_USED"); \ -+ expect_condlog(3, USED_STR(alias, wwid)); \ -+ } while(0) - - static void mock_bindings_file(const char *content, int match_line) - { -@@ -516,7 +516,7 @@ static void lb_empty_failed(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- mock_failed_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_failed_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -531,7 +531,7 @@ static void lb_empty_1_used(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -546,7 +546,7 @@ static void lb_empty_1_used_self(void **state) - char *alias; - - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - mock_self_alias("MPATHb", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -616,10 +616,10 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID1")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID1")); -- mock_used_alias("MPATHd", USED_STR("MPATHd", "WWID1")); -- mock_failed_alias("MPATHe", USED_STR("MPATHe", "WWID1")); -+ mock_used_alias("MPATHb", "WWID1"); -+ mock_used_alias("MPATHc", "WWID1"); -+ mock_used_alias("MPATHd", "WWID1"); -+ mock_failed_alias("MPATHe", "WWID1"); - mock_self_alias("MPATHf", "WWID1"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -@@ -689,7 +689,7 @@ static void lb_nomatch_a_d_1_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHc"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -705,8 +705,8 @@ static void lb_nomatch_a_d_2_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); -+ mock_used_alias("MPATHc", "WWID2"); - mock_unused_alias("MPATHe"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -722,9 +722,9 @@ static void lb_nomatch_a_d_3_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID1\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -- mock_used_alias("MPATHe", USED_STR("MPATHe", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); -+ mock_used_alias("MPATHc", "WWID2"); -+ mock_used_alias("MPATHe", "WWID2"); - mock_unused_alias("MPATHf"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -771,7 +771,7 @@ static void lb_nomatch_d_a_1_used(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, "MPATHd WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHb", USED_STR("MPATHb", "WWID2")); -+ mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHe"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -851,9 +851,9 @@ static void lb_nomatch_b_a_3_used(void **state) - will_return(__wrap_fgets, "MPATHz WWID26\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHaa", USED_STR("MPATHaa", "WWID2")); -- mock_used_alias("MPATHab", USED_STR("MPATHab", "WWID2")); -- mock_used_alias("MPATHac", USED_STR("MPATHac", "WWID2")); -+ mock_used_alias("MPATHaa", "WWID2"); -+ mock_used_alias("MPATHab", "WWID2"); -+ mock_used_alias("MPATHac", "WWID2"); - mock_unused_alias("MPATHad"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -895,7 +895,7 @@ static void lb_nomatch_int_max_used(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -+ mock_used_alias("MPATHa", "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); -@@ -926,7 +926,7 @@ static void lb_nomatch_int_max_m1_used(void **state) - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); -@@ -941,7 +941,7 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -+ mock_used_alias("MPATHa", "WWID2"); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -957,8 +957,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); - will_return(__wrap_fgets, NULL); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID2")); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, USED_STR("MPATH" MPATH_ID_INT_MAX, "WWID2")); -+ mock_used_alias("MPATHa", "WWID2"); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, -1); -@@ -1291,7 +1291,7 @@ static void gufa_match_a_used(void **state) { - - will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_ptr_equal(alias, NULL); -@@ -1355,7 +1355,7 @@ static void gufa_nomatch_c_b_used(void **state) { - mock_bindings_file("MPATHc WWID2\n" - "MPATHb WWID1", - -1); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID4")); -+ mock_used_alias("MPATHa", "WWID4"); - expect_condlog(3, NOMATCH_WWID_STR("WWID4")); - mock_unused_alias("MPATHd"); - -@@ -1450,7 +1450,7 @@ static void gufa_old_match_other_used(void **state) { - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); - - mock_bindings_file(bindings, -1); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_unused_alias("MPATHb"); - -@@ -1493,7 +1493,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { - - mock_bindings_file(bindings, 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); -- mock_used_alias("MPATHc", USED_STR("MPATHc", "WWID2")); -+ mock_used_alias("MPATHc", "WWID2"); - - alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); -@@ -1528,7 +1528,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { - - mock_bindings_file(bindings, 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -- mock_used_alias("MPATHa", USED_STR("MPATHa", "WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); diff --git a/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 1906258..aa49d69 100644 --- a/0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 84ce5fe7..104fdd5a 100644 +index 6fd4dabb..19692b1e 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1177,13 +1177,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1216,13 +1216,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 84ce5fe7..104fdd5a 100644 good_len = 8; break; default: -@@ -1201,10 +1197,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1240,10 +1236,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch b/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch deleted file mode 100644 index 2105f5a..0000000 --- a/0010-multipath-tools-test-use-mock_bindings_file-consiste.patch +++ /dev/null @@ -1,500 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 11:13:44 +0200 -Subject: [PATCH] multipath-tools test: use mock_bindings_file() consistently - -Further improve test readablity. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 178 +++++++++++++++++++++----------------------------- - 1 file changed, 76 insertions(+), 102 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index a32b43e8..f334f928 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -489,7 +489,7 @@ static void lb_empty(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); -@@ -501,7 +501,7 @@ static void lb_empty_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -515,7 +515,7 @@ static void lb_empty_failed(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_failed_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -@@ -530,7 +530,7 @@ static void lb_empty_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -@@ -545,7 +545,7 @@ static void lb_empty_1_used_self(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_used_alias("MPATHa", "WWID0"); - mock_self_alias("MPATHb", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -@@ -560,7 +560,7 @@ static void lb_match_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ mock_bindings_file("MPATHa WWID0\n", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); - assert_int_equal(rc, 0); -@@ -574,8 +574,7 @@ static void lb_nomatch_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 2); -@@ -587,8 +586,7 @@ static void lb_nomatch_a_bad_check(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); - assert_int_equal(rc, -1); -@@ -600,8 +598,7 @@ static void lb_nomatch_a_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -@@ -614,8 +611,7 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - mock_used_alias("MPATHb", "WWID1"); - mock_used_alias("MPATHc", "WWID1"); - mock_used_alias("MPATHd", "WWID1"); -@@ -632,8 +628,8 @@ static void do_lb_match_c(void **state, int check_if_taken) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHc WWID1", 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, 0); -@@ -657,9 +653,8 @@ static void lb_nomatch_a_c(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHc WWID1", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); -@@ -671,9 +666,8 @@ static void lb_nomatch_a_d_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -686,9 +680,8 @@ static void lb_nomatch_a_d_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHc"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -702,9 +695,8 @@ static void lb_nomatch_a_d_2_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_unused_alias("MPATHe"); -@@ -719,9 +711,8 @@ static void lb_nomatch_a_d_3_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHd WWID1", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_used_alias("MPATHe", "WWID2"); -@@ -737,9 +728,8 @@ static void lb_nomatch_c_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHc WWID1\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); -@@ -751,10 +741,9 @@ static void lb_nomatch_d_a_unused(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHc WWID1\n" -+ "MPATHa WWID0\n" -+ "MPATHd WWID0\n", -1); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -767,10 +756,9 @@ static void lb_nomatch_d_a_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHc WWID1\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHd WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHc WWID1\n" -+ "MPATHa WWID0\n" -+ "MPATHd WWID0\n", -1); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHe"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -784,10 +772,9 @@ static void lb_nomatch_a_b(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb WWID1\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); -@@ -799,10 +786,9 @@ static void lb_nomatch_a_b_bad(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb\n", -1); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -@@ -815,10 +801,9 @@ static void lb_nomatch_a_b_bad_self(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb\n", -1); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - mock_self_alias("MPATHc", "WWID2"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -832,10 +817,9 @@ static void lb_nomatch_b_a(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHz WWID26\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 27); -@@ -847,10 +831,9 @@ static void lb_nomatch_b_a_3_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATHz WWID26\n" -+ "MPATHa WWID0\n", -1); - mock_used_alias("MPATHaa", "WWID2"); - mock_used_alias("MPATHab", "WWID2"); - mock_used_alias("MPATHac", "WWID2"); -@@ -867,10 +850,9 @@ static void do_lb_nomatch_int_max(void **state, int check_if_taken) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); - assert_int_equal(rc, -1); -@@ -892,9 +874,8 @@ static void lb_nomatch_int_max_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); - mock_used_alias("MPATHa", "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -907,10 +888,9 @@ static void lb_nomatch_int_max_m1(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -+ "MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, INT_MAX); -@@ -922,10 +902,9 @@ static void lb_nomatch_int_max_m1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -+ "MPATHa WWID0\n", -1); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -938,9 +917,8 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); - mock_used_alias("MPATHa", "WWID2"); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -@@ -954,9 +932,8 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - int rc; - char *alias; - -- will_return(__wrap_fgets, "MPATHb WWID1\n"); -- will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHb WWID1\n" -+ "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); - mock_used_alias("MPATHa", "WWID2"); - mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); - expect_condlog(0, NOMORE_STR); -@@ -1014,7 +991,7 @@ static void rl_empty(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1027,7 +1004,7 @@ static void rl_match_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -+ mock_bindings_file("MPATHa WWID0\n", 0); - expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, 0); -@@ -1040,8 +1017,7 @@ static void rl_nomatch_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa WWID0\n", -1); - expect_condlog(3, NOMATCH_STR("MPATHb")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, -1); -@@ -1054,8 +1030,7 @@ static void rl_malformed_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa \n"); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("MPATHa \n", -1); - expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); -@@ -1074,8 +1049,7 @@ static void rl_overlong_a(void **state) - snprintf(line + sizeof(line) - 2, 2, "\n"); - - buf[0] = '\0'; -- will_return(__wrap_fgets, line); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file(line, -1); - expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); -@@ -1089,9 +1063,9 @@ static void rl_match_b(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- will_return(__wrap_fgets, "MPATHa WWID0\n"); -- will_return(__wrap_fgets, "MPATHz WWID26\n"); -- will_return(__wrap_fgets, "MPATHb WWID2\n"); -+ mock_bindings_file("MPATHa WWID0\n" -+ "MPATHz WWID26\n" -+ "MPATHb WWID2\n", 2); - expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, 0); -@@ -1222,7 +1196,7 @@ static void gufa_empty_new_rw(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1235,7 +1209,7 @@ static void gufa_empty_new_rw(void **state) { - static void gufa_empty_new_ro_1(void **state) { - char *alias; - will_return(__wrap_open_file, false); -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1248,7 +1222,7 @@ static void gufa_empty_new_ro_2(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1261,7 +1235,7 @@ static void gufa_match_a_unused(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ mock_bindings_file("MPATHa WWID0", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHa"); - -@@ -1275,7 +1249,7 @@ static void gufa_match_a_self(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ mock_bindings_file("MPATHa WWID0", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_self_alias("MPATHa", "WWID0"); - -@@ -1289,7 +1263,7 @@ static void gufa_match_a_used(void **state) { - - will_return(__wrap_open_file, true); - -- will_return(__wrap_fgets, BINDING_STR("MPATHa", "WWID0")); -+ mock_bindings_file("MPATHa WWID0", 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -@@ -1389,11 +1363,11 @@ static void gufa_old_empty(void **state) { - will_return(__wrap_open_file, true); - - /* rlookup_binding for ALIAS */ -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_STR("MPATHz")); - - /* lookup_binding */ -- will_return(__wrap_fgets, NULL); -+ mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - - mock_allocate_binding("MPATHz", "WWID0"); diff --git a/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch index 407b621..0059895 100644 --- a/0051-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 72fd8d57..a49e9f5a 100644 +index 3d80d224..15e3bd3a 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0011-libmultipath-add-global-variable-for-current-binding.patch b/0011-libmultipath-add-global-variable-for-current-binding.patch deleted file mode 100644 index c91259d..0000000 --- a/0011-libmultipath-add-global-variable-for-current-binding.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 15:32:17 +0200 -Subject: [PATCH] libmultipath: add global variable for current bindings - -Add a variable global_bindings that holds the currently active vector of -bindings. This variable is freed at program exit. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 11 +++++++++-- - libmultipath/alias.h | 1 + - libmultipath/libmultipath.version | 1 + - multipath/main.c | 2 ++ - multipathd/main.c | 1 + - 5 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 9e9ac563..dd363fd8 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -511,6 +511,7 @@ static void _free_binding(struct binding *bdg) - * an abstract type. - */ - typedef struct _vector Bindings; -+static Bindings global_bindings = { .allocated = 0 }; - - static void free_bindings(Bindings *bindings) - { -@@ -522,6 +523,11 @@ static void free_bindings(Bindings *bindings) - vector_reset(bindings); - } - -+void cleanup_bindings(void) -+{ -+ free_bindings(&global_bindings); -+} -+ - enum { - BINDING_EXISTS, - BINDING_CONFLICT, -@@ -751,7 +757,6 @@ int check_alias_settings(const struct config *conf) - pthread_cleanup_pop(1); - pthread_cleanup_pop(1); - -- pthread_cleanup_push_cast(free_bindings, &bindings); - fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); - if (fd != -1) { - FILE *file = fdopen(fd, "r"); -@@ -771,6 +776,8 @@ int check_alias_settings(const struct config *conf) - close(fd); - } - } -- pthread_cleanup_pop(1); -+ -+ cleanup_bindings(); -+ global_bindings = bindings; - return rc; - } -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index fa332233..37b49d9c 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -9,5 +9,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, - - struct config; - int check_alias_settings(const struct config *); -+void cleanup_bindings(void); - - #endif /* _ALIAS_H */ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index a7b8c337..ddd302f5 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -64,6 +64,7 @@ global: - checker_name; - checker_state_name; - check_foreign; -+ cleanup_bindings; - cleanup_lock; - coalesce_paths; - count_active_paths; -diff --git a/multipath/main.c b/multipath/main.c -index b78f3162..45e9745f 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -843,6 +843,8 @@ main (int argc, char *argv[]) - conf->force_sync = 1; - if (atexit(cleanup_vecs)) - condlog(1, "failed to register cleanup handler for vecs: %m"); -+ if (atexit(cleanup_bindings)) -+ condlog(1, "failed to register cleanup handler for bindings: %m"); - while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 'v': -diff --git a/multipathd/main.c b/multipathd/main.c -index 2e02a548..214ed4ae 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3325,6 +3325,7 @@ static void cleanup_child(void) - { - cleanup_threads(); - cleanup_vecs(); -+ cleanup_bindings(); - if (poll_dmevents) - cleanup_dmevent_waiter(); - diff --git a/0052-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0052-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch index c78d5c0..b0c8749 100644 --- a/0052-RH-compile-with-libreadline-support.patch +++ b/0012-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index a49e9f5a..51b55196 100644 +index 15e3bd3a..64384a72 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch b/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch deleted file mode 100644 index e0f8673..0000000 --- a/0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 15:37:15 +0200 -Subject: [PATCH] libmultipath: rename fix_bindings_file() to - update_bindings_file() - -We will use this function in a more generic way, give it a more -generic name. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index dd363fd8..0aac2393 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -595,8 +595,8 @@ static int write_bindings_file(const Bindings *bindings, int fd) - return 0; - } - --static int fix_bindings_file(const struct config *conf, -- const Bindings *bindings) -+static int update_bindings_file(const struct config *conf, -+ const Bindings *bindings) - { - int rc; - int fd = -1; -@@ -766,7 +766,7 @@ int check_alias_settings(const struct config *conf) - rc = _check_bindings_file(conf, file, &bindings); - pthread_cleanup_pop(1); - if (rc == -1 && can_write && !conf->bindings_read_only) -- rc = fix_bindings_file(conf, &bindings); -+ rc = update_bindings_file(conf, &bindings); - else if (rc == -1) - condlog(0, "ERROR: bad settings in read-only bindings file %s", - conf->bindings_file); diff --git a/0053-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch similarity index 98% rename from 0053-RH-Add-mpathcleanup.patch rename to 0013-RH-Add-mpathcleanup.patch index 9278829..c15fb6d 100644 --- a/0053-RH-Add-mpathcleanup.patch +++ b/0013-RH-Add-mpathcleanup.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski create mode 100755 multipath/mpathcleanup diff --git a/multipath/Makefile b/multipath/Makefile -index 9942d1a9..d281b501 100644 +index 9f14036c..99ad81b0 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -25,6 +25,7 @@ install: @@ -25,7 +25,7 @@ index 9942d1a9..d281b501 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -46,6 +47,7 @@ endif +@@ -48,6 +49,7 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf diff --git a/0013-libmultipath-alias.c-move-bindings-related-code-up.patch b/0013-libmultipath-alias.c-move-bindings-related-code-up.patch deleted file mode 100644 index 1ad7b9e..0000000 --- a/0013-libmultipath-alias.c-move-bindings-related-code-up.patch +++ /dev/null @@ -1,285 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 16:54:54 +0200 -Subject: [PATCH] libmultipath: alias.c: move bindings related code up - -No code changes, just moving code. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 239 ++++++++++++++++++++++--------------------- - 1 file changed, 120 insertions(+), 119 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 0aac2393..7af403da 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "util.h" -@@ -51,6 +52,125 @@ - - static const char bindings_file_header[] = BINDINGS_FILE_HEADER; - -+struct binding { -+ char *alias; -+ char *wwid; -+}; -+ -+/* -+ * Perhaps one day we'll implement this more efficiently, thus use -+ * an abstract type. -+ */ -+typedef struct _vector Bindings; -+static Bindings global_bindings = { .allocated = 0 }; -+ -+enum { -+ BINDING_EXISTS, -+ BINDING_CONFLICT, -+ BINDING_ADDED, -+ BINDING_DELETED, -+ BINDING_NOTFOUND, -+ BINDING_ERROR, -+}; -+ -+static void _free_binding(struct binding *bdg) -+{ -+ free(bdg->wwid); -+ free(bdg->alias); -+ free(bdg); -+} -+ -+static int add_binding(Bindings *bindings, const char *alias, const char *wwid) -+{ -+ struct binding *bdg; -+ int i, cmp = 0; -+ -+ /* -+ * Keep the bindings array sorted by alias. -+ * Optimization: Search backwards, assuming that the bindings file is -+ * sorted already. -+ */ -+ vector_foreach_slot_backwards(bindings, bdg, i) { -+ if ((cmp = strcmp(bdg->alias, alias)) <= 0) -+ break; -+ } -+ -+ /* Check for exact match */ -+ if (i >= 0 && cmp == 0) -+ return strcmp(bdg->wwid, wwid) ? -+ BINDING_CONFLICT : BINDING_EXISTS; -+ -+ i++; -+ bdg = calloc(1, sizeof(*bdg)); -+ if (bdg) { -+ bdg->wwid = strdup(wwid); -+ bdg->alias = strdup(alias); -+ if (bdg->wwid && bdg->alias && -+ vector_insert_slot(bindings, i, bdg)) -+ return BINDING_ADDED; -+ else -+ _free_binding(bdg); -+ } -+ -+ return BINDING_ERROR; -+} -+ -+static int write_bindings_file(const Bindings *bindings, int fd) -+{ -+ struct binding *bnd; -+ STRBUF_ON_STACK(line); -+ int i; -+ -+ if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) -+ != sizeof(BINDINGS_FILE_HEADER) - 1) -+ return -1; -+ -+ vector_foreach_slot(bindings, bnd, i) { -+ int len; -+ -+ if ((len = print_strbuf(&line, "%s %s\n", -+ bnd->alias, bnd->wwid)) < 0) -+ return -1; -+ if (write(fd, get_strbuf_str(&line), len) != len) -+ return -1; -+ truncate_strbuf(&line, 0); -+ } -+ return 0; -+} -+ -+static int update_bindings_file(const struct config *conf, -+ const Bindings *bindings) -+{ -+ int rc; -+ int fd = -1; -+ char tempname[PATH_MAX]; -+ mode_t old_umask; -+ -+ if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) -+ return -1; -+ /* coverity: SECURE_TEMP */ -+ old_umask = umask(0077); -+ if ((fd = mkstemp(tempname)) == -1) { -+ condlog(1, "%s: mkstemp: %m", __func__); -+ return -1; -+ } -+ umask(old_umask); -+ pthread_cleanup_push(cleanup_fd_ptr, &fd); -+ rc = write_bindings_file(bindings, fd); -+ pthread_cleanup_pop(1); -+ if (rc == -1) { -+ condlog(1, "failed to write new bindings file %s", -+ tempname); -+ unlink(tempname); -+ return rc; -+ } -+ if ((rc = rename(tempname, conf->bindings_file)) == -1) -+ condlog(0, "%s: rename: %m", __func__); -+ else -+ condlog(1, "updated bindings file %s", conf->bindings_file); -+ return rc; -+} -+ - int - valid_alias(const char *alias) - { -@@ -494,25 +614,6 @@ get_user_friendly_wwid(const char *alias, char *buff, const char *file) - return 0; - } - --struct binding { -- char *alias; -- char *wwid; --}; -- --static void _free_binding(struct binding *bdg) --{ -- free(bdg->wwid); -- free(bdg->alias); -- free(bdg); --} -- --/* -- * Perhaps one day we'll implement this more efficiently, thus use -- * an abstract type. -- */ --typedef struct _vector Bindings; --static Bindings global_bindings = { .allocated = 0 }; -- - static void free_bindings(Bindings *bindings) - { - struct binding *bdg; -@@ -528,106 +629,6 @@ void cleanup_bindings(void) - free_bindings(&global_bindings); - } - --enum { -- BINDING_EXISTS, -- BINDING_CONFLICT, -- BINDING_ADDED, -- BINDING_DELETED, -- BINDING_NOTFOUND, -- BINDING_ERROR, --}; -- --static int add_binding(Bindings *bindings, const char *alias, const char *wwid) --{ -- struct binding *bdg; -- int i, cmp = 0; -- -- /* -- * Keep the bindings array sorted by alias. -- * Optimization: Search backwards, assuming that the bindings file is -- * sorted already. -- */ -- vector_foreach_slot_backwards(bindings, bdg, i) { -- if ((cmp = strcmp(bdg->alias, alias)) <= 0) -- break; -- } -- -- /* Check for exact match */ -- if (i >= 0 && cmp == 0) -- return strcmp(bdg->wwid, wwid) ? -- BINDING_CONFLICT : BINDING_EXISTS; -- -- i++; -- bdg = calloc(1, sizeof(*bdg)); -- if (bdg) { -- bdg->wwid = strdup(wwid); -- bdg->alias = strdup(alias); -- if (bdg->wwid && bdg->alias && -- vector_insert_slot(bindings, i, bdg)) -- return BINDING_ADDED; -- else -- _free_binding(bdg); -- } -- -- return BINDING_ERROR; --} -- --static int write_bindings_file(const Bindings *bindings, int fd) --{ -- struct binding *bnd; -- STRBUF_ON_STACK(line); -- int i; -- -- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) -- != sizeof(BINDINGS_FILE_HEADER) - 1) -- return -1; -- -- vector_foreach_slot(bindings, bnd, i) { -- int len; -- -- if ((len = print_strbuf(&line, "%s %s\n", -- bnd->alias, bnd->wwid)) < 0) -- return -1; -- if (write(fd, get_strbuf_str(&line), len) != len) -- return -1; -- truncate_strbuf(&line, 0); -- } -- return 0; --} -- --static int update_bindings_file(const struct config *conf, -- const Bindings *bindings) --{ -- int rc; -- int fd = -1; -- char tempname[PATH_MAX]; -- mode_t old_umask; -- -- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) -- return -1; -- /* coverity: SECURE_TEMP */ -- old_umask = umask(0077); -- if ((fd = mkstemp(tempname)) == -1) { -- condlog(1, "%s: mkstemp: %m", __func__); -- return -1; -- } -- umask(old_umask); -- pthread_cleanup_push(cleanup_fd_ptr, &fd); -- rc = write_bindings_file(bindings, fd); -- pthread_cleanup_pop(1); -- if (rc == -1) { -- condlog(1, "failed to write new bindings file %s", -- tempname); -- unlink(tempname); -- return rc; -- } -- if ((rc = rename(tempname, conf->bindings_file)) == -1) -- condlog(0, "%s: rename: %m", __func__); -- else -- condlog(1, "updated bindings file %s", conf->bindings_file); -- return rc; --} -- - static int _check_bindings_file(const struct config *conf, FILE *file, - Bindings *bindings) - { diff --git a/0014-libmultipath-update_bindings_file-take-filename-argu.patch b/0014-libmultipath-update_bindings_file-take-filename-argu.patch deleted file mode 100644 index 6b9d2e8..0000000 --- a/0014-libmultipath-update_bindings_file-take-filename-argu.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 15:53:49 +0200 -Subject: [PATCH] libmultipath: update_bindings_file: take filename argument - -This function just uses the file name, no other configuration -parameters. Also, pass the Bindings argument first to use the -same convention as the other functions in this file. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 7af403da..9bd3875e 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -138,15 +138,15 @@ static int write_bindings_file(const Bindings *bindings, int fd) - return 0; - } - --static int update_bindings_file(const struct config *conf, -- const Bindings *bindings) -+static int update_bindings_file(const Bindings *bindings, -+ const char *bindings_file) - { - int rc; - int fd = -1; - char tempname[PATH_MAX]; - mode_t old_umask; - -- if (safe_sprintf(tempname, "%s.XXXXXX", conf->bindings_file)) -+ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) - return -1; - /* coverity: SECURE_TEMP */ - old_umask = umask(0077); -@@ -164,10 +164,10 @@ static int update_bindings_file(const struct config *conf, - unlink(tempname); - return rc; - } -- if ((rc = rename(tempname, conf->bindings_file)) == -1) -+ if ((rc = rename(tempname, bindings_file)) == -1) - condlog(0, "%s: rename: %m", __func__); - else -- condlog(1, "updated bindings file %s", conf->bindings_file); -+ condlog(1, "updated bindings file %s", bindings_file); - return rc; - } - -@@ -767,7 +767,7 @@ int check_alias_settings(const struct config *conf) - rc = _check_bindings_file(conf, file, &bindings); - pthread_cleanup_pop(1); - if (rc == -1 && can_write && !conf->bindings_read_only) -- rc = update_bindings_file(conf, &bindings); -+ rc = update_bindings_file(&bindings, conf->bindings_file); - else if (rc == -1) - condlog(0, "ERROR: bad settings in read-only bindings file %s", - conf->bindings_file); diff --git a/0015-libmultipath-update_bindings_file-use-a-single-write.patch b/0015-libmultipath-update_bindings_file-use-a-single-write.patch deleted file mode 100644 index 1e1fd15..0000000 --- a/0015-libmultipath-update_bindings_file-use-a-single-write.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 15:54:45 +0200 -Subject: [PATCH] libmultipath: update_bindings_file: use a single write() - -Save code and syscalls by assembling the content in memory first. -write() may return less bytes written than expected. Deal with it. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 9bd3875e..92f90f05 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -118,22 +118,30 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - static int write_bindings_file(const Bindings *bindings, int fd) - { - struct binding *bnd; -- STRBUF_ON_STACK(line); -+ STRBUF_ON_STACK(content); - int i; -+ size_t len; - -- if (write(fd, BINDINGS_FILE_HEADER, sizeof(BINDINGS_FILE_HEADER) - 1) -- != sizeof(BINDINGS_FILE_HEADER) - 1) -+ if (__append_strbuf_str(&content, BINDINGS_FILE_HEADER, -+ sizeof(BINDINGS_FILE_HEADER) - 1) == -1) - return -1; - - vector_foreach_slot(bindings, bnd, i) { -- int len; -- -- if ((len = print_strbuf(&line, "%s %s\n", -- bnd->alias, bnd->wwid)) < 0) -+ if (print_strbuf(&content, "%s %s\n", -+ bnd->alias, bnd->wwid) < 0) - return -1; -- if (write(fd, get_strbuf_str(&line), len) != len) -+ } -+ len = get_strbuf_len(&content); -+ while (len > 0) { -+ ssize_t n = write(fd, get_strbuf_str(&content), len); -+ -+ if (n < 0) -+ return n; -+ else if (n == 0) { -+ condlog(2, "%s: short write", __func__); - return -1; -- truncate_strbuf(&line, 0); -+ } -+ len -= n; - } - return 0; - } diff --git a/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch b/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch deleted file mode 100644 index 1126b95..0000000 --- a/0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 22:33:39 +0200 -Subject: [PATCH] libmultipath: update_bindings_file: don't log temp file name - -The name of the temp file is unlikely to be helpful for users, -and hard to predict in the unit test. Omit it. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 92f90f05..afa5879e 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -167,8 +167,7 @@ static int update_bindings_file(const Bindings *bindings, - rc = write_bindings_file(bindings, fd); - pthread_cleanup_pop(1); - if (rc == -1) { -- condlog(1, "failed to write new bindings file %s", -- tempname); -+ condlog(1, "failed to write new bindings file"); - unlink(tempname); - return rc; - } diff --git a/0017-libmultipath-alias.c-factor-out-read_binding.patch b/0017-libmultipath-alias.c-factor-out-read_binding.patch deleted file mode 100644 index 8c9cb08..0000000 --- a/0017-libmultipath-alias.c-factor-out-read_binding.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Aug 2023 21:17:25 +0200 -Subject: [PATCH] libmultipath: alias.c: factor out read_binding() - -This way we can test the parsing of input lines from the bindings -file more easily. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 58 ++++++++++++++++++++++++++++++-------------- - 1 file changed, 40 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index afa5879e..ecf4a2ac 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -636,6 +636,43 @@ void cleanup_bindings(void) - free_bindings(&global_bindings); - } - -+enum { -+ READ_BINDING_OK, -+ READ_BINDING_SKIP, -+}; -+ -+static int read_binding(char *line, unsigned int linenr, char **alias, -+ char **wwid) { -+ char *c, *saveptr; -+ -+ c = strpbrk(line, "#\n\r"); -+ if (c) -+ *c = '\0'; -+ -+ *alias = strtok_r(line, " \t", &saveptr); -+ if (!*alias) /* blank line */ -+ return READ_BINDING_SKIP; -+ -+ *wwid = strtok_r(NULL, " \t", &saveptr); -+ if (!*wwid) { -+ condlog(1, "invalid line %u in bindings file, missing WWID", -+ linenr); -+ return READ_BINDING_SKIP; -+ } -+ if (strlen(*wwid) > WWID_SIZE - 1) { -+ condlog(3, -+ "Ignoring too large wwid at %u in bindings file", -+ linenr); -+ return READ_BINDING_SKIP; -+ } -+ c = strtok_r(NULL, " \t", &saveptr); -+ if (c) -+ /* This is non-fatal */ -+ condlog(1, "invalid line %d in bindings file, extra args \"%s\"", -+ linenr, c); -+ return READ_BINDING_OK; -+} -+ - static int _check_bindings_file(const struct config *conf, FILE *file, - Bindings *bindings) - { -@@ -647,27 +684,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - - pthread_cleanup_push(cleanup_free_ptr, &line); - while ((n = getline(&line, &line_len, file)) >= 0) { -- char *c, *alias, *wwid, *saveptr; -+ char *alias, *wwid; - const char *mpe_wwid; - -- linenr++; -- c = strpbrk(line, "#\n\r"); -- if (c) -- *c = '\0'; -- alias = strtok_r(line, " \t", &saveptr); -- if (!alias) /* blank line */ -- continue; -- wwid = strtok_r(NULL, " \t", &saveptr); -- if (!wwid) { -- condlog(1, "invalid line %d in bindings file, missing WWID", -- linenr); -+ if (read_binding(line, ++linenr, &alias, &wwid) -+ == READ_BINDING_SKIP) - continue; -- } -- c = strtok_r(NULL, " \t", &saveptr); -- if (c) -- /* This is non-fatal */ -- condlog(1, "invalid line %d in bindings file, extra args \"%s\"", -- linenr, c); - - mpe_wwid = get_mpe_wwid(conf->mptable, alias); - if (mpe_wwid && strcmp(mpe_wwid, wwid)) { diff --git a/0018-libmultipath-keep-bindings-in-memory.patch b/0018-libmultipath-keep-bindings-in-memory.patch deleted file mode 100644 index bb26ea2..0000000 --- a/0018-libmultipath-keep-bindings-in-memory.patch +++ /dev/null @@ -1,545 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 22 Aug 2023 21:14:51 +0200 -Subject: [PATCH] libmultipath: keep bindings in memory - -Rather than opening the bindings file every time we must retrieve -a binding, keep the contents in memory and write the file only -if additions have been made. This simplifies the code, and should speed up -alias lookups significantly. As a side effect, the aliases will be stored -sorted by alias, which changes the way aliases are allocated if there are -unused "holes" in the sequence of aliases. For example, if the bindings file -contains mpathb, mpathy, and mpatha, in this order, the next new alias used to -be mpathz and is now mpathc. - -Another side effect is that multipathd will not automatically pick up changes -to the bindings file at runtime without a reconfigure operation. It is -questionable whether these on-the-fly changes were a good idea in the first -place, as inconsistent configurations may easily come to pass. It desired, -it would be feasible to implement automatic update of the bindings using the -existing inotify approach. - -The new implementation of get_user_friendly_alias() is slightly different -than before. The logic is summarized in a comment in the code. Unit tests -will be provided that illustrate the changes. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 351 ++++++++++++++++----------------------- - libmultipath/alias.h | 2 +- - libmultipath/configure.c | 3 +- - 3 files changed, 144 insertions(+), 212 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index ecf4a2ac..d6563749 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -50,8 +50,6 @@ - "# alias wwid\n" \ - "#\n" - --static const char bindings_file_header[] = BINDINGS_FILE_HEADER; -- - struct binding { - char *alias; - char *wwid; -@@ -80,6 +78,45 @@ static void _free_binding(struct binding *bdg) - free(bdg); - } - -+static const struct binding *get_binding_for_alias(const Bindings *bindings, -+ const char *alias) -+{ -+ const struct binding *bdg; -+ int i; -+ -+ if (!alias) -+ return NULL; -+ vector_foreach_slot(bindings, bdg, i) { -+ if (!strncmp(bdg->alias, alias, WWID_SIZE)) { -+ condlog(3, "Found matching alias [%s] in bindings file." -+ " Setting wwid to %s", alias, bdg->wwid); -+ return bdg; -+ } -+ } -+ -+ condlog(3, "No matching alias [%s] in bindings file.", alias); -+ return NULL; -+} -+ -+static const struct binding *get_binding_for_wwid(const Bindings *bindings, -+ const char *wwid) -+{ -+ const struct binding *bdg; -+ int i; -+ -+ if (!wwid) -+ return NULL; -+ vector_foreach_slot(bindings, bdg, i) { -+ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { -+ condlog(3, "Found matching wwid [%s] in bindings file." -+ " Setting alias to %s", wwid, bdg->alias); -+ return bdg; -+ } -+ } -+ condlog(3, "No matching wwid [%s] in bindings file.", wwid); -+ return NULL; -+} -+ - static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - { - struct binding *bdg; -@@ -115,6 +152,24 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - return BINDING_ERROR; - } - -+static int delete_binding(Bindings *bindings, const char *wwid) -+{ -+ struct binding *bdg; -+ int i; -+ -+ vector_foreach_slot(bindings, bdg, i) { -+ if (!strncmp(bdg->wwid, wwid, WWID_SIZE)) { -+ _free_binding(bdg); -+ break; -+ } -+ } -+ if (i >= VECTOR_SIZE(bindings)) -+ return BINDING_NOTFOUND; -+ -+ vector_del_slot(bindings, i); -+ return BINDING_DELETED; -+} -+ - static int write_bindings_file(const Bindings *bindings, int fd) - { - struct binding *bnd; -@@ -267,38 +322,15 @@ static bool id_already_taken(int id, const char *prefix, const char *map_wwid) - return alias_already_taken(alias, map_wwid); - } - --/* -- * Returns: 0 if matching entry in WWIDs file found -- * -1 if an error occurs -- * >0 a free ID that could be used for the WWID at hand -- * *map_alias is set to a freshly allocated string with the matching alias if -- * the function returns 0, or to NULL otherwise. -- */ --static int --lookup_binding(FILE *f, const char *map_wwid, char **map_alias, -- const char *prefix, int check_if_taken) -+int get_free_id(const Bindings *bindings, const char *prefix, const char *map_wwid) - { -- char buf[LINE_MAX]; -- unsigned int line_nr = 0; -- int id = 1; -+ const struct binding *bdg; -+ int i, id = 1; - int biggest_id = 1; - int smallest_bigger_id = INT_MAX; - -- *map_alias = NULL; -- -- rewind(f); -- while (fgets(buf, LINE_MAX, f)) { -- const char *alias, *wwid; -- char *c, *saveptr; -- int curr_id; -- -- line_nr++; -- c = strpbrk(buf, "#\n\r"); -- if (c) -- *c = '\0'; -- alias = strtok_r(buf, " \t", &saveptr); -- if (!alias) /* blank line */ -- continue; -+ vector_foreach_slot(bindings, bdg, i) { -+ int curr_id = scan_devname(bdg->alias, prefix); - - /* - * Find an unused index - explanation of the algorithm -@@ -333,8 +365,6 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - * biggest_id is always > smallest_bigger_id, except in the - * "perfectly ordered" case. - */ -- -- curr_id = scan_devname(alias, prefix); - if (curr_id == id) { - if (id < INT_MAX) - id++; -@@ -345,36 +375,15 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - } - if (curr_id > biggest_id) - biggest_id = curr_id; -+ - if (curr_id > id && curr_id < smallest_bigger_id) - smallest_bigger_id = curr_id; -- wwid = strtok_r(NULL, " \t", &saveptr); -- if (!wwid){ -- condlog(3, -- "Ignoring malformed line %u in bindings file", -- line_nr); -- continue; -- } -- if (strcmp(wwid, map_wwid) == 0){ -- condlog(3, "Found matching wwid [%s] in bindings file." -- " Setting alias to %s", wwid, alias); -- *map_alias = strdup(alias); -- if (*map_alias == NULL) { -- condlog(0, "Cannot copy alias from bindings " -- "file: out of memory"); -- return -1; -- } -- return 0; -- } -- } -- if (!prefix && check_if_taken) -- id = -1; -- if (id >= smallest_bigger_id) { -- if (biggest_id < INT_MAX) -- id = biggest_id + 1; -- else -- id = -1; - } -- if (id > 0 && check_if_taken) { -+ -+ if (id >= smallest_bigger_id) -+ id = biggest_id < INT_MAX ? biggest_id + 1 : -1; -+ -+ if (id > 0) { - while(id_already_taken(id, prefix, map_wwid)) { - if (id == INT_MAX) { - id = -1; -@@ -391,64 +400,17 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - } - } - } -- if (id < 0) { -+ -+ if (id < 0) - condlog(0, "no more available user_friendly_names"); -- return -1; -- } else -- condlog(3, "No matching wwid [%s] in bindings file.", map_wwid); - return id; - } - --static int --rlookup_binding(FILE *f, char *buff, const char *map_alias) --{ -- char line[LINE_MAX]; -- unsigned int line_nr = 0; -- -- buff[0] = '\0'; -- -- while (fgets(line, LINE_MAX, f)) { -- char *c, *saveptr; -- const char *alias, *wwid; -- -- line_nr++; -- c = strpbrk(line, "#\n\r"); -- if (c) -- *c = '\0'; -- alias = strtok_r(line, " \t", &saveptr); -- if (!alias) /* blank line */ -- continue; -- wwid = strtok_r(NULL, " \t", &saveptr); -- if (!wwid){ -- condlog(3, -- "Ignoring malformed line %u in bindings file", -- line_nr); -- continue; -- } -- if (strlen(wwid) > WWID_SIZE - 1) { -- condlog(3, -- "Ignoring too large wwid at %u in bindings file", line_nr); -- continue; -- } -- if (strcmp(alias, map_alias) == 0){ -- condlog(3, "Found matching alias [%s] in bindings file." -- " Setting wwid to %s", alias, wwid); -- strlcpy(buff, wwid, WWID_SIZE); -- return 0; -- } -- } -- condlog(3, "No matching alias [%s] in bindings file.", map_alias); -- -- return -1; --} -- - static char * --allocate_binding(int fd, const char *wwid, int id, const char *prefix) -+allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) - { - STRBUF_ON_STACK(buf); -- off_t offset; -- ssize_t len; -- char *alias, *c; -+ char *alias; - - if (id <= 0) { - condlog(0, "%s: cannot allocate new binding for id %d", -@@ -460,164 +422,135 @@ allocate_binding(int fd, const char *wwid, int id, const char *prefix) - format_devname(&buf, id) == -1) - return NULL; - -- if (print_strbuf(&buf, " %s\n", wwid) < 0) -- return NULL; -+ alias = steal_strbuf_str(&buf); - -- offset = lseek(fd, 0, SEEK_END); -- if (offset < 0){ -- condlog(0, "Cannot seek to end of bindings file : %s", -- strerror(errno)); -+ if (add_binding(&global_bindings, alias, wwid) != BINDING_ADDED) { -+ condlog(0, "%s: cannot allocate new binding %s for %s", -+ __func__, alias, wwid); -+ free(alias); - return NULL; - } - -- len = get_strbuf_len(&buf); -- alias = steal_strbuf_str(&buf); -- -- if (write(fd, alias, len) != len) { -- condlog(0, "Cannot write binding to bindings file : %s", -- strerror(errno)); -- /* clear partial write */ -- if (ftruncate(fd, offset)) -- condlog(0, "Cannot truncate the header : %s", -- strerror(errno)); -+ if (update_bindings_file(&global_bindings, filename) == -1) { -+ condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); -+ delete_binding(&global_bindings, wwid); - free(alias); - return NULL; - } -- c = strchr(alias, ' '); -- if (c) -- *c = '\0'; - - condlog(3, "Created new binding [%s] for WWID [%s]", alias, wwid); - return alias; - } - -+/* -+ * get_user_friendly_alias() action table -+ * -+ * The table shows the various cases, the actions taken, and the CI -+ * functions from tests/alias.c that represent them. -+ * -+ * - O: old alias given -+ * - A: old alias in table (y: yes, correct WWID; X: yes, wrong WWID) -+ * - W: wwid in table -+ * -+ * | No | O | A | W | action | function gufa_X | -+ * |----+---+---+---+--------------------------------------------+------------------------------| -+ * | 1 | n | - | n | get new alias | nomatch_Y | -+ * | 2 | n | - | y | use alias from bindings | match_a_Y | -+ * | 3 | y | n | n | add binding for old alias | old_nomatch_nowwidmatch | -+ * | 4 | y | n | y | use alias from bindings (avoid duplicates) | old_nomatch_wwidmatch | -+ * | 5 | y | y | n | [ impossible ] | - | -+ * | 6 | y | y | y | use old alias == alias from bindings | old_match | -+ * | 7 | y | X | n | get new alias | old_match_other | -+ * | 8 | y | X | y | use alias from bindings | old_match_other_wwidmatch | -+ * -+ * Notes: -+ * - "use alias from bindings" means that the alias from the bindings file will -+ * be tried; if it is in use, the alias selection will fail. No other -+ * bindings will be attempted. -+ * - "get new alias" fails if all aliases are used up, or if writing the -+ * bindings file fails. -+ * - if "alias_old" is set, it can't be bound to a different map. alias_old is -+ * initialized in find_existing_alias() by scanning the mpvec. We trust -+ * that the mpvec corrcectly represents kernel state. -+ */ -+ - char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, - const char *prefix, bool bindings_read_only) - { - char *alias = NULL; - int id = 0; -- int fd, can_write; - bool new_binding = false; -- char buff[WWID_SIZE]; -- FILE *f; -- -- fd = open_file(file, &can_write, bindings_file_header); -- if (fd < 0) -- return NULL; -- -- f = fdopen(fd, "r"); -- if (!f) { -- condlog(0, "cannot fdopen on bindings file descriptor"); -- close(fd); -- return NULL; -- } -+ const struct binding *bdg; - -- if (!strlen(alias_old)) -+ if (!*alias_old) - goto new_alias; - -- /* lookup the binding. if it exists, the wwid will be in buff -- * either way, id contains the id for the alias -- */ -- rlookup_binding(f, buff, alias_old); -- -- if (strlen(buff) > 0) { -- /* If buff is our wwid, it's already allocated correctly. */ -- if (strcmp(buff, wwid) == 0) { -+ /* See if there's a binding matching both alias_old and wwid */ -+ bdg = get_binding_for_alias(&global_bindings, alias_old); -+ if (bdg) { -+ if (!strcmp(bdg->wwid, wwid)) { - alias = strdup(alias_old); - goto out; -- - } else { - condlog(0, "alias %s already bound to wwid %s, cannot reuse", -- alias_old, buff); -+ alias_old, bdg->wwid); - goto new_alias; - } - } - -- /* -- * Look for an existing alias in the bindings file. -- * Pass prefix = NULL, so lookup_binding() won't try to allocate a new id. -- */ -- lookup_binding(f, wwid, &alias, NULL, 0); -- if (alias) { -- if (alias_already_taken(alias, wwid)) { -- free(alias); -- alias = NULL; -- } else -+ /* allocate the existing alias in the bindings file */ -+ id = scan_devname(alias_old, prefix); -+ -+new_alias: -+ /* Check for existing binding of WWID */ -+ bdg = get_binding_for_wwid(&global_bindings, wwid); -+ if (bdg) { -+ if (!alias_already_taken(bdg->alias, wwid)) { - condlog(3, "Use existing binding [%s] for WWID [%s]", -- alias, wwid); -+ bdg->alias, wwid); -+ alias = strdup(bdg->alias); -+ } - goto out; - } - -- /* alias_old is already taken by our WWID, update bindings file. */ -- id = scan_devname(alias_old, prefix); -- --new_alias: - if (id <= 0) { - /* - * no existing alias was provided, or allocating it - * failed. Try a new one. - */ -- id = lookup_binding(f, wwid, &alias, prefix, 1); -- if (id == 0 && alias_already_taken(alias, wwid)) { -- free(alias); -- alias = NULL; -- } -+ id = get_free_id(&global_bindings, prefix, wwid); - if (id <= 0) - goto out; - else - new_binding = true; - } - -- if (fflush(f) != 0) { -- condlog(0, "cannot fflush bindings file stream : %s", -- strerror(errno)); -- goto out; -- } -+ if (!bindings_read_only && id > 0) -+ alias = allocate_binding(file, wwid, id, prefix); - -- if (can_write && !bindings_read_only) { -- alias = allocate_binding(fd, wwid, id, prefix); -- if (alias && !new_binding) -- condlog(2, "Allocated existing binding [%s] for WWID [%s]", -- alias, wwid); -- } -+ if (alias && !new_binding) -+ condlog(2, "Allocated existing binding [%s] for WWID [%s]", -+ alias, wwid); - - out: -- pthread_cleanup_push(free, alias); -- fclose(f); -- pthread_cleanup_pop(0); - return alias; - } - --int --get_user_friendly_wwid(const char *alias, char *buff, const char *file) -+int get_user_friendly_wwid(const char *alias, char *buff) - { -- int fd, unused; -- FILE *f; -+ const struct binding *bdg; - - if (!alias || *alias == '\0') { - condlog(3, "Cannot find binding for empty alias"); - return -1; - } - -- fd = open_file(file, &unused, bindings_file_header); -- if (fd < 0) -- return -1; -- -- f = fdopen(fd, "r"); -- if (!f) { -- condlog(0, "cannot fdopen on bindings file descriptor : %s", -- strerror(errno)); -- close(fd); -+ bdg = get_binding_for_alias(&global_bindings, alias); -+ if (!bdg) { -+ *buff = '\0'; - return -1; - } -- -- rlookup_binding(f, buff, alias); -- if (!strlen(buff)) { -- fclose(f); -- return -1; -- } -- -- fclose(f); -+ strlcpy(buff, bdg->wwid, WWID_SIZE); - return 0; - } - -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index 37b49d9c..5ef6720b 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -2,7 +2,7 @@ - #define _ALIAS_H - - int valid_alias(const char *alias); --int get_user_friendly_wwid(const char *alias, char *buff, const char *file); -+int get_user_friendly_wwid(const char *alias, char *buff); - char *get_user_friendly_alias(const char *wwid, const char *file, - const char *alias_old, - const char *prefix, bool bindings_read_only); -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 029fbbd2..d8094903 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1378,8 +1378,7 @@ static int _get_refwwid(enum mpath_cmds cmd, const char *dev, - refwwid = tmpwwid; - - /* or may be a binding */ -- else if (get_user_friendly_wwid(dev, tmpwwid, -- conf->bindings_file) == 0) -+ else if (get_user_friendly_wwid(dev, tmpwwid) == 0) - refwwid = tmpwwid; - - /* or may be an alias */ diff --git a/0019-multipath-tools-tests-fix-alias-tests.patch b/0019-multipath-tools-tests-fix-alias-tests.patch deleted file mode 100644 index da618f6..0000000 --- a/0019-multipath-tools-tests-fix-alias-tests.patch +++ /dev/null @@ -1,1698 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 25 Aug 2023 17:55:55 +0200 -Subject: [PATCH] multipath-tools tests: fix alias tests - -The different implementation of get_user_friendly_alias() and its helpers -necessitates changes in the unit tests. It would be nice if it didn't, but the -unit tests are too closely bound to the implementation to make this possible. - -- The bindings table is held in memory in alphabetically sorted order, which - may change the result of looking for free alias IDs if the entries in the - bindings file were unordered initially. In particular, if only a small - number of bindings exists, "holes" in the file will be detected more easily. - But because the sort order of the aliases differs from simple alphabetic - sorting ("mpathz" precedes "mpathaa"), a bindings file that contains all - bindings from "a" to "aa" (or more) will appear unsorted. - As an extra check, some of the unit tests deliberately use a different - implementation of add_binding() that does not order the bindings - table. - -- Broken lines in the bindings file never make it to the in-memory - representation. An alias that appeard "used" because it occurred in a broken - line will not appear used any more. Warnings about malformed lines will only - be printed while the bindings file is read, not from get_user_friendly_alias(). - -- The match_line argument of mock_bindings_file() is obsolete. - -- lookup_binding() and rlookup_binding() have been removed from - libmultipath. They are now emulated in the unit test code. - -- lookup_binding() didn't check for used alias in all cases previously, but it does now. - -- prefix != NULL and check_if_taken == false is not supported any more - in lookup_binding(). - -- allocate_binding() uses a very different sequence of systems calls now, as - it's implemented using update_bindings_file(). In particular, it's now more - difficult to predict the content of the write() call that creates the - bindings file. See comments for __wrap_write(). - -- some unit tests for get_user_friendly_alias() had to call - mock_bindings_file() twice, because the old implementation would read the - file twice (first rlookup_binding() and then lookup_binding()). This is not - necessary any more. - -- The unit tests need a teardown function to clear the bindings table in memory. - -- Minor changes are necessary because of changed ordering of the log messages. - Previously, lookup_binding() combined check for an existing entry and the - search for a new ID. The new algorithm does this in two separate steps and - tests for used aliases in between, which causes a change in the order in which - log messages are emitted. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 957 ++++++++++++++++++++++++++++++++------------------ - 1 file changed, 614 insertions(+), 343 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index f334f928..50a21ecf 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -3,10 +3,12 @@ - #include - #include - #include -+#include "strbuf.h" - #include "util.h" - #include "alias.h" - #include "test-log.h" - #include -+#include - - #include "globals.c" - #include "../libmultipath/alias.c" -@@ -20,18 +22,6 @@ - #define MPATH_ID_INT_MAX_p1 "fxshrxx" - #endif - --void __wrap_rewind(FILE *stream) --{} -- --char *__wrap_fgets(char *buf, int n, FILE *stream) --{ -- char *val = mock_ptr_type(char *); -- if (!val) -- return NULL; -- strlcpy(buf, val, n); -- return buf; --} -- - static int __set_errno(int err) - { - if (err >= 0) { -@@ -43,23 +33,44 @@ static int __set_errno(int err) - } - } - --off_t __wrap_lseek(int fd, off_t offset, int whence) -+/* -+ * allocate_binding -> write_bindings_file() writes the entire file, i.e. the -+ * header, any pre-existing bindings, and the new binding. The complete content -+ * depends on history and is different to predict here. Therefore we check only -+ * the newly added binding. Because add_binding() sorts entries, this new -+ * binding isn't necessarily the last one; receive it from will_return() and -+ * search for it with strstr(). -+ * If the string to be written doesn't start with the bindings file -+ * header, it's a test of a partial write. -+ */ -+ssize_t __wrap_write(int fd, const void *buf, size_t count) - { -- return __set_errno(mock_type(int)); -+ const char *binding, *start; - -+#if DEBUG_WRITE -+ fprintf(stderr, "%s: %zx exp %zx\n===\n%s\n===\n", __func__, strlen(buf), -+ count, (const char *)buf); -+#endif -+ if (!strncmp((const char *)buf, BINDINGS_FILE_HEADER, -+ sizeof(BINDINGS_FILE_HEADER) - 1)) -+ start = (const char *)buf + sizeof(BINDINGS_FILE_HEADER) - 1; -+ else -+ start = buf; -+ binding = mock_ptr_type(char *); -+ start = strstr(start, binding); -+ check_expected(count); -+ assert_ptr_not_equal(start, NULL); -+ return __set_errno(mock_type(int)); - } - --ssize_t __wrap_write(int fd, const void *buf, size_t count) -+int __wrap_rename(const char *old, const char *new) - { -- check_expected(count); -- check_expected(buf); - return __set_errno(mock_type(int)); - } - --int __wrap_ftruncate(int fd, off_t length) -+int __wrap_mkstemp(char *template) - { -- check_expected(length); -- return __set_errno(mock_type(int)); -+ return 10; - } - - int __wrap_dm_map_present(const char * str) -@@ -84,32 +95,6 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - #define TEST_FDNO 1234 - #define TEST_FPTR ((FILE *) 0xaffe) - --int __wrap_open_file(const char *file, int *can_write, const char *header) --{ -- int cw = mock_type(int); -- -- *can_write = cw; -- return TEST_FDNO; --} -- --FILE *__wrap_fdopen(int fd, const char *mode) --{ -- assert_int_equal(fd, TEST_FDNO); -- return TEST_FPTR; --} -- --int __wrap_fflush(FILE *f) --{ -- assert_ptr_equal(f, TEST_FPTR); -- return 0; --} -- --int __wrap_fclose(FILE *f) --{ -- assert_ptr_equal(f, TEST_FPTR); -- return 0; --} -- - /* strbuf wrapper for the old format_devname() */ - static int __format_devname(char *name, int id, size_t len, const char *prefix) - { -@@ -466,22 +451,85 @@ static void mock_self_alias(const char *alias, const char *wwid) - expect_condlog(3, USED_STR(alias, wwid)); \ - } while(0) - --static void mock_bindings_file(const char *content, int match_line) -+static int add_binding_unsorted(Bindings *bindings, -+ const char *alias, const char *wwid) -+{ -+ struct binding *bdg = calloc(1, sizeof(*bdg)); -+ -+ if (!bdg) -+ return -1; -+ bdg->wwid = strdup(wwid); -+ bdg->alias = strdup(alias); -+ if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { -+ free(bdg->alias); -+ free(bdg->wwid); -+ free(bdg); -+ return BINDING_ERROR; -+ } -+ vector_set_slot(bindings, bdg); -+ return BINDING_ADDED; -+} -+ -+static void __mock_bindings_file(const char *content, -+ int (*add)(Bindings *, const char *, const char *)) - { -- static char cnt[1024]; -- char *token; -+ char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; -+ char *token, *savep = NULL; - int i; - -- assert_in_range(strlcpy(cnt, content, sizeof(cnt)), 0, sizeof(cnt) - 1); -+ cnt = strdup(content); -+ assert_ptr_not_equal(cnt, NULL); - -- for (token = strtok(cnt, "\n"), i = 0; -+ for (token = strtok_r(cnt, "\n", &savep), i = 0; - token && *token; -- token = strtok(NULL, "\n"), i++) { -- will_return(__wrap_fgets, token); -- if (match_line == i) -- return; -+ token = strtok_r(NULL, "\n", &savep), i++) { -+ char *alias, *wwid; -+ int rc; -+ -+ if (read_binding(token, i + 1, &alias, &wwid) -+ == READ_BINDING_SKIP) -+ continue; -+ -+ rc = add(&global_bindings, alias, wwid); -+ assert_int_equal(rc, BINDING_ADDED); - } -- will_return(__wrap_fgets, NULL); -+} -+ -+static void mock_bindings_file(const char *content) { -+ return __mock_bindings_file(content, add_binding); -+} -+ -+static void mock_bindings_file_unsorted(const char *content) { -+ return __mock_bindings_file(content, add_binding_unsorted); -+} -+ -+static int teardown_bindings(void **state) -+{ -+ cleanup_bindings(); -+ return 0; -+} -+ -+static int lookup_binding(FILE *dummy, const char *wwid, char **alias, -+ const char *prefix, int check_if_taken) -+{ -+ const struct binding *bdg; -+ int id; -+ -+ /* -+ * get_free_id() always checks if aliases are taken. -+ * Therefore if prefix is non-null, check_if_taken must be true. -+ */ -+ assert_true(!prefix || check_if_taken); -+ *alias = NULL; -+ bdg = get_binding_for_wwid(&global_bindings, wwid); -+ if (bdg) { -+ *alias = strdup(bdg->alias); -+ return 0; -+ } else if (!prefix && check_if_taken) -+ return -1; -+ -+ id = get_free_id(&global_bindings, prefix, wwid); -+ return id; - } - - static void lb_empty(void **state) -@@ -489,7 +537,7 @@ static void lb_empty(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); -@@ -501,7 +549,7 @@ static void lb_empty_unused(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -@@ -515,10 +563,10 @@ static void lb_empty_failed(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_failed_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -530,10 +578,10 @@ static void lb_empty_1_used(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -545,10 +593,10 @@ static void lb_empty_1_used_self(void **state) - int rc; - char *alias; - -- mock_bindings_file("", -1); -+ mock_bindings_file(""); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_used_alias("MPATHa", "WWID0"); - mock_self_alias("MPATHb", "WWID0"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); -@@ -560,9 +608,9 @@ static void lb_match_a(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", 0); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); -- rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); -@@ -574,9 +622,10 @@ static void lb_nomatch_a(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); -+ mock_unused_alias("MPATHb"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -586,8 +635,8 @@ static void lb_nomatch_a_bad_check(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -- expect_condlog(0, NOMORE_STR); -+ mock_bindings_file("MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, NULL, 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); -@@ -598,7 +647,7 @@ static void lb_nomatch_a_unused(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -@@ -611,27 +660,27 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - int rc; - char *alias; - -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - mock_used_alias("MPATHb", "WWID1"); - mock_used_alias("MPATHc", "WWID1"); - mock_used_alias("MPATHd", "WWID1"); - mock_failed_alias("MPATHe", "WWID1"); - mock_self_alias("MPATHf", "WWID1"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); - } - --static void do_lb_match_c(void **state, int check_if_taken) -+static void do_lb_match_c(void **state) - { - int rc; - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHc WWID1", 1); -+ "MPATHc WWID1"); - expect_condlog(3, FOUND_STR("MPATHc", "WWID1")); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", check_if_taken); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHc"); -@@ -640,12 +689,12 @@ static void do_lb_match_c(void **state, int check_if_taken) - - static void lb_match_c(void **state) - { -- do_lb_match_c(state, 0); -+ do_lb_match_c(state); - } - - static void lb_match_c_check(void **state) - { -- do_lb_match_c(state, 1); -+ do_lb_match_c(state); - } - - static void lb_nomatch_a_c(void **state) -@@ -654,9 +703,10 @@ static void lb_nomatch_a_c(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHc WWID1", -1); -+ "MPATHc WWID1"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ mock_unused_alias("MPATHb"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -667,7 +717,7 @@ static void lb_nomatch_a_d_unused(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -681,10 +731,10 @@ static void lb_nomatch_a_d_1_used(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHc"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); -@@ -696,11 +746,11 @@ static void lb_nomatch_a_d_2_used(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_unused_alias("MPATHe"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -712,12 +762,12 @@ static void lb_nomatch_a_d_3_used(void **state) - char *alias; - - mock_bindings_file("MPATHa WWID0\n" -- "MPATHd WWID1", -1); -+ "MPATHd WWID1"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_used_alias("MPATHc", "WWID2"); - mock_used_alias("MPATHe", "WWID2"); - mock_unused_alias("MPATHf"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 6); - assert_ptr_equal(alias, NULL); -@@ -729,9 +779,10 @@ static void lb_nomatch_c_a(void **state) - char *alias; - - mock_bindings_file("MPATHc WWID1\n" -- "MPATHa WWID0\n", -1); -+ "MPATHa WWID0\n"); -+ mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -743,7 +794,7 @@ static void lb_nomatch_d_a_unused(void **state) - - mock_bindings_file("MPATHc WWID1\n" - "MPATHa WWID0\n" -- "MPATHd WWID0\n", -1); -+ "MPATHd WWID0\n"); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -@@ -758,10 +809,10 @@ static void lb_nomatch_d_a_1_used(void **state) - - mock_bindings_file("MPATHc WWID1\n" - "MPATHa WWID0\n" -- "MPATHd WWID0\n", -1); -+ "MPATHd WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - mock_used_alias("MPATHb", "WWID2"); - mock_unused_alias("MPATHe"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); -@@ -774,9 +825,10 @@ static void lb_nomatch_a_b(void **state) - - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb WWID1\n", -1); -+ "MPATHb WWID1\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ mock_unused_alias("MPATHc"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } -@@ -786,13 +838,19 @@ static void lb_nomatch_a_b_bad(void **state) - int rc; - char *alias; - -+ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); -+ /* -+ * The broken line will be ignored when constructing the bindings vector. -+ * Thus in lookup_binding() MPATHb is never encountered, -+ * and MPATHb appears usable. -+ */ - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb\n", -1); -- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); -+ "MPATHb\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -- assert_int_equal(rc, 3); -+ mock_unused_alias("MPATHb"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } - -@@ -801,84 +859,200 @@ static void lb_nomatch_a_b_bad_self(void **state) - int rc; - char *alias; - -+ expect_condlog(1, "invalid line 3 in bindings file, missing WWID\n"); - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb\n", -1); -- expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); -- mock_self_alias("MPATHc", "WWID2"); -+ "MPATHb\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_self_alias("MPATHb", "WWID2"); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -- assert_int_equal(rc, 3); -+ assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_b_a(void **state) -+static void lb_nomatch_b_z_a(void **state) - { - int rc; - char *alias; - -+ /* -+ * add_bindings() sorts alphabetically. Therefore get_free_id() -+ * finds MPATHc as a free entry. -+ */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" -- "MPATHa WWID0\n", -1); -+ "MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -- assert_int_equal(rc, 27); -+ mock_unused_alias("MPATHc"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_b_a_3_used(void **state) -+static void lb_nomatch_b_aa_a(void **state) - { - int rc; - char *alias; - -+ /* -+ * add_bindings() sorts alphabetically. ("a", "aa", b"). -+ * The get_free_id() algorithm finds the "hole" after "b". -+ */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" -- "MPATHa WWID0\n", -1); -- mock_used_alias("MPATHaa", "WWID2"); -- mock_used_alias("MPATHab", "WWID2"); -- mock_used_alias("MPATHac", "WWID2"); -- mock_unused_alias("MPATHad"); -+ "MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_unused_alias("MPATHc"); - rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -- assert_int_equal(rc, 30); -+ assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } - --#ifdef MPATH_ID_INT_MAX --static void do_lb_nomatch_int_max(void **state, int check_if_taken) -+static void fill_bindings(struct strbuf *buf, int start, int end) -+{ -+ int i; -+ -+ for (i = start; i <= end; i++) { -+ print_strbuf(buf, "MPATH"); -+ format_devname(buf, i + 1); -+ print_strbuf(buf, " WWID%d\n", i); -+ } -+} -+ -+static void lb_nomatch_b_a_aa(void **state) -+{ -+ int rc; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ /* -+ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -+ * lookup_binding finds MPATHac as next free entry. -+ */ -+ fill_bindings(&buf, 0, 26); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); -+ mock_unused_alias("MPATHab"); -+ rc = lookup_binding(NULL, "WWID28", &alias, "MPATH", 1); -+ assert_int_equal(rc, 28); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_b_a_aa_zz(void **state) -+{ -+ int rc, i; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ /* -+ * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -+ * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is -+ * found before MPATHb, and MPATHzz was in the bindings, too. -+ */ -+ for (i = 0; i <= 26; i++) { -+ print_strbuf(&buf, "MPATH"); -+ format_devname(&buf, i + 1); -+ print_strbuf(&buf, " WWID%d\n", i); -+ } -+ print_strbuf(&buf, "MPATHzz WWID676\n"); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID703")); -+ mock_unused_alias("MPATHaaa"); -+ rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); -+ assert_int_equal(rc, 703); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_b_z_a_unsorted(void **state) -+{ -+ int rc; -+ char *alias; -+ -+ /* -+ * With unsorted bindings (shouldn't happen normally), get_free_id() -+ * plays safe and returns MPATHaa as first free entry. -+ */ -+ mock_bindings_file_unsorted("MPATHb WWID1\n" -+ "MPATHz WWID26\n" -+ "MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_unused_alias("MPATHaa"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 27); -+ assert_ptr_equal(alias, NULL); -+} -+ -+static void lb_nomatch_b_a(void **state) - { - int rc; - char *alias; - - mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n" -- "MPATHa WWID0\n", -1); -- expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", check_if_taken); -- assert_int_equal(rc, -1); -+ "MPATHa WWID0\n"); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -+ mock_unused_alias("MPATHc"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_int_max(void **state) -+static void lb_nomatch_b_a_3_used(void **state) - { -- do_lb_nomatch_int_max(state, 0); -+ int rc; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ fill_bindings(&buf, 0, 26); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID31")); -+ mock_used_alias("MPATHab", "WWID31"); -+ mock_used_alias("MPATHac", "WWID31"); -+ mock_used_alias("MPATHad", "WWID31"); -+ mock_unused_alias("MPATHae"); -+ rc = lookup_binding(NULL, "WWID31", &alias, "MPATH", 1); -+ assert_int_equal(rc, 31); -+ assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_int_max_check(void **state) -+#ifdef MPATH_ID_INT_MAX -+/* -+ * The bindings will be sorted by alias, alphabetically, which is not -+ * the same as the "numeric" sort order for user-friendly aliases. -+ * get_free_id() selects the highest used ID + 1 if an unsorted entry -+ * is encountered in the bindings table and it's id is equal to the -+ * next "expected" id. This happens if all IDs from "a" to "aa" are -+ * in the table. If the INT_MAX entry is in the table, too, it will -+ * overflow. -+ */ -+static void lb_nomatch_int_max(void **state) - { -- do_lb_nomatch_int_max(state, 1); -+ int rc; -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ fill_bindings(&buf, 0, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); -+ expect_condlog(0, NOMORE_STR); -+ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); -+ assert_int_equal(rc, -1); -+ assert_ptr_equal(alias, NULL); - } - - static void lb_nomatch_int_max_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n", -1); -- mock_used_alias("MPATHa", "WWID2"); -+ fill_bindings(&buf, 1, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); -+ mock_used_alias("MPATHa", "WWIDNOMORE"); - expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -887,12 +1061,14 @@ static void lb_nomatch_int_max_m1(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -- "MPATHa WWID0\n", -1); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); -+ fill_bindings(&buf, 0, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); - } -@@ -901,13 +1077,15 @@ static void lb_nomatch_int_max_m1_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n" -- "MPATHa WWID0\n", -1); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); -+ fill_bindings(&buf, 0, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); - expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -916,13 +1094,15 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); -- mock_used_alias("MPATHa", "WWID2"); -+ fill_bindings(&buf, 1, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_used_alias("MPATHa", "WWIDMAX"); - mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); - } -@@ -931,13 +1111,17 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - { - int rc; - char *alias; -+ STRBUF_ON_STACK(buf); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n", -1); -- mock_used_alias("MPATHa", "WWID2"); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWID2"); -+ fill_bindings(&buf, 1, 26); -+ print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ -+ expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -+ mock_used_alias("MPATHa", "WWIDMAX"); -+ mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); - expect_condlog(0, NOMORE_STR); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -+ rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -946,52 +1130,68 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - static int test_lookup_binding(void) - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(lb_empty), -- cmocka_unit_test(lb_empty_unused), -- cmocka_unit_test(lb_empty_failed), -- cmocka_unit_test(lb_empty_1_used), -- cmocka_unit_test(lb_empty_1_used_self), -- cmocka_unit_test(lb_match_a), -- cmocka_unit_test(lb_nomatch_a), -- cmocka_unit_test(lb_nomatch_a_bad_check), -- cmocka_unit_test(lb_nomatch_a_unused), -- cmocka_unit_test(lb_nomatch_a_3_used_failed_self), -- cmocka_unit_test(lb_match_c), -- cmocka_unit_test(lb_match_c_check), -- cmocka_unit_test(lb_nomatch_a_c), -- cmocka_unit_test(lb_nomatch_a_d_unused), -- cmocka_unit_test(lb_nomatch_a_d_1_used), -- cmocka_unit_test(lb_nomatch_a_d_2_used), -- cmocka_unit_test(lb_nomatch_a_d_3_used), -- cmocka_unit_test(lb_nomatch_c_a), -- cmocka_unit_test(lb_nomatch_d_a_unused), -- cmocka_unit_test(lb_nomatch_d_a_1_used), -- cmocka_unit_test(lb_nomatch_a_b), -- cmocka_unit_test(lb_nomatch_a_b_bad), -- cmocka_unit_test(lb_nomatch_a_b_bad_self), -- cmocka_unit_test(lb_nomatch_b_a), -- cmocka_unit_test(lb_nomatch_b_a_3_used), -+ cmocka_unit_test_teardown(lb_empty, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_failed, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_empty_1_used_self, teardown_bindings), -+ cmocka_unit_test_teardown(lb_match_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_bad_check, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_3_used_failed_self, teardown_bindings), -+ cmocka_unit_test_teardown(lb_match_c, teardown_bindings), -+ cmocka_unit_test_teardown(lb_match_c_check, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_c, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_2_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_d_3_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_c_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_d_a_unused, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_d_a_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_b, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_b_bad, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_a_b_bad_self, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_z_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), - #ifdef MPATH_ID_INT_MAX -- cmocka_unit_test(lb_nomatch_int_max), -- cmocka_unit_test(lb_nomatch_int_max_check), -- cmocka_unit_test(lb_nomatch_int_max_used), -- cmocka_unit_test(lb_nomatch_int_max_m1), -- cmocka_unit_test(lb_nomatch_int_max_m1_used), -- cmocka_unit_test(lb_nomatch_int_max_m1_1_used), -- cmocka_unit_test(lb_nomatch_int_max_m1_2_used), -+ cmocka_unit_test_teardown(lb_nomatch_int_max, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_1_used, teardown_bindings), -+ cmocka_unit_test_teardown(lb_nomatch_int_max_m1_2_used, teardown_bindings), - #endif - }; - - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+static int rlookup_binding(FILE *dummy, char *buf, const char *alias) { -+ -+ const struct binding *bdg; -+ -+ bdg = get_binding_for_alias(&global_bindings, alias); -+ if (!bdg) { -+ return -1; -+ } -+ strlcpy(buf, bdg->wwid, WWID_SIZE); -+ return 0; -+} -+ - static void rl_empty(void **state) - { - int rc; - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1004,7 +1204,7 @@ static void rl_match_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("MPATHa WWID0\n", 0); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHa", "WWID0")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, 0); -@@ -1017,7 +1217,7 @@ static void rl_nomatch_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("MPATHa WWID0\n", -1); -+ mock_bindings_file("MPATHa WWID0\n"); - expect_condlog(3, NOMATCH_STR("MPATHb")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, -1); -@@ -1030,8 +1230,8 @@ static void rl_malformed_a(void **state) - char buf[WWID_SIZE]; - - buf[0] = '\0'; -- mock_bindings_file("MPATHa \n", -1); -- expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); -+ expect_condlog(1, "invalid line 1 in bindings file, missing WWID\n"); -+ mock_bindings_file("MPATHa \n"); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1049,8 +1249,8 @@ static void rl_overlong_a(void **state) - snprintf(line + sizeof(line) - 2, 2, "\n"); - - buf[0] = '\0'; -- mock_bindings_file(line, -1); - expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); -+ mock_bindings_file(line); - expect_condlog(3, NOMATCH_STR("MPATHa")); - rc = rlookup_binding(NULL, buf, "MPATHa"); - assert_int_equal(rc, -1); -@@ -1065,7 +1265,7 @@ static void rl_match_b(void **state) - buf[0] = '\0'; - mock_bindings_file("MPATHa WWID0\n" - "MPATHz WWID26\n" -- "MPATHb WWID2\n", 2); -+ "MPATHb WWID2\n"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHb", "WWID2")); - rc = rlookup_binding(NULL, buf, "MPATHb"); - assert_int_equal(rc, 0); -@@ -1075,31 +1275,41 @@ static void rl_match_b(void **state) - static int test_rlookup_binding(void) - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(rl_empty), -- cmocka_unit_test(rl_match_a), -- cmocka_unit_test(rl_nomatch_a), -- cmocka_unit_test(rl_malformed_a), -- cmocka_unit_test(rl_overlong_a), -- cmocka_unit_test(rl_match_b), -+ cmocka_unit_test_teardown(rl_empty, teardown_bindings), -+ cmocka_unit_test_teardown(rl_match_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_nomatch_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_malformed_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_overlong_a, teardown_bindings), -+ cmocka_unit_test_teardown(rl_match_b, teardown_bindings), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+void check_bindings_size(int n) -+{ -+ /* avoid -Waddress problem */ -+ Bindings *bindings = &global_bindings; -+ -+ assert_int_equal(VECTOR_SIZE(bindings), n); -+} -+ - static void al_a(void **state) - { - static const char ln[] = "MPATHa WWIDa\n"; - char *alias; - -- will_return(__wrap_lseek, 0); -- expect_value(__wrap_write, count, strlen(ln)); -- expect_string(__wrap_write, buf, ln); -- will_return(__wrap_write, strlen(ln)); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_rename, 0); -+ expect_condlog(1, "updated bindings file foo"); - expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); - -- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); -+ check_bindings_size(1); - free(alias); - } - -@@ -1108,15 +1318,17 @@ static void al_zz(void **state) - static const char ln[] = "MPATHzz WWIDzz\n"; - char *alias; - -- will_return(__wrap_lseek, 0); -- expect_value(__wrap_write, count, strlen(ln)); -- expect_string(__wrap_write, buf, ln); -- will_return(__wrap_write, strlen(ln)); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_rename, 0); -+ expect_condlog(1, "updated bindings file foo"); - expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); - -- alias = allocate_binding(0, "WWIDzz", 26*26 + 26, "MPATH"); -+ alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHzz"); -+ check_bindings_size(1); - free(alias); - } - -@@ -1127,6 +1339,7 @@ static void al_0(void **state) - expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); - alias = allocate_binding(0, "WWIDa", 0, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); - } - - static void al_m2(void **state) -@@ -1136,67 +1349,133 @@ static void al_m2(void **state) - expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); - alias = allocate_binding(0, "WWIDa", -2, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); -+} -+ -+static void al_write_partial(void **state) -+{ -+ static const char ln[] = "MPATHa WWIDa\n"; -+ char *alias; -+ -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); -+ expect_value(__wrap_write, count, 1); -+ will_return(__wrap_write, ln + sizeof(ln) - 2); -+ will_return(__wrap_write, 1); -+ will_return(__wrap_rename, 0); -+ expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); -+ -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ assert_ptr_not_equal(alias, NULL); -+ assert_string_equal(alias, "MPATHa"); -+ check_bindings_size(1); -+ free(alias); - } - --static void al_lseek_err(void **state) -+static void al_write_short(void **state) - { -+ static const char ln[] = "MPATHa WWIDa\n"; - char *alias; - -- will_return(__wrap_lseek, -ENODEV); -- expect_condlog(0, "Cannot seek to end of bindings file : No such device\n"); -- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln) - 1); -+ expect_value(__wrap_write, count, 1); -+ will_return(__wrap_write, ln + sizeof(ln) - 2); -+ will_return(__wrap_write, 0); -+ expect_condlog(2, "write_bindings_file: short write"); -+ expect_condlog(1, "failed to write new bindings file"); -+ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); -+ -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); - } - - static void al_write_err(void **state) - { - static const char ln[] = "MPATHa WWIDa\n"; -- const int offset = 20; - char *alias; - -- will_return(__wrap_lseek, offset); -- expect_value(__wrap_write, count, strlen(ln)); -- expect_string(__wrap_write, buf, ln); -- will_return(__wrap_write, strlen(ln) - 1); -- expect_value(__wrap_ftruncate, length, offset); -- will_return(__wrap_ftruncate, 0); -- expect_condlog(0, "Cannot write binding to bindings file :"); -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, -EPERM); -+ expect_condlog(1, "failed to write new bindings file"); -+ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); - -- alias = allocate_binding(0, "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); -+} -+ -+static void al_rename_err(void **state) -+{ -+ static const char ln[] = "MPATHa WWIDa\n"; -+ char *alias; -+ -+ expect_value(__wrap_write, count, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_write, ln); -+ will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); -+ will_return(__wrap_rename, -EROFS); -+ -+ expect_condlog(0, "update_bindings_file: rename: Read-only file system"); -+ expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); -+ alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ assert_ptr_equal(alias, NULL); -+ check_bindings_size(0); - } - - static int test_allocate_binding(void) - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(al_a), -- cmocka_unit_test(al_zz), -- cmocka_unit_test(al_0), -- cmocka_unit_test(al_m2), -- cmocka_unit_test(al_lseek_err), -- cmocka_unit_test(al_write_err), -+ cmocka_unit_test_teardown(al_a, teardown_bindings), -+ cmocka_unit_test_teardown(al_zz, teardown_bindings), -+ cmocka_unit_test_teardown(al_0, teardown_bindings), -+ cmocka_unit_test_teardown(al_m2, teardown_bindings), -+ cmocka_unit_test_teardown(al_write_partial, teardown_bindings), -+ cmocka_unit_test_teardown(al_write_short, teardown_bindings), -+ cmocka_unit_test_teardown(al_write_err, teardown_bindings), -+ cmocka_unit_test_teardown(al_rename_err, teardown_bindings), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); - } - --#define mock_allocate_binding(alias, wwid) \ -+#define mock_allocate_binding_err_len(alias, wwid, len, err, msg) \ - do { \ - static const char ln[] = BINDING_STR(alias, wwid); \ - \ -- will_return(__wrap_lseek, 0); \ -- expect_value(__wrap_write, count, strlen(ln)); \ -- expect_string(__wrap_write, buf, ln); \ -- will_return(__wrap_write, strlen(ln)); \ -- expect_condlog(3, NEW_STR(alias, wwid)); \ -+ expect_value(__wrap_write, count, \ -+ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ -+ will_return(__wrap_write, ln); \ -+ will_return(__wrap_write, \ -+ strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ -+ will_return(__wrap_rename, err); \ -+ if (err == 0) { \ -+ expect_condlog(1, "updated bindings file x\n"); \ -+ expect_condlog(3, NEW_STR(alias, wwid)); \ -+ } else { \ -+ expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ -+ expect_condlog(1, "allocate_binding: deleting binding " \ -+ alias " for " wwid "\n"); \ -+ } \ - } while (0) - -+#define mock_allocate_binding_err(alias, wwid, err, msg) \ -+ mock_allocate_binding_err_len(alias, wwid, 0, err, msg) -+ -+#define mock_allocate_binding(alias, wwid) \ -+ mock_allocate_binding_err(alias, wwid, 0, "") -+ -+#define mock_allocate_binding_len(alias, wwid, len) \ -+ mock_allocate_binding_err_len(alias, wwid, len, 0, "") -+ - static void gufa_empty_new_rw(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -@@ -1208,10 +1487,11 @@ static void gufa_empty_new_rw(void **state) { - - static void gufa_empty_new_ro_1(void **state) { - char *alias; -- will_return(__wrap_open_file, false); -- mock_bindings_file("", -1); -+ -+ mock_bindings_file(""); - mock_unused_alias("MPATHa"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); - assert_ptr_equal(alias, NULL); -@@ -1220,11 +1500,9 @@ static void gufa_empty_new_ro_1(void **state) { - static void gufa_empty_new_ro_2(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("", -1); -- mock_unused_alias("MPATHa"); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHa"); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_ptr_equal(alias, NULL); -@@ -1233,11 +1511,10 @@ static void gufa_empty_new_ro_2(void **state) { - static void gufa_match_a_unused(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("MPATHa WWID0", 0); -+ mock_bindings_file("MPATHa WWID0"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHa"); -+ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); -@@ -1247,11 +1524,10 @@ static void gufa_match_a_unused(void **state) { - static void gufa_match_a_self(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file("MPATHa WWID0", 0); -+ mock_bindings_file("MPATHa WWID0"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_self_alias("MPATHa", "WWID0"); -+ expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); -@@ -1261,9 +1537,8 @@ static void gufa_match_a_self(void **state) { - static void gufa_match_a_used(void **state) { - char *alias; - -- will_return(__wrap_open_file, true); - -- mock_bindings_file("MPATHa WWID0", 0); -+ mock_bindings_file("MPATHa WWID0"); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -@@ -1273,15 +1548,14 @@ static void gufa_match_a_used(void **state) { - - static void gufa_nomatch_a_c(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ static const char bindings[] = ("MPATHa WWID0\n" -+ "MPATHc WWID2\n"); - -- mock_bindings_file("MPATHa WWID0\n" -- "MPATHc WWID2", -- -1); -+ mock_bindings_file(bindings); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - -- mock_allocate_binding("MPATHb", "WWID1"); -+ mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); - - alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); -@@ -1290,15 +1564,14 @@ static void gufa_nomatch_a_c(void **state) { - - static void gufa_nomatch_c_a(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHc WWID2\n" -+ "MPATHa WWID0\n"); - -- mock_bindings_file("MPATHc WWID2\n" -- "MPATHa WWID0", -- -1); -+ mock_bindings_file(bindings); - mock_unused_alias("MPATHb"); - expect_condlog(3, NOMATCH_WWID_STR("WWID1")); - -- mock_allocate_binding("MPATHb", "WWID1"); -+ mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); -@@ -1307,15 +1580,14 @@ static void gufa_nomatch_c_a(void **state) { - - static void gufa_nomatch_c_b(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHc WWID2\n" -+ "MPATHb WWID1\n"); - -- mock_bindings_file("MPATHc WWID2\n" -- "MPATHb WWID1\n", -- -1); -- mock_unused_alias("MPATHa"); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_unused_alias("MPATHa"); - -- mock_allocate_binding("MPATHa", "WWID0"); -+ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHa"); -@@ -1324,16 +1596,15 @@ static void gufa_nomatch_c_b(void **state) { - - static void gufa_nomatch_c_b_used(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHc WWID2\n" -+ "MPATHb WWID1\n"); - -- mock_bindings_file("MPATHc WWID2\n" -- "MPATHb WWID1", -- -1); -- mock_used_alias("MPATHa", "WWID4"); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID4")); -+ mock_used_alias("MPATHa", "WWID4"); - mock_unused_alias("MPATHd"); - -- mock_allocate_binding("MPATHd", "WWID4"); -+ mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHd"); -@@ -1342,32 +1613,59 @@ static void gufa_nomatch_c_b_used(void **state) { - - static void gufa_nomatch_b_f_a(void **state) { - char *alias; -- will_return(__wrap_open_file, true); -+ const char bindings[] = ("MPATHb WWID1\n" -+ "MPATHf WWID6\n" -+ "MPATHa WWID0\n"); - -- mock_bindings_file("MPATHb WWID1\n" -- "MPATHf WWID6\n" -- "MPATHa WWID0\n", -- -1); -+ mock_bindings_file_unsorted(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID7")); - mock_unused_alias("MPATHg"); - -- mock_allocate_binding("MPATHg", "WWID7"); -+ mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); - assert_string_equal(alias, "MPATHg"); - free(alias); - } - -+static void gufa_nomatch_b_aa_a(void **state) { -+ char *alias; -+ STRBUF_ON_STACK(buf); -+ -+ fill_bindings(&buf, 0, 26); -+ mock_bindings_file(get_strbuf_str(&buf)); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID28")); -+ mock_unused_alias("MPATHab"); -+ mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); -+ -+ alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHab"); -+ free(alias); -+} -+ -+static void gufa_nomatch_b_f_a_sorted(void **state) { -+ char *alias; -+ const char bindings[] = ("MPATHb WWID1\n" -+ "MPATHf WWID6\n" -+ "MPATHa WWID0\n"); -+ -+ mock_bindings_file(bindings); -+ expect_condlog(3, NOMATCH_WWID_STR("WWID7")); -+ mock_unused_alias("MPATHc"); -+ -+ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); -+ -+ alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ assert_string_equal(alias, "MPATHc"); -+ free(alias); -+} -+ - static void gufa_old_empty(void **state) { - char *alias; -- will_return(__wrap_open_file, true); - - /* rlookup_binding for ALIAS */ -- mock_bindings_file("", -1); -+ mock_bindings_file(""); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- /* lookup_binding */ -- mock_bindings_file("", -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - - mock_allocate_binding("MPATHz", "WWID0"); -@@ -1380,11 +1678,9 @@ static void gufa_old_empty(void **state) { - - static void gufa_old_match(void **state) { - char *alias; -- will_return(__wrap_open_file, true); - - mock_bindings_file("MPATHb WWID1\n" -- "MPATHz WWID0", -- 1); -+ "MPATHz WWID0"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -@@ -1394,19 +1690,15 @@ static void gufa_old_match(void **state) { - - static void gufa_old_match_other(void **state) { - char *alias; -- static const char bindings[] = "MPATHz WWID9"; -- -- will_return(__wrap_open_file, true); -+ static const char bindings[] = "MPATHz WWID9\n"; - -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_unused_alias("MPATHa"); - -- mock_allocate_binding("MPATHa", "WWID0"); -+ mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHa"); -@@ -1415,21 +1707,16 @@ static void gufa_old_match_other(void **state) { - - static void gufa_old_match_other_used(void **state) { - char *alias; -- static const char bindings[] = "MPATHz WWID9"; -+ static const char bindings[] = "MPATHz WWID9\n"; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, -1); -- mock_used_alias("MPATHa", "WWID0"); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); -+ mock_used_alias("MPATHa", "WWID0"); - mock_unused_alias("MPATHb"); - -- mock_allocate_binding("MPATHb", "WWID0"); -- -+ mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); -@@ -1439,15 +1726,13 @@ static void gufa_old_match_other_wwidmatch(void **state) { - char *alias; - static const char bindings[] = ("MPATHz WWID9\n" - "MPATHc WWID2"); -- will_return(__wrap_open_file, true); - -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); - mock_unused_alias("MPATHc"); -+ expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); - - alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHc"); -@@ -1459,13 +1744,9 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { - static const char bindings[] = ("MPATHz WWID9\n" - "MPATHc WWID2"); - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file(bindings, 0); -+ mock_bindings_file(bindings); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID9")); - expect_condlog(0, REUSE_STR("MPATHz", "WWID9")); -- -- mock_bindings_file(bindings, 1); - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); - mock_used_alias("MPATHc", "WWID2"); - -@@ -1477,12 +1758,8 @@ static void gufa_old_nomatch_wwidmatch(void **state) { - char *alias; - static const char bindings[] = "MPATHa WWID0"; - -- will_return(__wrap_open_file, true); -- -- mock_bindings_file(bindings, -1); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- mock_bindings_file(bindings, 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_unused_alias("MPATHa"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); -@@ -1495,12 +1772,9 @@ static void gufa_old_nomatch_wwidmatch(void **state) { - static void gufa_old_nomatch_wwidmatch_used(void **state) { - char *alias; - static const char bindings[] = "MPATHa WWID0"; -- will_return(__wrap_open_file, true); - -- mock_bindings_file(bindings, -1); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- mock_bindings_file(bindings, 0); - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -@@ -1510,17 +1784,13 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { - - static void gufa_old_nomatch_nowwidmatch(void **state) { - char *alias; -- static const char bindings[] = "MPATHb WWID1"; -- -- will_return(__wrap_open_file, true); -+ static const char bindings[] = "MPATHb WWID1\n"; - -- mock_bindings_file(bindings, -1); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_STR("MPATHz")); -- -- mock_bindings_file(bindings, -1); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - -- mock_allocate_binding("MPATHz", "WWID0"); -+ mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); - expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); - - alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -@@ -1531,26 +1801,28 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { - static int test_get_user_friendly_alias() - { - const struct CMUnitTest tests[] = { -- cmocka_unit_test(gufa_empty_new_rw), -- cmocka_unit_test(gufa_empty_new_ro_1), -- cmocka_unit_test(gufa_empty_new_ro_2), -- cmocka_unit_test(gufa_match_a_unused), -- cmocka_unit_test(gufa_match_a_self), -- cmocka_unit_test(gufa_match_a_used), -- cmocka_unit_test(gufa_nomatch_a_c), -- cmocka_unit_test(gufa_nomatch_c_a), -- cmocka_unit_test(gufa_nomatch_c_b), -- cmocka_unit_test(gufa_nomatch_c_b_used), -- cmocka_unit_test(gufa_nomatch_b_f_a), -- cmocka_unit_test(gufa_old_empty), -- cmocka_unit_test(gufa_old_match), -- cmocka_unit_test(gufa_old_match_other), -- cmocka_unit_test(gufa_old_match_other_used), -- cmocka_unit_test(gufa_old_match_other_wwidmatch), -- cmocka_unit_test(gufa_old_match_other_wwidmatch_used), -- cmocka_unit_test(gufa_old_nomatch_wwidmatch), -- cmocka_unit_test(gufa_old_nomatch_wwidmatch_used), -- cmocka_unit_test(gufa_old_nomatch_nowwidmatch), -+ cmocka_unit_test_teardown(gufa_empty_new_rw, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_empty_new_ro_1, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_empty_new_ro_2, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_match_a_unused, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_match_a_self, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_match_a_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_a_c, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_c_a, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_c_b, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_c_b_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_b_f_a, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_b_aa_a, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_nomatch_b_f_a_sorted, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_empty, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_match_other_wwidmatch_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), -+ cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -@@ -1566,7 +1838,6 @@ int main(void) - ret += test_lookup_binding(); - ret += test_rlookup_binding(); - ret += test_allocate_binding(); -- ret += test_allocate_binding(); - ret += test_get_user_friendly_alias(); - - return ret; diff --git a/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch b/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch deleted file mode 100644 index c105b01..0000000 --- a/0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 25 Aug 2023 20:35:19 +0200 -Subject: [PATCH] libmultipath: dm_get_uuid(): return emtpy UUID for - non-existing maps - -libdevmapper will most probably not return a UUID for non-existing -maps anyway. But it's cheap to double-check here. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 248c3734..9be82f4e 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -706,12 +706,16 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) - { - struct dm_task *dmt; - const char *uuidtmp; -+ struct dm_info info; - int r = 1; - - dmt = libmp_dm_task_create(DM_DEVICE_INFO); - if (!dmt) - return 1; - -+ if (uuid_len > 0) -+ uuid[0] = '\0'; -+ - if (!dm_task_set_name (dmt, name)) - goto uuidout; - -@@ -720,11 +724,13 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len) - goto uuidout; - } - -+ if (!dm_task_get_info(dmt, &info) || -+ !info.exists) -+ goto uuidout; -+ - uuidtmp = dm_task_get_uuid(dmt); - if (uuidtmp) - strlcpy(uuid, uuidtmp, uuid_len); -- else -- uuid[0] = '\0'; - - r = 0; - uuidout: diff --git a/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch b/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch deleted file mode 100644 index 4d15554..0000000 --- a/0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 28 Aug 2023 12:26:37 +0200 -Subject: [PATCH] libmultipath: adapt to new semantics of dm_get_uuid() - -dm_get_uuid() will return 1 for non-existing maps. Thus we don't need -to call dm_map_present() any more in alias_already_taken(). This changes -our semantics: previously we'd avoid using an alias for which dm_get_uuid() -had failed. Now we treat failure in dm_get_uuid() as indication that the -map doesn't exist. This is not dangerous because dm_task_get_uuid() cannot -fail, and thus the modified dm_get_uuid() will fail if and only if -dm_map_present() would return false. - -This makes the "failed alias" test mostly obsolete, as "failed" is now -treated as "unused". - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 25 +++++++++++++------------ - tests/alias.c | 32 +++++++------------------------- - 2 files changed, 20 insertions(+), 37 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index d6563749..58436ec0 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -295,18 +295,19 @@ scan_devname(const char *alias, const char *prefix) - static bool alias_already_taken(const char *alias, const char *map_wwid) - { - -- if (dm_map_present(alias)) { -- char wwid[WWID_SIZE]; -- -- /* If both the name and the wwid match, then it's fine.*/ -- if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && -- strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -- return false; -- condlog(3, "%s: alias '%s' already taken, reselecting alias", -- map_wwid, alias); -- return true; -- } -- return false; -+ char wwid[WWID_SIZE]; -+ -+ /* If the map doesn't exist, it's fine */ -+ if (dm_get_uuid(alias, wwid, sizeof(wwid)) != 0) -+ return false; -+ -+ /* If both the name and the wwid match, it's fine.*/ -+ if (strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -+ return false; -+ -+ condlog(3, "%s: alias '%s' already taken, reselecting alias", -+ map_wwid, alias); -+ return true; - } - - static bool id_already_taken(int id, const char *prefix, const char *map_wwid) -diff --git a/tests/alias.c b/tests/alias.c -index 50a21ecf..d1cc487b 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -73,12 +73,6 @@ int __wrap_mkstemp(char *template) - return 10; - } - --int __wrap_dm_map_present(const char * str) --{ -- check_expected(str); -- return mock_type(int); --} -- - int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - { - int ret; -@@ -398,14 +392,13 @@ static int test_scan_devname(void) - - static void mock_unused_alias(const char *alias) - { -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 0); -+ expect_string(__wrap_dm_get_uuid, name, alias); -+ expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); -+ will_return(__wrap_dm_get_uuid, 1); - } - - static void mock_self_alias(const char *alias, const char *wwid) - { -- expect_string(__wrap_dm_map_present, str, alias); -- will_return(__wrap_dm_map_present, 1); - expect_string(__wrap_dm_get_uuid, name, alias); - expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); - will_return(__wrap_dm_get_uuid, 0); -@@ -432,18 +425,13 @@ static void mock_self_alias(const char *alias, const char *wwid) - - #define mock_failed_alias(alias, wwid) \ - do { \ -- expect_string(__wrap_dm_map_present, str, alias); \ -- will_return(__wrap_dm_map_present, 1); \ - expect_string(__wrap_dm_get_uuid, name, alias); \ - expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ - will_return(__wrap_dm_get_uuid, 1); \ -- expect_condlog(3, USED_STR(alias, wwid)); \ - } while (0) - - #define mock_used_alias(alias, wwid) \ - do { \ -- expect_string(__wrap_dm_map_present, str, alias); \ -- will_return(__wrap_dm_map_present, 1); \ - expect_string(__wrap_dm_get_uuid, name, alias); \ - expect_value(__wrap_dm_get_uuid, uuid_len, WWID_SIZE); \ - will_return(__wrap_dm_get_uuid, 0); \ -@@ -566,9 +554,8 @@ static void lb_empty_failed(void **state) - mock_bindings_file(""); - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_failed_alias("MPATHa", "WWID0"); -- mock_unused_alias("MPATHb"); - rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 1); -- assert_int_equal(rc, 2); -+ assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); - free(alias); - } -@@ -666,9 +653,8 @@ static void lb_nomatch_a_3_used_failed_self(void **state) - mock_used_alias("MPATHc", "WWID1"); - mock_used_alias("MPATHd", "WWID1"); - mock_failed_alias("MPATHe", "WWID1"); -- mock_self_alias("MPATHf", "WWID1"); - rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 1); -- assert_int_equal(rc, 6); -+ assert_int_equal(rc, 5); - assert_ptr_equal(alias, NULL); - } - -@@ -940,7 +926,7 @@ static void lb_nomatch_b_a_aa(void **state) - - static void lb_nomatch_b_a_aa_zz(void **state) - { -- int rc, i; -+ int rc; - char *alias; - STRBUF_ON_STACK(buf); - -@@ -949,11 +935,7 @@ static void lb_nomatch_b_a_aa_zz(void **state) - * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is - * found before MPATHb, and MPATHzz was in the bindings, too. - */ -- for (i = 0; i <= 26; i++) { -- print_strbuf(&buf, "MPATH"); -- format_devname(&buf, i + 1); -- print_strbuf(&buf, " WWID%d\n", i); -- } -+ fill_bindings(&buf, 0, 26); - print_strbuf(&buf, "MPATHzz WWID676\n"); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWID703")); diff --git a/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch b/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch deleted file mode 100644 index 1504bec..0000000 --- a/0022-libmultipath-sort-aliases-by-length-and-strcmp.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 15:19:54 +0200 -Subject: [PATCH] libmultipath: sort aliases by length and strcmp - -The current sort order of aliases is alphabetical, which is does not match -the actual order of aliases, where "mpathaa" > "mpathz". Change the ordering as -follows: first sort by string length, then alphabetically. This will make -sure that for aliases with the same prefix, alias order is correct ("mpathaaa" -will be sorted after "mpathzz", etc). Even for mixed prefixes, the alias -order will be correct for every individual prefix, even though aliases with -different prefixes may alternate in the file. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 45 +++++++++++++++++++++++++++++++++----------- - 1 file changed, 34 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 58436ec0..af6565b1 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -117,6 +117,35 @@ static const struct binding *get_binding_for_wwid(const Bindings *bindings, - return NULL; - } - -+/* -+ * Sort order for aliases. -+ * -+ * The "numeric" ordering of aliases for a given prefix P is -+ * Pa, ..., Pz, Paa, ..., Paz, Pba, ... , Pzz, Paaa, ..., Pzzz, Paaaa, ... -+ * We use the fact that for equal prefix, longer strings are always -+ * higher than shorter ones. Strings of equal length are sorted alphabetically. -+ * This is achieved by sorting be length first, then using strcmp(). -+ * If multiple prefixes are in use, the aliases with a given prefix will -+ * not necessarily be in a contiguous range of the vector, but they will -+ * be ordered such that for a given prefix, numercally higher aliases will -+ * always be sorted after lower ones. -+ */ -+static int alias_compar(const void *p1, const void *p2) -+{ -+ const char *alias1 = *((char * const *)p1); -+ const char *alias2 = *((char * const *)p2); -+ -+ if (alias1 && alias2) { -+ ssize_t ldif = strlen(alias1) - strlen(alias2); -+ -+ if (ldif) -+ return ldif; -+ return strcmp(alias1, alias2); -+ } else -+ /* Move NULL alias to the end */ -+ return alias1 ? -1 : alias2 ? 1 : 0; -+} -+ - static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - { - struct binding *bdg; -@@ -128,7 +157,7 @@ static int add_binding(Bindings *bindings, const char *alias, const char *wwid) - * sorted already. - */ - vector_foreach_slot_backwards(bindings, bdg, i) { -- if ((cmp = strcmp(bdg->alias, alias)) <= 0) -+ if ((cmp = alias_compar(&bdg->alias, &alias)) <= 0) - break; - } - -@@ -657,16 +686,10 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - return rc; - } - --static int alias_compar(const void *p1, const void *p2) -+static int mp_alias_compar(const void *p1, const void *p2) - { -- const char *alias1 = (*(struct mpentry * const *)p1)->alias; -- const char *alias2 = (*(struct mpentry * const *)p2)->alias; -- -- if (alias1 && alias2) -- return strcmp(alias1, alias2); -- else -- /* Move NULL alias to the end */ -- return alias1 ? -1 : alias2 ? 1 : 0; -+ return alias_compar(&((*(struct mpentry * const *)p1)->alias), -+ &((*(struct mpentry * const *)p2)->alias)); - } - - /* -@@ -700,7 +723,7 @@ int check_alias_settings(const struct config *conf) - pthread_cleanup_push_cast(free_bindings, &bindings); - pthread_cleanup_push(cleanup_vector_free, mptable); - -- vector_sort(mptable, alias_compar); -+ vector_sort(mptable, mp_alias_compar); - vector_foreach_slot(mptable, mpe, i) { - if (!mpe->alias) - /* diff --git a/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch b/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch deleted file mode 100644 index dd0f29d..0000000 --- a/0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 15:46:02 +0200 -Subject: [PATCH] multipath-tools tests: fix alias test after sort order change - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 30 ++++++++++++------------------ - 1 file changed, 12 insertions(+), 18 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index d1cc487b..8ed95d7a 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -932,16 +932,15 @@ static void lb_nomatch_b_a_aa_zz(void **state) - - /* - * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -- * lookup_binding finds MPATHaaa as next free entry, because MPATHaa is -- * found before MPATHb, and MPATHzz was in the bindings, too. -+ * lookup_binding finds MPATHab as next free entry. - */ - fill_bindings(&buf, 0, 26); - print_strbuf(&buf, "MPATHzz WWID676\n"); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWID703")); -- mock_unused_alias("MPATHaaa"); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWID703", &alias, "MPATH", 1); -- assert_int_equal(rc, 703); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -998,13 +997,8 @@ static void lb_nomatch_b_a_3_used(void **state) - - #ifdef MPATH_ID_INT_MAX - /* -- * The bindings will be sorted by alias, alphabetically, which is not -- * the same as the "numeric" sort order for user-friendly aliases. -- * get_free_id() selects the highest used ID + 1 if an unsorted entry -- * is encountered in the bindings table and it's id is equal to the -- * next "expected" id. This happens if all IDs from "a" to "aa" are -- * in the table. If the INT_MAX entry is in the table, too, it will -- * overflow. -+ * The bindings will be sorted by alias. Therefore we have no chance to -+ * simulate a "full" table. - */ - static void lb_nomatch_int_max(void **state) - { -@@ -1016,9 +1010,9 @@ static void lb_nomatch_int_max(void **state) - print_strbuf(&buf, "MPATH%s WWIDMAX\n", MPATH_ID_INT_MAX); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); -- expect_condlog(0, NOMORE_STR); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1049,9 +1043,9 @@ static void lb_nomatch_int_max_m1(void **state) - print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, INT_MAX); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1065,10 +1059,10 @@ static void lb_nomatch_int_max_m1_used(void **state) - print_strbuf(&buf, "MPATH%s WWIDMAXM1\n", MPATH_ID_INT_MAX_m1); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); -- expect_condlog(0, NOMORE_STR); -+ mock_used_alias("MPATHab", "WWIDMAX"); -+ mock_unused_alias("MPATHac"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 29); - assert_ptr_equal(alias, NULL); - } - diff --git a/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch b/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch deleted file mode 100644 index b16b3da..0000000 --- a/0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 19:50:51 +0200 -Subject: [PATCH] libmultipath: simplify get_free_id() assuming total ordering - -If we can assume that the bindings array is totally ordered for every -prefix, which the previous patch guarantees, the search for a free ID can be -simplified. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 85 ++++++++++---------------------------------- - 1 file changed, 18 insertions(+), 67 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index af6565b1..66e34e31 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -356,83 +356,34 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww - { - const struct binding *bdg; - int i, id = 1; -- int biggest_id = 1; -- int smallest_bigger_id = INT_MAX; - - vector_foreach_slot(bindings, bdg, i) { - int curr_id = scan_devname(bdg->alias, prefix); - -- /* -- * Find an unused index - explanation of the algorithm -- * -- * ID: 1 = mpatha, 2 = mpathb, ... -- * -- * We assume the bindings are unsorted. The only constraint -- * is that no ID occurs more than once. IDs that occur in the -- * bindings are called "used". -- * -- * We call the list 1,2,3,..., exactly in this order, the list -- * of "expected" IDs. The variable "id" always holds the next -- * "expected" ID, IOW the last "expected" ID encountered plus 1. -- * Thus all IDs below "id" are known to be used. However, at the -- * end of the loop, the value of "id" isn't necessarily unused. -- * -- * "smallest_bigger_id" is the smallest used ID that was -- * encountered while it was larger than the next "expected" ID -- * at that iteration. Let X be some used ID. If all IDs below X -- * are used and encountered in the right sequence before X, "id" -- * will be > X when the loop ends. Otherwise, X was encountered -- * "out of order", the condition (X > id) holds when X is -- * encountered, and "smallest_bigger_id" will be set to X; i.e. -- * it will be less or equal than X when the loop ends. -- * -- * At the end of the loop, (id < smallest_bigger_id) means that -- * the value of "id" had been encountered neither in order nor -- * out of order, and is thus unused. (id >= smallest_bigger_id) -- * means that "id"'s value is in use. In this case, we play safe -- * and use "biggest_id + 1" as the next value to try. -- * -- * biggest_id is always > smallest_bigger_id, except in the -- * "perfectly ordered" case. -- */ -- if (curr_id == id) { -- if (id < INT_MAX) -- id++; -- else { -- id = -1; -- break; -- } -+ if (curr_id == -1) -+ continue; -+ if (id > curr_id) { -+ condlog(0, "%s: ERROR: bindings are not sorted", __func__); -+ return -1; - } -- if (curr_id > biggest_id) -- biggest_id = curr_id; -- -- if (curr_id > id && curr_id < smallest_bigger_id) -- smallest_bigger_id = curr_id; -+ while (id < curr_id && id_already_taken(id, prefix, map_wwid)) -+ id++; -+ if (id < curr_id) -+ return id; -+ id++; -+ if (id <= 0) -+ break; - } - -- if (id >= smallest_bigger_id) -- id = biggest_id < INT_MAX ? biggest_id + 1 : -1; -- -- if (id > 0) { -- while(id_already_taken(id, prefix, map_wwid)) { -- if (id == INT_MAX) { -- id = -1; -- break; -- } -- id++; -- if (id == smallest_bigger_id) { -- if (biggest_id == INT_MAX) { -- id = -1; -- break; -- } -- if (biggest_id >= smallest_bigger_id) -- id = biggest_id + 1; -- } -- } -+ for (; id > 0; id++) { -+ if (!id_already_taken(id, prefix, map_wwid)) -+ break; - } - -- if (id < 0) -+ if (id <= 0) { -+ id = -1; - condlog(0, "no more available user_friendly_names"); -+ } - return id; - } - diff --git a/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch b/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch deleted file mode 100644 index b1d6b15..0000000 --- a/0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 19:58:03 +0200 -Subject: [PATCH] multipath-tools tests: adapt alias tests for total ordering - -The "unsorted" test fail now, and are removed. The algorithm is now -better at finding "gaps". - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 88 ++++++++------------------------------------------- - 1 file changed, 14 insertions(+), 74 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index 8ed95d7a..dff5f93b 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -439,27 +439,7 @@ static void mock_self_alias(const char *alias, const char *wwid) - expect_condlog(3, USED_STR(alias, wwid)); \ - } while(0) - --static int add_binding_unsorted(Bindings *bindings, -- const char *alias, const char *wwid) --{ -- struct binding *bdg = calloc(1, sizeof(*bdg)); -- -- if (!bdg) -- return -1; -- bdg->wwid = strdup(wwid); -- bdg->alias = strdup(alias); -- if (!bdg->wwid || !bdg->alias || !vector_alloc_slot(bindings)) { -- free(bdg->alias); -- free(bdg->wwid); -- free(bdg); -- return BINDING_ERROR; -- } -- vector_set_slot(bindings, bdg); -- return BINDING_ADDED; --} -- --static void __mock_bindings_file(const char *content, -- int (*add)(Bindings *, const char *, const char *)) -+static void __mock_bindings_file(const char *content) - { - char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; - char *token, *savep = NULL; -@@ -478,17 +458,13 @@ static void __mock_bindings_file(const char *content, - == READ_BINDING_SKIP) - continue; - -- rc = add(&global_bindings, alias, wwid); -+ rc = add_binding(&global_bindings, alias, wwid); - assert_int_equal(rc, BINDING_ADDED); - } - } - - static void mock_bindings_file(const char *content) { -- return __mock_bindings_file(content, add_binding); --} -- --static void mock_bindings_file_unsorted(const char *content) { -- return __mock_bindings_file(content, add_binding_unsorted); -+ return __mock_bindings_file(content); - } - - static int teardown_bindings(void **state) -@@ -861,10 +837,6 @@ static void lb_nomatch_b_z_a(void **state) - int rc; - char *alias; - -- /* -- * add_bindings() sorts alphabetically. Therefore get_free_id() -- * finds MPATHc as a free entry. -- */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" - "MPATHa WWID0\n"); -@@ -880,10 +852,6 @@ static void lb_nomatch_b_aa_a(void **state) - int rc; - char *alias; - -- /* -- * add_bindings() sorts alphabetically. ("a", "aa", b"). -- * The get_free_id() algorithm finds the "hole" after "b". -- */ - mock_bindings_file("MPATHb WWID1\n" - "MPATHz WWID26\n" - "MPATHa WWID0\n"); -@@ -911,10 +879,6 @@ static void lb_nomatch_b_a_aa(void **state) - char *alias; - STRBUF_ON_STACK(buf); - -- /* -- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -- * lookup_binding finds MPATHac as next free entry. -- */ - fill_bindings(&buf, 0, 26); - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWID28")); -@@ -930,10 +894,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) - char *alias; - STRBUF_ON_STACK(buf); - -- /* -- * add_bindings() sorts alphabetically. ("a", "aa", "ab", "b", "c", ...) -- * lookup_binding finds MPATHab as next free entry. -- */ - fill_bindings(&buf, 0, 26); - print_strbuf(&buf, "MPATHzz WWID676\n"); - mock_bindings_file(get_strbuf_str(&buf)); -@@ -944,25 +904,6 @@ static void lb_nomatch_b_a_aa_zz(void **state) - assert_ptr_equal(alias, NULL); - } - --static void lb_nomatch_b_z_a_unsorted(void **state) --{ -- int rc; -- char *alias; -- -- /* -- * With unsorted bindings (shouldn't happen normally), get_free_id() -- * plays safe and returns MPATHaa as first free entry. -- */ -- mock_bindings_file_unsorted("MPATHb WWID1\n" -- "MPATHz WWID26\n" -- "MPATHa WWID0\n"); -- expect_condlog(3, NOMATCH_WWID_STR("WWID2")); -- mock_unused_alias("MPATHaa"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 1); -- assert_int_equal(rc, 27); -- assert_ptr_equal(alias, NULL); --} -- - static void lb_nomatch_b_a(void **state) - { - int rc; -@@ -1027,9 +968,9 @@ static void lb_nomatch_int_max_used(void **state) - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDNOMORE")); - mock_used_alias("MPATHa", "WWIDNOMORE"); -- expect_condlog(0, NOMORE_STR); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDNOMORE", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1077,9 +1018,9 @@ static void lb_nomatch_int_max_m1_1_used(void **state) - mock_bindings_file(get_strbuf_str(&buf)); - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); - mock_used_alias("MPATHa", "WWIDMAX"); -- mock_unused_alias("MPATH" MPATH_ID_INT_MAX); -+ mock_unused_alias("MPATHab"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, INT_MAX); -+ assert_int_equal(rc, 28); - assert_ptr_equal(alias, NULL); - } - -@@ -1095,10 +1036,10 @@ static void lb_nomatch_int_max_m1_2_used(void **state) - - expect_condlog(3, NOMATCH_WWID_STR("WWIDMAX")); - mock_used_alias("MPATHa", "WWIDMAX"); -- mock_used_alias("MPATH" MPATH_ID_INT_MAX, "WWIDMAX"); -- expect_condlog(0, NOMORE_STR); -+ mock_used_alias("MPATHab", "WWIDMAX"); -+ mock_unused_alias("MPATHac"); - rc = lookup_binding(NULL, "WWIDMAX", &alias, "MPATH", 1); -- assert_int_equal(rc, -1); -+ assert_int_equal(rc, 29); - assert_ptr_equal(alias, NULL); - } - #endif -@@ -1133,7 +1074,6 @@ static int test_lookup_binding(void) - cmocka_unit_test_teardown(lb_nomatch_b_aa_a, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a_aa, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a_aa_zz, teardown_bindings), -- cmocka_unit_test_teardown(lb_nomatch_b_z_a_unsorted, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a, teardown_bindings), - cmocka_unit_test_teardown(lb_nomatch_b_a_3_used, teardown_bindings), - #ifdef MPATH_ID_INT_MAX -@@ -1593,14 +1533,14 @@ static void gufa_nomatch_b_f_a(void **state) { - "MPATHf WWID6\n" - "MPATHa WWID0\n"); - -- mock_bindings_file_unsorted(bindings); -+ mock_bindings_file(bindings); - expect_condlog(3, NOMATCH_WWID_STR("WWID7")); -- mock_unused_alias("MPATHg"); -+ mock_unused_alias("MPATHc"); - -- mock_allocate_binding_len("MPATHg", "WWID7", sizeof(bindings) - 1); -+ mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); - - alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -- assert_string_equal(alias, "MPATHg"); -+ assert_string_equal(alias, "MPATHc"); - free(alias); - } - diff --git a/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch b/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch deleted file mode 100644 index 5317ef9..0000000 --- a/0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 21:39:44 +0200 -Subject: [PATCH] multipath-tools tests: add test for ordering of bindings - -As the assignment of free aliases now relies on the bindings being -properly sorted, add some unit tests to make sure the sorting algorithm -works. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/alias.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 209 insertions(+), 3 deletions(-) - -diff --git a/tests/alias.c b/tests/alias.c -index dff5f93b..7f3ff38a 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -13,6 +13,9 @@ - #include "globals.c" - #include "../libmultipath/alias.c" - -+/* For verbose printing of all aliases in the ordering tests */ -+#define ALIAS_DEBUG 0 -+ - #if INT_MAX == 0x7fffffff - /* user_friendly_name for map #INT_MAX */ - #define MPATH_ID_INT_MAX "fxshrxw" -@@ -439,11 +442,12 @@ static void mock_self_alias(const char *alias, const char *wwid) - expect_condlog(3, USED_STR(alias, wwid)); \ - } while(0) - --static void __mock_bindings_file(const char *content) -+static void __mock_bindings_file(const char *content, bool conflict_ok) - { - char *cnt __attribute__((cleanup(cleanup_charp))) = NULL; - char *token, *savep = NULL; - int i; -+ uintmax_t values[] = { BINDING_ADDED, BINDING_CONFLICT }; - - cnt = strdup(content); - assert_ptr_not_equal(cnt, NULL); -@@ -459,12 +463,12 @@ static void __mock_bindings_file(const char *content) - continue; - - rc = add_binding(&global_bindings, alias, wwid); -- assert_int_equal(rc, BINDING_ADDED); -+ assert_in_set(rc, values, conflict_ok ? 2 : 1); - } - } - - static void mock_bindings_file(const char *content) { -- return __mock_bindings_file(content); -+ return __mock_bindings_file(content, false); - } - - static int teardown_bindings(void **state) -@@ -1744,6 +1748,207 @@ static int test_get_user_friendly_alias() - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+/* Numbers 1-1000, randomly shuffled */ -+static const int random_numbers[1000] = { -+ 694, 977, 224, 178, 841, 818, 914, 549, 831, 942, 263, 834, 919, 800, -+ 111, 517, 719, 297, 988, 98, 332, 516, 754, 772, 495, 488, 331, 529, -+ 142, 747, 848, 618, 375, 624, 74, 753, 782, 944, 623, 468, 862, 997, -+ 417, 258, 298, 774, 673, 904, 883, 766, 867, 400, 11, 950, 14, 784, -+ 655, 155, 396, 9, 743, 93, 651, 245, 968, 306, 785, 581, 880, 486, -+ 168, 631, 203, 4, 663, 294, 702, 762, 619, 684, 48, 181, 21, 443, 643, -+ 863, 1000, 327, 26, 126, 382, 765, 586, 76, 49, 925, 319, 865, 797, -+ 876, 693, 334, 433, 243, 419, 901, 854, 326, 985, 347, 874, 527, 282, -+ 290, 380, 167, 95, 3, 257, 936, 60, 426, 227, 345, 577, 492, 467, 580, -+ 967, 422, 823, 718, 610, 64, 700, 412, 163, 288, 506, 828, 432, 51, -+ 356, 348, 539, 478, 17, 945, 602, 123, 450, 660, 429, 113, 310, 358, -+ 512, 758, 508, 19, 542, 304, 286, 446, 918, 723, 333, 603, 731, 978, -+ 230, 697, 109, 872, 175, 853, 947, 965, 121, 222, 101, 811, 117, 601, -+ 191, 752, 384, 415, 938, 278, 915, 715, 240, 552, 912, 838, 150, 840, -+ 627, 29, 636, 464, 861, 481, 992, 249, 934, 82, 368, 724, 807, 593, -+ 157, 147, 199, 637, 41, 62, 902, 505, 621, 342, 174, 260, 729, 961, -+ 219, 311, 629, 789, 81, 739, 860, 712, 223, 165, 741, 981, 485, 363, -+ 346, 709, 125, 369, 279, 634, 399, 162, 193, 769, 149, 314, 868, 612, -+ 524, 675, 341, 343, 476, 606, 388, 613, 850, 264, 903, 451, 908, 779, -+ 453, 148, 497, 46, 132, 43, 885, 955, 269, 395, 72, 128, 767, 989, -+ 929, 423, 742, 55, 13, 79, 924, 182, 295, 563, 668, 169, 974, 154, -+ 970, 54, 674, 52, 437, 570, 550, 531, 554, 793, 678, 218, 367, 105, -+ 197, 315, 958, 892, 86, 47, 284, 37, 561, 522, 198, 689, 817, 573, -+ 877, 201, 803, 501, 881, 546, 530, 523, 780, 579, 953, 135, 23, 620, -+ 84, 698, 303, 656, 357, 323, 494, 58, 131, 913, 995, 120, 70, 1, 195, -+ 365, 210, 25, 898, 173, 307, 239, 77, 418, 952, 963, 92, 455, 425, 12, -+ 536, 161, 328, 933, 401, 251, 735, 725, 362, 322, 557, 681, 302, 53, -+ 786, 801, 391, 946, 748, 133, 717, 851, 7, 372, 993, 387, 906, 373, -+ 667, 33, 670, 389, 209, 611, 896, 652, 69, 999, 344, 845, 633, 36, -+ 487, 192, 180, 45, 640, 427, 707, 805, 188, 152, 905, 217, 30, 252, -+ 386, 665, 299, 541, 410, 787, 5, 857, 751, 392, 44, 595, 146, 745, -+ 641, 957, 866, 773, 806, 815, 659, 102, 704, 430, 106, 296, 129, 847, -+ 130, 990, 669, 236, 225, 680, 159, 213, 438, 189, 447, 600, 232, 594, -+ 32, 56, 390, 647, 855, 428, 330, 714, 738, 706, 666, 461, 469, 482, -+ 558, 814, 559, 177, 575, 538, 309, 383, 261, 156, 420, 761, 630, 893, -+ 10, 116, 940, 844, 71, 377, 662, 312, 520, 244, 143, 759, 119, 186, -+ 592, 909, 864, 376, 768, 254, 265, 394, 511, 760, 574, 6, 436, 514, -+ 59, 226, 644, 956, 578, 825, 548, 145, 736, 597, 378, 821, 987, 897, -+ 354, 144, 722, 895, 589, 503, 826, 498, 543, 617, 763, 231, 808, 528, -+ 89, 479, 607, 737, 170, 404, 371, 65, 103, 340, 283, 141, 313, 858, -+ 289, 124, 971, 687, 954, 732, 39, 926, 176, 100, 267, 519, 890, 535, -+ 276, 448, 27, 457, 899, 385, 184, 275, 770, 544, 614, 449, 160, 658, -+ 259, 973, 108, 604, 24, 207, 562, 757, 744, 324, 444, 962, 591, 480, -+ 398, 409, 998, 253, 325, 445, 979, 8, 35, 118, 73, 683, 208, 85, 190, -+ 791, 408, 871, 657, 179, 18, 556, 496, 475, 20, 894, 484, 775, 889, -+ 463, 241, 730, 57, 907, 551, 859, 943, 185, 416, 870, 590, 435, 471, -+ 932, 268, 381, 626, 502, 565, 273, 534, 672, 778, 292, 473, 566, 104, -+ 172, 285, 832, 411, 329, 628, 397, 472, 271, 910, 711, 690, 969, 585, -+ 809, 941, 923, 555, 228, 685, 242, 94, 96, 211, 140, 61, 922, 795, -+ 869, 34, 255, 38, 984, 676, 15, 560, 632, 434, 921, 355, 582, 351, -+ 212, 200, 819, 960, 649, 852, 75, 771, 361, 996, 238, 316, 720, 671, -+ 462, 112, 569, 171, 664, 625, 588, 405, 553, 270, 533, 353, 842, 114, -+ 972, 83, 937, 63, 194, 237, 537, 980, 802, 916, 959, 688, 839, 350, -+ 917, 650, 545, 615, 151, 352, 686, 726, 266, 509, 439, 491, 935, 608, -+ 518, 653, 339, 609, 277, 635, 836, 88, 407, 440, 642, 927, 229, 727, -+ 360, 477, 846, 413, 454, 616, 28, 598, 567, 540, 790, 424, 247, 317, -+ 746, 911, 798, 321, 547, 248, 734, 829, 220, 138, 756, 500, 691, 196, -+ 740, 930, 843, 733, 221, 827, 50, 813, 949, 525, 349, 474, 134, 875, -+ 695, 513, 414, 515, 638, 99, 366, 490, 975, 246, 465, 206, 281, 583, -+ 256, 587, 749, 2, 951, 679, 215, 364, 458, 402, 646, 991, 335, 982, -+ 835, 300, 900, 703, 994, 983, 234, 888, 532, 804, 584, 305, 792, 442, -+ 291, 964, 158, 370, 452, 250, 521, 166, 948, 812, 794, 272, 699, 205, -+ 183, 507, 301, 920, 781, 233, 824, 137, 489, 833, 887, 966, 856, 78, -+ 830, 153, 359, 696, 526, 216, 66, 701, 403, 891, 849, 571, 308, 483, -+ 164, 293, 928, 677, 320, 837, 441, 639, 564, 510, 648, 274, 336, 661, -+ 878, 777, 816, 976, 493, 810, 67, 87, 91, 187, 882, 986, 80, 22, 499, -+ 90, 705, 139, 136, 122, 708, 716, 886, 572, 127, 40, 721, 764, 16, -+ 379, 692, 645, 456, 710, 460, 783, 97, 776, 713, 884, 115, 466, 596, -+ 374, 406, 110, 568, 68, 214, 622, 470, 107, 504, 682, 31, 421, 576, -+ 654, 605, 788, 799, 280, 338, 931, 873, 204, 287, 459, 755, 939, 599, -+ 431, 796, 235, 42, 750, 262, 318, 393, 202, 822, 879, 820, 728, 337, -+}; -+ -+static void fill_bindings_random(struct strbuf *buf, int start, int end, -+ const char *prefix) -+{ -+ int i; -+ -+ for (i = start; i < end; i++) { -+ print_strbuf(buf, "%s", prefix); -+ format_devname(buf, random_numbers[i]); -+ print_strbuf(buf, " WWID%d\n", random_numbers[i]); -+ } -+} -+ -+struct random_aliases { -+ int start; -+ int end; -+ const char *prefix; -+}; -+ -+static void order_test(int n, const struct random_aliases ra[], bool conflict_ok) -+{ -+ STRBUF_ON_STACK(buf); -+ int i, j, prev, curr, tmp; -+ struct binding *bdg; -+ Bindings *bindings = &global_bindings; -+ -+ for (j = 0; j < n; j++) -+ fill_bindings_random(&buf, ra[j].start, ra[j].end, ra[j].prefix); -+ __mock_bindings_file(get_strbuf_str(&buf), conflict_ok); -+ -+ for (j = 0; j < n; j++) { -+ bdg = VECTOR_SLOT(bindings, 0); -+ if (ALIAS_DEBUG && j == 0) -+ printf("%d: %s\n", 0, bdg->alias); -+ prev = scan_devname(bdg->alias, ra[j].prefix); -+ i = 1; -+ vector_foreach_slot_after(bindings, bdg, i) { -+ if (ALIAS_DEBUG && j == 0) -+ printf("%d: %s\n", i, bdg->alias); -+ tmp = scan_devname(bdg->alias, ra[j].prefix); -+ if (tmp == -1) -+ continue; -+ curr = tmp; -+ if (prev > 0) { -+ if (curr <= prev) -+ printf("ERROR: %d (%s) %d >= %d\n", -+ i, bdg->alias, prev, curr); -+ assert_true(curr > prev); -+ } -+ prev = curr; -+ } -+ } -+} -+ -+static void order_01(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 1000, "MPATH" }, -+ }; -+ -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_02(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 500, "MPATH" }, -+ { 200, 700, "mpath" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_03(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 500, 1000, "MPTH" }, -+ { 0, 500, "MPATH" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_04(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 500, "mpa" }, -+ { 250, 750, "mp" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, true); -+} -+ -+static void order_05(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 100, "A" }, -+ { 0, 100, "B" }, -+ { 0, 100, "C" }, -+ { 0, 100, "D" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, false); -+} -+ -+static void order_06(void **state) -+{ -+ const struct random_aliases ra[] = { -+ { 0, 100, "" }, -+ { 0, 100, "a" }, -+ { 0, 100, "aa" }, -+ { 0, 100, "ab" }, -+ { 0, 100, "aaa" }, -+ }; -+ order_test(ARRAY_SIZE(ra), ra, true); -+} -+ -+static int test_bindings_order() -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test_teardown(order_01, teardown_bindings), -+ cmocka_unit_test_teardown(order_02, teardown_bindings), -+ cmocka_unit_test_teardown(order_03, teardown_bindings), -+ cmocka_unit_test_teardown(order_04, teardown_bindings), -+ cmocka_unit_test_teardown(order_05, teardown_bindings), -+ cmocka_unit_test_teardown(order_06, teardown_bindings), -+ }; -+ -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ - int main(void) - { - int ret = 0; -@@ -1755,6 +1960,7 @@ int main(void) - ret += test_rlookup_binding(); - ret += test_allocate_binding(); - ret += test_get_user_friendly_alias(); -+ ret += test_bindings_order(); - - return ret; - } diff --git a/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch b/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch deleted file mode 100644 index af21b74..0000000 --- a/0027-multipathd-watch-bindings-file-with-inotify-timestam.patch +++ /dev/null @@ -1,597 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 7 Sep 2023 22:22:43 +0200 -Subject: [PATCH] multipathd: watch bindings file with inotify + timestamp - -Since "libmultipath: keep bindings in memory", we don't re-read the -bindings file after every modification. Add a notification mechanism -that makes multipathd aware of changes to the bindings file. Because -multipathd itself will change the bindings file, it must compare -timestamps in order to avoid reading the file repeatedly. - -Because select_alias() can be called from multiple thread contexts (uxlsnr, -uevent handler), we need to add locking for the bindings file. The -timestamp must also be protected by a lock, because it can't be read -or written atomically. - -Note: The notification mechanism expects the bindings file to be -atomically replaced by rename(2). Changes must be made in a temporary file and -applied using rename(2), as in update_bindings_file(). The inotify -mechanism deliberately does not listen to close-after-write events -that would be generated by editing the bindings file directly. This - -Note also: new bindings will only be read from add_map_with_path(), -i.e. either during reconfigure(), or when a new map is created during -runtime. Existing maps will not be renamed if the binding file changes, -unless the user runs "multipathd reconfigure". This is not a change -wrt the previous code, but it should be mentioned anyway. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 256 +++++++++++++++++++++++++----- - libmultipath/alias.h | 3 +- - libmultipath/libmultipath.version | 5 + - multipathd/uxlsnr.c | 36 ++++- - tests/alias.c | 3 + - 5 files changed, 256 insertions(+), 47 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 66e34e31..964b8a7b 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "util.h" -@@ -22,6 +23,7 @@ - #include "config.h" - #include "devmapper.h" - #include "strbuf.h" -+#include "time-util.h" - - /* - * significant parts of this file were taken from iscsi-bindings.c of the -@@ -50,6 +52,12 @@ - "# alias wwid\n" \ - "#\n" - -+/* uatomic access only */ -+static int bindings_file_changed = 1; -+ -+static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; -+static struct timespec bindings_last_updated; -+ - struct binding { - char *alias; - char *wwid; -@@ -60,6 +68,9 @@ struct binding { - * an abstract type. - */ - typedef struct _vector Bindings; -+ -+/* Protect global_bindings */ -+static pthread_mutex_t bindings_mutex = PTHREAD_MUTEX_INITIALIZER; - static Bindings global_bindings = { .allocated = 0 }; - - enum { -@@ -78,6 +89,27 @@ static void _free_binding(struct binding *bdg) - free(bdg); - } - -+static void free_bindings(Bindings *bindings) -+{ -+ struct binding *bdg; -+ int i; -+ -+ vector_foreach_slot(bindings, bdg, i) -+ _free_binding(bdg); -+ vector_reset(bindings); -+} -+ -+static void set_global_bindings(Bindings *bindings) -+{ -+ Bindings old_bindings; -+ -+ pthread_mutex_lock(&bindings_mutex); -+ old_bindings = global_bindings; -+ global_bindings = *bindings; -+ pthread_mutex_unlock(&bindings_mutex); -+ free_bindings(&old_bindings); -+} -+ - static const struct binding *get_binding_for_alias(const Bindings *bindings, - const char *alias) - { -@@ -199,7 +231,8 @@ static int delete_binding(Bindings *bindings, const char *wwid) - return BINDING_DELETED; - } - --static int write_bindings_file(const Bindings *bindings, int fd) -+static int write_bindings_file(const Bindings *bindings, int fd, -+ struct timespec *ts) - { - struct binding *bnd; - STRBUF_ON_STACK(content); -@@ -227,9 +260,56 @@ static int write_bindings_file(const Bindings *bindings, int fd) - } - len -= n; - } -+ fsync(fd); -+ if (ts) { -+ struct stat st; -+ -+ if (fstat(fd, &st) == 0) -+ *ts = st.st_mtim; -+ else -+ clock_gettime(CLOCK_REALTIME_COARSE, ts); -+ } - return 0; - } - -+void handle_bindings_file_inotify(const struct inotify_event *event) -+{ -+ struct config *conf; -+ const char *base; -+ bool changed = false; -+ struct stat st; -+ struct timespec ts = { 0, 0 }; -+ int ret; -+ -+ if (!(event->mask & IN_MOVED_TO)) -+ return; -+ -+ conf = get_multipath_config(); -+ base = strrchr(conf->bindings_file, '/'); -+ changed = base && base > conf->bindings_file && -+ !strcmp(base + 1, event->name); -+ ret = stat(conf->bindings_file, &st); -+ put_multipath_config(conf); -+ -+ if (!changed) -+ return; -+ -+ pthread_mutex_lock(×tamp_mutex); -+ if (ret == 0) { -+ ts = st.st_mtim; -+ changed = timespeccmp(&ts, &bindings_last_updated) > 0; -+ } -+ pthread_mutex_unlock(×tamp_mutex); -+ -+ if (changed) { -+ uatomic_xchg(&bindings_file_changed, 1); -+ condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", -+ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); -+ } else -+ condlog(3, "%s: bindings file is up-to-date, timestamp: %ld.%06ld", -+ __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); -+} -+ - static int update_bindings_file(const Bindings *bindings, - const char *bindings_file) - { -@@ -237,6 +317,7 @@ static int update_bindings_file(const Bindings *bindings, - int fd = -1; - char tempname[PATH_MAX]; - mode_t old_umask; -+ struct timespec ts; - - if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) - return -1; -@@ -248,7 +329,7 @@ static int update_bindings_file(const Bindings *bindings, - } - umask(old_umask); - pthread_cleanup_push(cleanup_fd_ptr, &fd); -- rc = write_bindings_file(bindings, fd); -+ rc = write_bindings_file(bindings, fd, &ts); - pthread_cleanup_pop(1); - if (rc == -1) { - condlog(1, "failed to write new bindings file"); -@@ -257,8 +338,12 @@ static int update_bindings_file(const Bindings *bindings, - } - if ((rc = rename(tempname, bindings_file)) == -1) - condlog(0, "%s: rename: %m", __func__); -- else -+ else { -+ pthread_mutex_lock(×tamp_mutex); -+ bindings_last_updated = ts; -+ pthread_mutex_unlock(×tamp_mutex); - condlog(1, "updated bindings file %s", bindings_file); -+ } - return rc; - } - -@@ -387,6 +472,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww - return id; - } - -+/* Called with binding_mutex held */ - static char * - allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) - { -@@ -423,6 +509,30 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre - return alias; - } - -+enum { -+ BINDINGS_FILE_UP2DATE, -+ BINDINGS_FILE_READ, -+ BINDINGS_FILE_ERROR, -+ BINDINGS_FILE_BAD, -+}; -+ -+static int _read_bindings_file(const struct config *conf, Bindings *bindings, -+ bool force); -+ -+static void read_bindings_file(void) -+{ -+ struct config *conf; -+ Bindings bindings = {.allocated = 0, }; -+ int rc; -+ -+ conf = get_multipath_config(); -+ pthread_cleanup_push(put_multipath_config, conf); -+ rc = _read_bindings_file(conf, &bindings, false); -+ pthread_cleanup_pop(1); -+ if (rc == BINDINGS_FILE_READ) -+ set_global_bindings(&bindings); -+} -+ - /* - * get_user_friendly_alias() action table - * -@@ -463,6 +573,11 @@ char *get_user_friendly_alias(const char *wwid, const char *file, const char *al - bool new_binding = false; - const struct binding *bdg; - -+ read_bindings_file(); -+ -+ pthread_mutex_lock(&bindings_mutex); -+ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); -+ - if (!*alias_old) - goto new_alias; - -@@ -514,40 +629,40 @@ new_alias: - alias, wwid); - - out: -+ /* unlock bindings_mutex */ -+ pthread_cleanup_pop(1); - return alias; - } - - int get_user_friendly_wwid(const char *alias, char *buff) - { - const struct binding *bdg; -+ int rc = -1; - - if (!alias || *alias == '\0') { - condlog(3, "Cannot find binding for empty alias"); - return -1; - } - -+ read_bindings_file(); -+ -+ pthread_mutex_lock(&bindings_mutex); -+ pthread_cleanup_push(cleanup_mutex, &bindings_mutex); - bdg = get_binding_for_alias(&global_bindings, alias); -- if (!bdg) { -+ if (bdg) { -+ strlcpy(buff, bdg->wwid, WWID_SIZE); -+ rc = 0; -+ } else - *buff = '\0'; -- return -1; -- } -- strlcpy(buff, bdg->wwid, WWID_SIZE); -- return 0; --} -- --static void free_bindings(Bindings *bindings) --{ -- struct binding *bdg; -- int i; -- -- vector_foreach_slot(bindings, bdg, i) -- _free_binding(bdg); -- vector_reset(bindings); -+ pthread_cleanup_pop(1); -+ return rc; - } - - void cleanup_bindings(void) - { -+ pthread_mutex_lock(&bindings_mutex); - free_bindings(&global_bindings); -+ pthread_mutex_unlock(&bindings_mutex); - } - - enum { -@@ -595,7 +710,20 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - char *line = NULL; - size_t line_len = 0; - ssize_t n; -- -+ char header[sizeof(BINDINGS_FILE_HEADER)]; -+ -+ header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; -+ if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { -+ condlog(2, "%s: failed to read header from %s", __func__, -+ conf->bindings_file); -+ fseek(file, 0, SEEK_SET); -+ rc = -1; -+ } else if (strcmp(header, BINDINGS_FILE_HEADER)) { -+ condlog(2, "%s: invalid header in %s", __func__, -+ conf->bindings_file); -+ fseek(file, 0, SEEK_SET); -+ rc = -1; -+ } - pthread_cleanup_push(cleanup_free_ptr, &line); - while ((n = getline(&line, &line_len, file)) >= 0) { - char *alias, *wwid; -@@ -643,6 +771,68 @@ static int mp_alias_compar(const void *p1, const void *p2) - &((*(struct mpentry * const *)p2)->alias)); - } - -+static int _read_bindings_file(const struct config *conf, Bindings *bindings, -+ bool force) -+{ -+ int can_write; -+ int rc = 0, ret, fd; -+ FILE *file; -+ struct stat st; -+ int has_changed = uatomic_xchg(&bindings_file_changed, 0); -+ -+ if (!force) { -+ if (!has_changed) { -+ condlog(4, "%s: bindings are unchanged", __func__); -+ return BINDINGS_FILE_UP2DATE; -+ } -+ } -+ -+ fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); -+ if (fd == -1) -+ return BINDINGS_FILE_ERROR; -+ -+ file = fdopen(fd, "r"); -+ if (file != NULL) { -+ condlog(3, "%s: reading %s", __func__, conf->bindings_file); -+ -+ pthread_cleanup_push(cleanup_fclose, file); -+ ret = _check_bindings_file(conf, file, bindings); -+ if (ret == 0) { -+ struct timespec ts; -+ -+ rc = BINDINGS_FILE_READ; -+ ret = fstat(fd, &st); -+ if (ret == 0) -+ ts = st.st_mtim; -+ else { -+ condlog(1, "%s: fstat failed (%m), using current time", __func__); -+ clock_gettime(CLOCK_REALTIME_COARSE, &ts); -+ } -+ pthread_mutex_lock(×tamp_mutex); -+ bindings_last_updated = ts; -+ pthread_mutex_unlock(×tamp_mutex); -+ } else if (ret == -1 && can_write && !conf->bindings_read_only) { -+ ret = update_bindings_file(bindings, conf->bindings_file); -+ if (ret == 0) -+ rc = BINDINGS_FILE_READ; -+ else -+ rc = BINDINGS_FILE_BAD; -+ } else { -+ condlog(0, "ERROR: bad settings in read-only bindings file %s", -+ conf->bindings_file); -+ rc = BINDINGS_FILE_BAD; -+ } -+ pthread_cleanup_pop(1); -+ } else { -+ condlog(1, "failed to fdopen %s: %m", -+ conf->bindings_file); -+ close(fd); -+ rc = BINDINGS_FILE_ERROR; -+ } -+ -+ return rc; -+} -+ - /* - * check_alias_settings(): test for inconsistent alias configuration - * -@@ -661,8 +851,7 @@ static int mp_alias_compar(const void *p1, const void *p2) - */ - int check_alias_settings(const struct config *conf) - { -- int can_write; -- int rc = 0, i, fd; -+ int i, rc; - Bindings bindings = {.allocated = 0, }; - vector mptable = NULL; - struct mpentry *mpe; -@@ -695,27 +884,12 @@ int check_alias_settings(const struct config *conf) - pthread_cleanup_pop(1); - pthread_cleanup_pop(1); - -- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); -- if (fd != -1) { -- FILE *file = fdopen(fd, "r"); -- -- if (file != NULL) { -- pthread_cleanup_push(cleanup_fclose, file); -- rc = _check_bindings_file(conf, file, &bindings); -- pthread_cleanup_pop(1); -- if (rc == -1 && can_write && !conf->bindings_read_only) -- rc = update_bindings_file(&bindings, conf->bindings_file); -- else if (rc == -1) -- condlog(0, "ERROR: bad settings in read-only bindings file %s", -- conf->bindings_file); -- } else { -- condlog(1, "failed to fdopen %s: %m", -- conf->bindings_file); -- close(fd); -- } -+ rc = _read_bindings_file(conf, &bindings, true); -+ -+ if (rc == BINDINGS_FILE_READ) { -+ set_global_bindings(&bindings); -+ rc = 0; - } - -- cleanup_bindings(); -- global_bindings = bindings; - return rc; - } -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index 5ef6720b..ca8911f4 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -10,5 +10,6 @@ char *get_user_friendly_alias(const char *wwid, const char *file, - struct config; - int check_alias_settings(const struct config *); - void cleanup_bindings(void); -- -+struct inotify_event; -+void handle_bindings_file_inotify(const struct inotify_event *event); - #endif /* _ALIAS_H */ -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index ddd302f5..57e50c12 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -238,3 +238,8 @@ global: - local: - *; - }; -+ -+LIBMULTIPATH_20.1.0 { -+global: -+ handle_bindings_file_inotify; -+}; -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index 02e89fb4..d1f8f234 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -41,6 +41,7 @@ - #include "cli.h" - #include "uxlsnr.h" - #include "strbuf.h" -+#include "alias.h" - - /* state of client connection */ - enum { -@@ -190,6 +191,7 @@ void wakeup_cleanup(void *arg) - struct watch_descriptors { - int conf_wd; - int dir_wd; -+ int mp_wd; /* /etc/multipath; for bindings file */ - }; - - /* failing to set the watch descriptor is o.k. we just miss a warning -@@ -200,6 +202,8 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - struct config *conf; - int dir_reset = 0; - int conf_reset = 0; -+ int mp_reset = 0; -+ char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; - - if (notify_fd == -1) - return; -@@ -214,7 +218,10 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - conf_reset = 1; - if (wds->dir_wd == -1) - dir_reset = 1; -+ if (wds->mp_wd == -1) -+ mp_reset = 1; - } -+ bindings_file = strdup(conf->bindings_file); - put_multipath_config(conf); - - if (dir_reset) { -@@ -235,7 +242,18 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - if (wds->conf_wd == -1) - condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); - } -- return; -+ if (mp_reset && bindings_file) { -+ char *slash = strrchr(bindings_file, '/'); -+ -+ if (slash && slash > bindings_file) { -+ *slash = '\0'; -+ wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, -+ IN_MOVED_TO|IN_ONLYDIR); -+ if (wds->mp_wd == -1) -+ condlog(3, "didn't set up notifications on %s: %m", -+ bindings_file); -+ } -+ } - } - - static void handle_inotify(int fd, struct watch_descriptors *wds) -@@ -256,12 +274,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) - inotify_rm_watch(fd, wds->conf_wd); - if (wds->dir_wd != -1) - inotify_rm_watch(fd, wds->dir_wd); -- wds->conf_wd = wds->dir_wd = -1; -+ if (wds->mp_wd != -1) -+ inotify_rm_watch(fd, wds->mp_wd); -+ wds->conf_wd = wds->dir_wd = wds->mp_wd = -1; - } - break; - } - -- got_notify = 1; - for (ptr = buff; ptr < buff + len; - ptr += sizeof(struct inotify_event) + event->len) { - event = (const struct inotify_event *) ptr; -@@ -273,7 +292,13 @@ static void handle_inotify(int fd, struct watch_descriptors *wds) - wds->conf_wd = inotify_add_watch(notify_fd, DEFAULT_CONFIGFILE, IN_CLOSE_WRITE); - else if (wds->dir_wd == event->wd) - wds->dir_wd = -1; -+ else if (wds->mp_wd == event->wd) -+ wds->mp_wd = -1; - } -+ if (wds->mp_wd != -1 && wds->mp_wd == event->wd) -+ handle_bindings_file_inotify(event); -+ else -+ got_notify = 1; - } - } - if (got_notify) -@@ -599,7 +624,7 @@ void *uxsock_listen(long ux_sock, void *trigger_data) - int max_pfds = MIN_POLLS + POLLFDS_BASE; - /* conf->sequence_nr will be 1 when uxsock_listen is first called */ - unsigned int sequence_nr = 0; -- struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1 }; -+ struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1, .mp_wd = -1, }; - struct vectors *vecs = trigger_data; - - condlog(3, "uxsock: startup listener"); -@@ -666,7 +691,8 @@ void *uxsock_listen(long ux_sock, void *trigger_data) - - reset_watch(notify_fd, &wds, &sequence_nr); - polls[POLLFD_NOTIFY].fd = notify_fd; -- if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1)) -+ if (notify_fd == -1 || (wds.conf_wd == -1 && wds.dir_wd == -1 -+ && wds.mp_wd == -1)) - polls[POLLFD_NOTIFY].events = 0; - else - polls[POLLFD_NOTIFY].events = POLLIN; -diff --git a/tests/alias.c b/tests/alias.c -index 7f3ff38a..9ae27567 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -1954,6 +1954,9 @@ int main(void) - int ret = 0; - init_test_verbosity(3); - -+ /* avoid open_file() call in _read_bindings_file */ -+ bindings_file_changed = 0; -+ - ret += test_format_devname(); - ret += test_scan_devname(); - ret += test_lookup_binding(); diff --git a/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch b/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch deleted file mode 100644 index bba92f3..0000000 --- a/0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 19:54:07 +0200 -Subject: [PATCH] multipath-tools tests: mock pthread_mutex_{lock,unlock} - -If some test fails with a lock held, cmocka doesn't deal well with -pthread_cleanup_pop(). Such tests can cause deadlock with the locking -primitives in the alias code, because locks don't get properly unlocked. Just -mock the lock/unlock functions and generate an error if they weren't paired at -the end of the test. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 1 + - tests/alias.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 47 insertions(+) - -diff --git a/tests/Makefile b/tests/Makefile -index c777d07a..7dac8a8f 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -52,6 +52,7 @@ blacklist-test_LIBDEPS := -ludev - vpd-test_OBJDEPS := $(multipathdir)/discovery.o - vpd-test_LIBDEPS := -ludev -lpthread -ldl - alias-test_TESTDEPS := test-log.o -+alias-test_OBJDEPS := $(mpathutildir)/util.o - alias-test_LIBDEPS := -lpthread -ldl - valid-test_OBJDEPS := $(multipathdir)/valid.o $(multipathdir)/discovery.o - valid-test_LIBDEPS := -lmount -ludev -lpthread -ldl -diff --git a/tests/alias.c b/tests/alias.c -index 9ae27567..94df36d8 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -89,6 +89,47 @@ int __wrap_dm_get_uuid(const char *name, char *uuid, int uuid_len) - return ret; - } - -+static int lock_errors; -+static int bindings_locked; -+static int timestamp_locked; -+int __wrap_pthread_mutex_lock(pthread_mutex_t *mutex) -+{ -+ if (mutex == &bindings_mutex) { -+ if (bindings_locked) { -+ fprintf(stderr, "%s: bindings_mutex LOCKED\n", __func__); -+ lock_errors++; -+ } -+ bindings_locked = 1; -+ } else if (mutex == ×tamp_mutex) { -+ if (timestamp_locked) { -+ fprintf(stderr, "%s: timestamp_mutex LOCKED\n", __func__); -+ lock_errors++; -+ } -+ timestamp_locked = 1; -+ } else -+ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); -+ return 0; -+} -+ -+int __wrap_pthread_mutex_unlock(pthread_mutex_t *mutex) -+{ -+ if (mutex == &bindings_mutex) { -+ if (!bindings_locked) { -+ fprintf(stderr, "%s: bindings_mutex UNLOCKED\n", __func__); -+ lock_errors++; -+ } -+ bindings_locked = 0; -+ } else if (mutex == ×tamp_mutex) { -+ if (!timestamp_locked) { -+ fprintf(stderr, "%s: timestamp_mutex UNLOCKED\n", __func__); -+ lock_errors++; -+ } -+ timestamp_locked = 0; -+ } else -+ fprintf(stderr, "%s called for unknown mutex %p\n", __func__, mutex); -+ return 0; -+} -+ - #define TEST_FDNO 1234 - #define TEST_FPTR ((FILE *) 0xaffe) - -@@ -1718,6 +1759,10 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { - free(alias); - } - -+static void gufa_check_locking(void **state) { -+ assert_int_equal(lock_errors, 0); -+} -+ - static int test_get_user_friendly_alias() - { - const struct CMUnitTest tests[] = { -@@ -1743,6 +1788,7 @@ static int test_get_user_friendly_alias() - cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch, teardown_bindings), - cmocka_unit_test_teardown(gufa_old_nomatch_wwidmatch_used, teardown_bindings), - cmocka_unit_test_teardown(gufa_old_nomatch_nowwidmatch, teardown_bindings), -+ cmocka_unit_test(gufa_check_locking), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch b/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch deleted file mode 100644 index 26b79a8..0000000 --- a/0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 22:13:51 +0200 -Subject: [PATCH] multipath-tools Makefile: sanitize paths for configuration - files - -Make the path to multipath.conf configurable, and use the same prefix -by default for multipath.conf and multipath/conf.d. For "usr-merged" -distributions with immutable /usr, we'll want to have the configuration -under a different prefix. This can be achieved by using e.g. - - make prefix=/usr etc_prefix="" - -Note that with prefix=/usr, before this patch the code would use -/usr/etc/multipath/conf.d, but /etc/multipath.conf. If this (rather -inconsistent) behavior is desired, use the following command line: - - make prefix=/usr configfile=/etc/multipath.conf - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 9 ++++++--- - libmultipath/defaults.h | 1 - - 2 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 502cd0f1..39972d93 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -37,6 +37,8 @@ prefix := - exec_prefix := $(prefix) - # Prefix for non-essential libraries (libdmmp) - usr_prefix := $(prefix) -+# Prefix for configfuration files (multipath.conf) -+etc_prefix := $(prefix) - # Where to install systemd-related files. systemd is usually installed under /usr - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) -@@ -54,7 +56,8 @@ usrlibdir := $(usr_prefix)/$(LIB) - includedir := $(usr_prefix)/include - pkgconfdir := $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath --configdir := $(prefix)/etc/multipath/conf.d -+configdir := $(etc_prefix)/etc/multipath/conf.d -+configfile := $(etc_prefix)/etc/multipath.conf - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) - libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) -@@ -84,8 +87,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) - CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -- -DRUNTIME_DIR=\"$(runtimedir)\" \ -- -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -+ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -+ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS := -fPIE -DPIE - LIB_CFLAGS := -fPIC -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index b3f11d4c..bc2d6388 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -66,7 +66,6 @@ - #define MAX_DEV_LOSS_TMO UINT_MAX - #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" - #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" --#define DEFAULT_CONFIGFILE "/etc/multipath.conf" - #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" - #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" - #define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" diff --git a/0030-multipath-tools-add-compile-time-configuration-for-e.patch b/0030-multipath-tools-add-compile-time-configuration-for-e.patch deleted file mode 100644 index afdf833..0000000 --- a/0030-multipath-tools-add-compile-time-configuration-for-e.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 22:26:22 +0200 -Subject: [PATCH] multipath-tools: add compile time configuration for - "/etc/multipath" - -Instead of hard-conding "/etc/multipath" as the path for the state -files "bindings", "prkeys", and "wwids", make this path configurable -via the "statedir" compile-time option. The default is currently still -/etc, it might change to /var/lib or similar in the future. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 4 +++- - libmultipath/defaults.h | 6 +++--- - 2 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 39972d93..96206b2f 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -58,6 +58,7 @@ pkgconfdir := $(usrlibdir)/pkgconfig - plugindir := $(prefix)/$(LIB)/multipath - configdir := $(etc_prefix)/etc/multipath/conf.d - configfile := $(etc_prefix)/etc/multipath.conf -+statedir := $(etc_prefix)/etc/multipath - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) - libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) -@@ -88,7 +89,8 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -+ -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -+ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS := -fPIE -DPIE - LIB_CFLAGS := -fPIC -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index bc2d6388..d01f9712 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -66,9 +66,9 @@ - #define MAX_DEV_LOSS_TMO UINT_MAX - #define DEFAULT_PIDFILE RUNTIME_DIR "/multipathd.pid" - #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" --#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" --#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" --#define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" -+#define DEFAULT_BINDINGS_FILE STATE_DIR "/bindings" -+#define DEFAULT_WWIDS_FILE STATE_DIR "/wwids" -+#define DEFAULT_PRKEYS_FILE STATE_DIR "/prkeys" - #define MULTIPATH_SHM_BASE RUNTIME_DIR "/multipath/" - - diff --git a/0031-multipath-tools-man-pages-generate-with-correct-path.patch b/0031-multipath-tools-man-pages-generate-with-correct-path.patch deleted file mode 100644 index 65fc077..0000000 --- a/0031-multipath-tools-man-pages-generate-with-correct-path.patch +++ /dev/null @@ -1,366 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Sep 2023 22:48:16 +0200 -Subject: [PATCH] multipath-tools man pages: generate with correct paths - -Generate the man pages using the compile-time settings for paths -to multipath.conf etc. - -Add a paragraph about the CONFIGDIR (/etc/multipath/conf.d) -and the drop-in configuration files in the multipath.conf man page. - -Also, make sure all generated man pages and other files are correctly -removed by "make clean". - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - .gitignore | 4 +++ - Makefile.inc | 3 +++ - mpathpersist/Makefile | 5 ++-- - .../{mpathpersist.8 => mpathpersist.8.in} | 2 +- - multipath/Makefile | 13 +++++---- - multipath/{multipath.8 => multipath.8.in} | 10 +++---- - .../{multipath.conf.5 => multipath.conf.5.in} | 27 ++++++++++++------- - multipathd/Makefile | 9 ++++--- - multipathd/{multipathd.8 => multipathd.8.in} | 8 +++--- - 9 files changed, 49 insertions(+), 32 deletions(-) - rename mpathpersist/{mpathpersist.8 => mpathpersist.8.in} (99%) - rename multipath/{multipath.8 => multipath.8.in} (97%) - rename multipath/{multipath.conf.5 => multipath.conf.5.in} (98%) - rename multipathd/{multipathd.8 => multipathd.8.in} (97%) - -diff --git a/.gitignore b/.gitignore -index 535353e5..2986578f 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -13,11 +13,15 @@ cscope.files - cscope.out - kpartx/kpartx - multipath/multipath -+multipath/multipath.8 -+multipath/multipath.conf.5 - multipath/multipath.rules - multipath/tmpfiles.conf - multipathd/multipathd -+multipathd/multipathd.8 - multipathd/multipathc - mpathpersist/mpathpersist -+mpathpersist/mpathpersist.8 - abi.tar.gz - abi - abi-test -diff --git a/Makefile.inc b/Makefile.inc -index 96206b2f..79e521e1 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -133,3 +133,6 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - @grep -P '^[ \t]+[a-zA-Z_][a-zA-Z0-9_]*;' $< >>$@ - @printf 'local:\n\t*;\n};\n' >>$@ - -+%: %.in -+ @echo creating $@ -+ $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g' $< >$@ -diff --git a/mpathpersist/Makefile b/mpathpersist/Makefile -index f57c105c..f3749467 100644 ---- a/mpathpersist/Makefile -+++ b/mpathpersist/Makefile -@@ -8,10 +8,11 @@ LIBDEPS += -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath \ - -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd -lpthread -ldevmapper -ludev - - EXEC = mpathpersist -+MANPAGES := mpathpersist.8 - - OBJS = main.o - --all: $(EXEC) -+all: $(EXEC) $(MANPAGES) - - $(EXEC): $(OBJS) - $(Q)$(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) $(LIBDEPS) -@@ -23,7 +24,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 - - clean: dep_clean -- $(Q)$(RM) core *.o $(EXEC) -+ $(Q)$(RM) core *.o $(EXEC) $(MANPAGES) - - include $(wildcard $(OBJS:.o=.d)) - -diff --git a/mpathpersist/mpathpersist.8 b/mpathpersist/mpathpersist.8.in -similarity index 99% -rename from mpathpersist/mpathpersist.8 -rename to mpathpersist/mpathpersist.8.in -index 8d26b37c..fecef0d6 100644 ---- a/mpathpersist/mpathpersist.8 -+++ b/mpathpersist/mpathpersist.8.in -@@ -31,7 +31,7 @@ mpathpersist \- Manages SCSI persistent reservations on dm multipath devices. - . - This utility is used to manage SCSI persistent reservations on Device Mapper - Multipath devices. To be able to use this functionality, the \fIreservation_key\fR --attribute must be defined in the \fI/etc/multipath.conf\fR file. Otherwise the -+attribute must be defined in the \fI@CONFIGFILE@\fR file. Otherwise the - \fBmultipathd\fR daemon will not check for persistent reservation for newly - discovered paths or reinstated paths. - . -diff --git a/multipath/Makefile b/multipath/Makefile -index 73db991a..68cb5ce7 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -3,7 +3,9 @@ - # - include ../Makefile.inc - --EXEC := multipath -+EXEC := multipath -+MANPAGES := multipath.8 multipath.conf.5 -+GENERATED := $(MANPAGES) multipath.rules tmpfiles.conf - - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathcmddir) - CFLAGS += $(BIN_CFLAGS) -@@ -13,7 +15,7 @@ LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathutildir) -lmpathutil \ - - OBJS := main.o - --all: $(EXEC) multipath.rules tmpfiles.conf -+all: $(EXEC) $(GENERATED) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - @echo building $@ because of $? -@@ -47,15 +49,12 @@ uninstall: - $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules - $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 - $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 -+ $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf - - clean: dep_clean -- $(Q)$(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf -+ $(Q)$(RM) core *.o $(EXEC) $(GENERATED) - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: - $(Q)$(RM) $(OBJS:.o=.d) -- --%: %.in -- @echo creating $@ -- $(Q)sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ -diff --git a/multipath/multipath.8 b/multipath/multipath.8.in -similarity index 97% -rename from multipath/multipath.8 -rename to multipath/multipath.8.in -index 5fed6df7..348eb220 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8.in -@@ -185,7 +185,7 @@ Display the currently used multipathd configuration. - .B \-T - Display the currently used multipathd configuration, limiting the output to - those devices actually present in the system. This can be used a template for --creating \fImultipath.conf\fR. -+creating \fI@CONFIGFILE@\fR. - . - .\" ---------------------------------------------------------------------------- - .SH OPTIONS -@@ -233,11 +233,11 @@ option from \fBmultipath.conf(5)\fR. - .B \-i - Ignore WWIDs file when processing devices. If - \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in --\fImultipath.conf\fR, multipath only considers devices that are -+\fI@CONFIGFILE@\fR, multipath only considers devices that are - listed in the WWIDs file. This option overrides that behavior. For other values - of \fIfind_multipaths\fR, this option has no effect. See the description of - \fIfind_multipaths\fR in --.BR multipath.conf (5). -+.BR @CONFIGFILE@ (5). - This option should only be used in rare circumstances. - . - .TP -@@ -246,8 +246,8 @@ Treat the bindings file as read only. - . - .TP - .BI \-b " file" --Set \fIuser_friendly_names\fR bindings file location. The default is --\fI/etc/multipath/bindings\fR. -+(\fBdeprecated, do not use\fR) Set \fIuser_friendly_names\fR bindings file location. The default is -+\fI@STATE_DIR@/bindings\fR. - . - .TP - .B \-q -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5.in -similarity index 98% -rename from multipath/multipath.conf.5 -rename to multipath/multipath.conf.5.in -index 93af17db..20df2232 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5.in -@@ -13,14 +13,14 @@ - .SH NAME - .\" ---------------------------------------------------------------------------- - . --multipath.conf \- multipath daemon configuration file. -+@CONFIGFILE@, @CONFIGDIR@/*.conf \- multipath daemon configuration file. - . - . - .\" ---------------------------------------------------------------------------- - .SH DESCRIPTION - .\" ---------------------------------------------------------------------------- - . --.B "/etc/multipath.conf" -+.B "@CONFIGFILE@" - is the configuration file for the multipath daemon. It is used to - overwrite the built-in configuration table of \fBmultipathd\fP. - Any line whose first non-white-space character is a '#' is considered -@@ -29,6 +29,15 @@ a comment line. Empty lines are ignored. - Currently used multipathd configuration can be displayed with the \fBmultipath -t\fR - or \fBmultipathd show config\fR command. - . -+.PP -+Additional configuration can be made in drop-in files under -+.B @CONFIGDIR@. -+Files ending in \fI.conf\fR in this directory are read -+in alphabetical order, after reading \fI@CONFIGFILE@\fR. -+They use the same syntax as \fI@CONFIGFILE@\fR itself, -+and support all sections and keywords. If a keyword occurs in the same section -+in multiple files, the last occurence will take precedence over all others. -+. - . - .\" ---------------------------------------------------------------------------- - .SH SYNTAX -@@ -85,7 +94,7 @@ not mandatory. - . - .LP - .B Note on regular expressions: --The \fImultipath.conf\fR syntax allows many attribute values to be specified as POSIX -+The \fI@CONFIGFILE@\fR syntax allows many attribute values to be specified as POSIX - Extended Regular Expressions (see \fBregex\fR(7)). These regular expressions - are \fBcase sensitive\fR and \fBnot anchored\fR, thus the expression "bar" matches "barbie", - "rhabarber", and "wunderbar", but not "Barbie". To avoid unwanted substring -@@ -711,7 +720,7 @@ The default is: \fBno\fR - .B user_friendly_names - If set to - .I yes --, using the bindings file \fI/etc/multipath/bindings\fR to assign a persistent -+, using the bindings file \fI@STATE_DIR@/bindings\fR to assign a persistent - and unique alias to the multipath, in the form of mpath. If set to - .I no - use the WWID as the alias. In either case this be will -@@ -790,7 +799,7 @@ The full pathname of the binding file to be used when the user_friendly_names - option is set. - .RS - .TP --The default is: \fB/etc/multipath/bindings\fR -+The default is: \fB@STATE_DIR@/bindings\fR - .RE - . - . -@@ -801,7 +810,7 @@ The full pathname of the WWIDs file, which is used by multipath to keep track - of the WWIDs for LUNs it has created multipath devices on in the past. - .RS - .TP --The default is: \fB/etc/multipath/wwids\fR -+The default is: \fB@STATE_DIR@/wwids\fR - .RE - . - . -@@ -813,7 +822,7 @@ track of the persistent reservation key used for a specific WWID, when - \fIreservation_key\fR is set to \fBfile\fR. - .RS - .TP --The default is: \fB/etc/multipath/prkeys\fR -+The default is: \fB@STATE_DIR@/prkeys\fR - .RE - . - . -@@ -872,7 +881,7 @@ The default is: \fBno\fR - .I yes - and the SCSI layer has already attached a hardware_handler to the device, - multipath will not force the device to use the hardware_handler specified by --multipath.conf. If the SCSI layer has not attached a hardware handler, -+@CONFIGFILE@. If the SCSI layer has not attached a hardware handler, - multipath will continue to use its configured hardware handler. - .RS - .PP -@@ -1559,7 +1568,7 @@ given device, the attributes of all matching entries are applied to it. - If an attribute is specified in several matching device subsections, - later entries take precedence. Thus, entries in files under \fIconfig_dir\fR (in - reverse alphabetical order) have the highest precedence, followed by entries --in \fImultipath.conf\fR; the built-in hardware table has the lowest -+in \fI@CONFIGFILE@\fR; the built-in hardware table has the lowest - precedence. Inside a configuration file, later entries have higher precedence - than earlier ones. - .LP -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 0d0146c5..cdba3db1 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -1,7 +1,8 @@ - include ../Makefile.inc - --EXEC := multipathd --CLI := multipathc -+EXEC := multipathd -+CLI := multipathc -+MANPAGES := multipathd.8 - - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ - $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ -@@ -42,7 +43,7 @@ ifeq ($(FPIN_SUPPORT),1) - OBJS += fpin_handlers.o - endif - --all : $(EXEC) $(CLI) -+all : $(EXEC) $(CLI) $(MANPAGES) - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - @echo building $@ because of $? -@@ -79,7 +80,7 @@ uninstall: - $(Q)$(RM) $(DESTDIR)$(unitdir)/$(EXEC).socket - - clean: dep_clean -- $(Q)$(RM) core *.o $(EXEC) $(CLI) -+ $(Q)$(RM) core *.o $(EXEC) $(CLI) $(MANPAGES) - - include $(wildcard $(OBJS:.o=.d) $(CLI_OBJS:.o=.d)) - -diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8.in -similarity index 97% -rename from multipathd/multipathd.8 -rename to multipathd/multipathd.8.in -index cc72b775..e98c27fd 100644 ---- a/multipathd/multipathd.8 -+++ b/multipathd/multipathd.8.in -@@ -155,7 +155,7 @@ Show the format wildcards used in interactive commands taking $format. - .TP - .B list|show config - Show the currently used configuration, derived from default values and values --specified within the configuration file \fI/etc/multipath.conf\fR. -+specified within the configuration file \fI@CONFIGFILE@\fR. - . - .TP - .B list|show config local -@@ -165,7 +165,7 @@ the devices section to those devices that are actually present in the system. - .TP - .B list|show blacklist - Show the currently used blacklist rules, derived from default values and values --specified within the configuration file \fI/etc/multipath.conf\fR. -+specified within the configuration file \fI@CONFIGFILE@\fR. - . - .TP - .B list|show devices -@@ -290,13 +290,13 @@ Get the current persistent reservation key associated with $map. - .B map|multipath $map setprkey key $key - Set the persistent reservation key associated with $map to $key in the - \fIprkeys_file\fR. This key will only be used by multipathd if --\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. -+\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. - . - .TP - .B map|multipath $map unsetprkey - Remove the persistent reservation key associated with $map from the - \fIprkeys_file\fR. This will only unset the key used by multipathd if --\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. -+\fIreservation_key\fR is set to \fBfile\fR in \fI@CONFIGFILE@\fR. - . - .TP - .B path $path setmarginal diff --git a/0032-libdmmp-Makefile-fix-bug-in-install-section.patch b/0032-libdmmp-Makefile-fix-bug-in-install-section.patch deleted file mode 100644 index a3f2470..0000000 --- a/0032-libdmmp-Makefile-fix-bug-in-install-section.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 09:30:13 +0200 -Subject: [PATCH] libdmmp/Makefile: fix bug in install section - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libdmmp/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libdmmp/Makefile b/libdmmp/Makefile -index 078eca8f..172ba045 100644 ---- a/libdmmp/Makefile -+++ b/libdmmp/Makefile -@@ -44,7 +44,7 @@ install: - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) - $(Q)sed -i 's|__INCLUDEDIR__|$(includedir)|g' \ - $(DESTDIR)$(pkgconfdir)/$(PKGFILE) -- $(Q)$(INSTALL_PROGRAM) -d 755 $(DESTDIR)$(mandir)/man3 -+ $(Q)$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(mandir)/man3 - $(Q)$(INSTALL_PROGRAM) -m 644 -t $(DESTDIR)$(mandir)/man3 docs/man/*.3 - - uninstall: diff --git a/0033-multipath-tools-README.md-improve-documentation-for-.patch b/0033-multipath-tools-README.md-improve-documentation-for-.patch deleted file mode 100644 index 3c7edd0..0000000 --- a/0033-multipath-tools-README.md-improve-documentation-for-.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 10:22:13 +0200 -Subject: [PATCH] multipath-tools: README.md: improve documentation for - compile-time options - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - README.md | 38 ++++++++++++++++++++++++++------------ - 1 file changed, 26 insertions(+), 12 deletions(-) - -diff --git a/README.md b/README.md -index a7f994ae..679e55bf 100644 ---- a/README.md -+++ b/README.md -@@ -89,9 +89,17 @@ The following variables can be passed to the `make` command line: - * `plugindir="/some/path"`: directory where libmultipath plugins (path - checkers, prioritizers, and foreign multipath support) will be looked up. - This used to be the run-time option `multipath_dir` in earlier versions. -- * `configdir="/some/path"` : directory to search for configuration files. -+ The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on -+ systems that have `/lib64`, and `lib` otherwise. -+ * `configfile="/some/path`": The path to the main configuration file. -+ The defalt is `$(etc_prefix)/etc/multipath.conf`. -+ * `configdir="/some/path"` : directory to search for additional configuration files. - This used to be the run-time option `config_dir` in earlier versions. -- The default is `/etc/multipath/conf.d`. -+ The default is `$(etc_prefix)/etc/multipath/conf.d`. -+ * `statedir="/some/path"`: The path of the directory where multipath-tools -+ stores run-time settings that need persist between reboots, such as known -+ WWIDs, user-friendly names, and persistent reservation keys. -+ The default is `$(etc_prefix)/etc/multipath`. - * `READLINE=libedit` or `READLINE=libreadline`: enable command line history - and TAB completion in the interactive mode *(which is entered with `multipathd -k` or `multipathc`)*. - The respective development package will be required for building. -@@ -119,21 +127,27 @@ The following variables can be passed to the `make` command line: - ### Installation Paths - - * `prefix`: The directory prefix for (almost) all files to be installed. -- Distributions may want to set this to `/usr`. -- **Note**: for multipath-tools, unlike many other packages, `prefix` -- defaults to the empty string, which resolves to the root directory (`/`). -+ "Usr-merged" distributions[^systemd] may want to set this to `/usr`. The -+ default is empty (`""`). - * `usr_prefix`: where to install those parts of the code that aren't necessary -- for booting. You may want to set this to `/usr` if `prefix` is empty. -- * `systemd_prefix`: Prefix for systemd-related files. It defaults to `/usr`. -- Some systemd installations use separate `prefix` and `rootprefix`. On such -- a distribution, set `prefix`, and override `unitdir` to use systemd's -- `rootprefix`. -+ for booting. Non-usr-merged distributions[^systemd] may want to set this to -+ `/usr`. The default is `$(prefix)`. -+ * `systemd_prefix`: Prefix for systemd-related files[^systemd]. The default is `/usr`. -+ * `etc_prefix`: The prefix for configuration files. "Usr-merged" -+ distributions with immutable `/usr`[^systemd] may want to set this to -+ `/etc`. The default is `$(prefix)`. - * `LIB`: the subdirectory under `prefix` where shared libraries will be - installed. By default, the makefile uses `/lib64` if this directory is - found on the build system, and `/lib` otherwise. - --See also `configdir` and `plugindir` above. See `Makefile.inc` for more --fine-grained control. -+The options `configdir`, `plugindir`, `configfile`, and `statedir` above can -+be used for setting indvidual paths where the `prefix` variables don't provide -+sufficient control. See `Makefile.inc` for even more fine-grained control. -+ -+[^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. -+ On such a distribution, set `prefix`, and override `unitdir` to use systemd's -+ `rootprefix`. Recent systemd releases generally require everything to be -+ installed under `/usr` (so-called "usr-merged" distribution). On "usr- - - ### Compiler Options - diff --git a/0034-libmultipath-print-built-in-values-for-deprecated-op.patch b/0034-libmultipath-print-built-in-values-for-deprecated-op.patch deleted file mode 100644 index 45e7874..0000000 --- a/0034-libmultipath-print-built-in-values-for-deprecated-op.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 11:36:25 +0200 -Subject: [PATCH] libmultipath: print built-in values for deprecated options - -In the error messages we print when a deprecated option is encountered, -print the compile-time value of the option. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index f81c84aa..dace343d 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -314,14 +314,16 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ - static int deprecated_handler(struct config *conf, vector strvec, const char *file, - int line_nr); - --#define declare_deprecated_handler(option) \ -+#define declare_deprecated_handler(option, default) \ - static int \ - deprecated_ ## option ## _handler (struct config *conf, vector strvec, \ - const char *file, int line_nr) \ - { \ - static bool warned; \ - if (!warned) { \ -- condlog(1, "%s line %d: ignoring deprecated option \"" #option "\"", file, line_nr); \ -+ condlog(1, "%s line %d: ignoring deprecated option \"" \ -+ #option "\", using built-in value: \"%s\"", \ -+ file, line_nr, default); \ - warned = true; \ - } \ - return deprecated_handler(conf, strvec, file, line_nr); \ -@@ -2057,11 +2059,11 @@ snprint_deprecated (struct config *conf, struct strbuf *buff, const void * data) - } - - // Deprecated keywords --declare_deprecated_handler(config_dir) --declare_deprecated_handler(disable_changed_wwids) --declare_deprecated_handler(getuid_callout) --declare_deprecated_handler(multipath_dir) --declare_deprecated_handler(pg_timeout) -+declare_deprecated_handler(config_dir, CONFIG_DIR) -+declare_deprecated_handler(disable_changed_wwids, "yes") -+declare_deprecated_handler(getuid_callout, "(not set)") -+declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) -+declare_deprecated_handler(pg_timeout, "(not set)") - - /* - * If you add or remove a keyword also update multipath/multipath.conf.5 diff --git a/0035-multipath-add-a-missing-newline.patch b/0035-multipath-add-a-missing-newline.patch deleted file mode 100644 index 706b7d3..0000000 --- a/0035-multipath-add-a-missing-newline.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 11:37:37 +0200 -Subject: [PATCH] multipath: add a missing newline - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 45e9745f..b91289e8 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1025,7 +1025,7 @@ main (int argc, char *argv[]) - } - - if (check_alias_settings(conf)) { -- fprintf(stderr, "fatal configuration error, aborting"); -+ fprintf(stderr, "fatal configuration error, aborting\n"); - exit(RTVL_FAIL); - } - diff --git a/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch b/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch deleted file mode 100644 index c48240b..0000000 --- a/0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 16:03:34 +0200 -Subject: [PATCH] multipath-tools: allow prefixes with and w/o trailing slash - -Add some logic to Makefile.inc that leads to the same result -for "prefix=" and "prefix=/", or "prefix=/usr" and "prefix=/usr/". -The logic does not work for multiple trailing slashes. It applies -to all XYZ_prefix variables in Makefile.inc. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 35 ++++++++++++++++++++++------------- - 1 file changed, 22 insertions(+), 13 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 79e521e1..6e384e68 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -43,22 +43,31 @@ etc_prefix := $(prefix) - # Note: some systemd installations use separate "prefix" and "rootprefix". - # In this case, override only unitdir to use systemd's "rootprefix" instead of $(systemd_prefix) - systemd_prefix := /usr --unitdir := $(systemd_prefix)/lib/systemd/system --tmpfilesdir := $(systemd_prefix)/lib/tmpfiles.d --modulesloaddir := $(systemd_prefix)/lib/modules-load.d --libudevdir := $(systemd_prefix)/lib/udev -+ -+# Make sure all prefix variables end in "/" -+append-slash = $(1)$(if $(filter %/,$(1)),,/) -+override prefix := $(call append-slash,$(prefix)) -+override exec_prefix := $(call append-slash,$(exec_prefix)) -+override usr_prefix := $(call append-slash,$(usr_prefix)) -+override etc_prefix := $(call append-slash,$(etc_prefix)) -+override systemd_prefix := $(call append-slash,$(systemd_prefix)) -+ -+unitdir := $(systemd_prefix)lib/systemd/system -+tmpfilesdir := $(systemd_prefix)lib/tmpfiles.d -+modulesloaddir := $(systemd_prefix)lib/modules-load.d -+libudevdir := $(systemd_prefix)lib/udev - udevrulesdir := $(libudevdir)/rules.d --bindir := $(exec_prefix)/sbin --mandir := $(usr_prefix)/share/man -+bindir := $(exec_prefix)sbin -+mandir := $(usr_prefix)share/man - LIB := $(if $(shell test -d /lib64 && echo 1),lib64,lib) --syslibdir := $(prefix)/$(LIB) --usrlibdir := $(usr_prefix)/$(LIB) --includedir := $(usr_prefix)/include -+syslibdir := $(prefix)$(LIB) -+usrlibdir := $(usr_prefix)$(LIB) -+includedir := $(usr_prefix)include - pkgconfdir := $(usrlibdir)/pkgconfig --plugindir := $(prefix)/$(LIB)/multipath --configdir := $(etc_prefix)/etc/multipath/conf.d --configfile := $(etc_prefix)/etc/multipath.conf --statedir := $(etc_prefix)/etc/multipath -+plugindir := $(prefix)$(LIB)/multipath -+configdir := $(etc_prefix)etc/multipath/conf.d -+configfile := $(etc_prefix)etc/multipath.conf -+statedir := $(etc_prefix)etc/multipath - runtimedir := $(if $(shell test -L /var/run -o ! -d /var/run && echo 1),/run,/var/run) - devmapper_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir devmapper),/usr/include) - libudev_incdir := $(or $(shell $(PKG_CONFIG) --variable=includedir libudev),/usr/include) diff --git a/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch b/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch deleted file mode 100644 index 6e066ee..0000000 --- a/0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch +++ /dev/null @@ -1,897 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 Sep 2023 17:58:13 +0200 -Subject: [PATCH] libmultipath: deprecate bindings_file, wwids_file, - prkeys_file - -The options bindings_file, wwids_file, and prkeys_file have been -deprecated since cb4d6db ("libmultipath: deprecate file and directory config -options") (multipath-tools 0.8.8). Deprecate and ignore them now. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/alias.c | 43 +++++++++---------- - libmultipath/alias.h | 3 +- - libmultipath/config.c | 18 -------- - libmultipath/config.h | 3 -- - libmultipath/dict.c | 39 +++--------------- - libmultipath/libmultipath.version | 8 +--- - libmultipath/prkey.c | 7 ++-- - libmultipath/prkey.h | 7 ++-- - libmultipath/propsel.c | 5 +-- - libmultipath/wwids.c | 18 ++------ - multipath/main.c | 2 +- - multipath/multipath.conf.5.in | 23 +++++------ - multipathd/uxlsnr.c | 17 +++----- - tests/alias.c | 68 +++++++++++++++---------------- - 14 files changed, 90 insertions(+), 171 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 964b8a7b..e5d3f151 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -55,6 +55,8 @@ - /* uatomic access only */ - static int bindings_file_changed = 1; - -+static const char bindings_file_path[] = DEFAULT_BINDINGS_FILE; -+ - static pthread_mutex_t timestamp_mutex = PTHREAD_MUTEX_INITIALIZER; - static struct timespec bindings_last_updated; - -@@ -274,7 +276,6 @@ static int write_bindings_file(const Bindings *bindings, int fd, - - void handle_bindings_file_inotify(const struct inotify_event *event) - { -- struct config *conf; - const char *base; - bool changed = false; - struct stat st; -@@ -284,12 +285,9 @@ void handle_bindings_file_inotify(const struct inotify_event *event) - if (!(event->mask & IN_MOVED_TO)) - return; - -- conf = get_multipath_config(); -- base = strrchr(conf->bindings_file, '/'); -- changed = base && base > conf->bindings_file && -- !strcmp(base + 1, event->name); -- ret = stat(conf->bindings_file, &st); -- put_multipath_config(conf); -+ base = strrchr(bindings_file_path, '/'); -+ changed = base && !strcmp(base + 1, event->name); -+ ret = stat(bindings_file_path, &st); - - if (!changed) - return; -@@ -310,8 +308,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) - __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); - } - --static int update_bindings_file(const Bindings *bindings, -- const char *bindings_file) -+static int update_bindings_file(const Bindings *bindings) - { - int rc; - int fd = -1; -@@ -319,7 +316,7 @@ static int update_bindings_file(const Bindings *bindings, - mode_t old_umask; - struct timespec ts; - -- if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file)) -+ if (safe_sprintf(tempname, "%s.XXXXXX", bindings_file_path)) - return -1; - /* coverity: SECURE_TEMP */ - old_umask = umask(0077); -@@ -336,13 +333,13 @@ static int update_bindings_file(const Bindings *bindings, - unlink(tempname); - return rc; - } -- if ((rc = rename(tempname, bindings_file)) == -1) -+ if ((rc = rename(tempname, bindings_file_path)) == -1) - condlog(0, "%s: rename: %m", __func__); - else { - pthread_mutex_lock(×tamp_mutex); - bindings_last_updated = ts; - pthread_mutex_unlock(×tamp_mutex); -- condlog(1, "updated bindings file %s", bindings_file); -+ condlog(1, "updated bindings file %s", bindings_file_path); - } - return rc; - } -@@ -474,7 +471,7 @@ int get_free_id(const Bindings *bindings, const char *prefix, const char *map_ww - - /* Called with binding_mutex held */ - static char * --allocate_binding(const char *filename, const char *wwid, int id, const char *prefix) -+allocate_binding(const char *wwid, int id, const char *prefix) - { - STRBUF_ON_STACK(buf); - char *alias; -@@ -498,7 +495,7 @@ allocate_binding(const char *filename, const char *wwid, int id, const char *pre - return NULL; - } - -- if (update_bindings_file(&global_bindings, filename) == -1) { -+ if (update_bindings_file(&global_bindings) == -1) { - condlog(1, "%s: deleting binding %s for %s", __func__, alias, wwid); - delete_binding(&global_bindings, wwid); - free(alias); -@@ -565,7 +562,7 @@ static void read_bindings_file(void) - * that the mpvec corrcectly represents kernel state. - */ - --char *get_user_friendly_alias(const char *wwid, const char *file, const char *alias_old, -+char *get_user_friendly_alias(const char *wwid, const char *alias_old, - const char *prefix, bool bindings_read_only) - { - char *alias = NULL; -@@ -622,7 +619,7 @@ new_alias: - } - - if (!bindings_read_only && id > 0) -- alias = allocate_binding(file, wwid, id, prefix); -+ alias = allocate_binding(wwid, id, prefix); - - if (alias && !new_binding) - condlog(2, "Allocated existing binding [%s] for WWID [%s]", -@@ -715,12 +712,12 @@ static int _check_bindings_file(const struct config *conf, FILE *file, - header[sizeof(BINDINGS_FILE_HEADER) - 1] = '\0'; - if (fread(header, sizeof(BINDINGS_FILE_HEADER) - 1, 1, file) < 1) { - condlog(2, "%s: failed to read header from %s", __func__, -- conf->bindings_file); -+ bindings_file_path); - fseek(file, 0, SEEK_SET); - rc = -1; - } else if (strcmp(header, BINDINGS_FILE_HEADER)) { - condlog(2, "%s: invalid header in %s", __func__, -- conf->bindings_file); -+ bindings_file_path); - fseek(file, 0, SEEK_SET); - rc = -1; - } -@@ -787,13 +784,13 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, - } - } - -- fd = open_file(conf->bindings_file, &can_write, BINDINGS_FILE_HEADER); -+ fd = open_file(bindings_file_path, &can_write, BINDINGS_FILE_HEADER); - if (fd == -1) - return BINDINGS_FILE_ERROR; - - file = fdopen(fd, "r"); - if (file != NULL) { -- condlog(3, "%s: reading %s", __func__, conf->bindings_file); -+ condlog(3, "%s: reading %s", __func__, bindings_file_path); - - pthread_cleanup_push(cleanup_fclose, file); - ret = _check_bindings_file(conf, file, bindings); -@@ -812,20 +809,20 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, - bindings_last_updated = ts; - pthread_mutex_unlock(×tamp_mutex); - } else if (ret == -1 && can_write && !conf->bindings_read_only) { -- ret = update_bindings_file(bindings, conf->bindings_file); -+ ret = update_bindings_file(bindings); - if (ret == 0) - rc = BINDINGS_FILE_READ; - else - rc = BINDINGS_FILE_BAD; - } else { - condlog(0, "ERROR: bad settings in read-only bindings file %s", -- conf->bindings_file); -+ bindings_file_path); - rc = BINDINGS_FILE_BAD; - } - pthread_cleanup_pop(1); - } else { - condlog(1, "failed to fdopen %s: %m", -- conf->bindings_file); -+ bindings_file_path); - close(fd); - rc = BINDINGS_FILE_ERROR; - } -diff --git a/libmultipath/alias.h b/libmultipath/alias.h -index ca8911f4..629e8d56 100644 ---- a/libmultipath/alias.h -+++ b/libmultipath/alias.h -@@ -3,8 +3,7 @@ - - int valid_alias(const char *alias); - int get_user_friendly_wwid(const char *alias, char *buff); --char *get_user_friendly_alias(const char *wwid, const char *file, -- const char *alias_old, -+char *get_user_friendly_alias(const char *wwid, const char *alias_old, - const char *prefix, bool bindings_read_only); - - struct config; -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 7b207590..b7dbc6f5 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -752,15 +752,6 @@ static void _uninit_config(struct config *conf) - if (conf->hwhandler) - free(conf->hwhandler); - -- if (conf->bindings_file) -- free(conf->bindings_file); -- -- if (conf->wwids_file) -- free(conf->wwids_file); -- -- if (conf->prkeys_file) -- free(conf->prkeys_file); -- - if (conf->prio_name) - free(conf->prio_name); - -@@ -922,9 +913,6 @@ int _init_config (const char *file, struct config *conf) - * internal defaults - */ - get_sys_max_fds(&conf->max_fds); -- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); -- conf->wwids_file = set_default(DEFAULT_WWIDS_FILE); -- conf->prkeys_file = set_default(DEFAULT_PRKEYS_FILE); - conf->attribute_flags = 0; - conf->reassign_maps = DEFAULT_REASSIGN_MAPS; - conf->checkint = CHECKINT_UNDEF; -@@ -1078,12 +1066,6 @@ int _init_config (const char *file, struct config *conf) - merge_blacklist(conf->elist_wwid); - merge_blacklist_device(conf->elist_device); - -- if (conf->bindings_file == NULL) -- conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE); -- -- if (!conf->bindings_file || !conf->wwids_file || !conf->prkeys_file) -- goto out; -- - libmp_verbosity = conf->verbosity; - return 0; - out: -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 0a2c297b..8c22ce75 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -207,9 +207,6 @@ struct config { - char * uid_attribute; - char * features; - char * hwhandler; -- char * bindings_file; -- char * wwids_file; -- char * prkeys_file; - char * prio_name; - char * prio_args; - char * checker_name; -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index dace343d..044067af 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -168,27 +168,6 @@ fail: - return 0; - } - --static int --set_path(vector strvec, void *ptr, const char *file, int line_nr) --{ -- char **str_ptr = (char **)ptr; -- char *old_str = *str_ptr; -- -- *str_ptr = set_value(strvec); -- if (!*str_ptr) { -- free(old_str); -- return 1; -- } -- if ((*str_ptr)[0] != '/'){ -- condlog(1, "%s line %d, %s is not an absolute path. Ignoring", -- file, line_nr, *str_ptr); -- free(*str_ptr); -- *str_ptr = old_str; -- } else -- free(old_str); -- return 0; --} -- - static int - set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) - { -@@ -831,15 +810,6 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) - declare_mp_handler(user_friendly_names, set_yes_no_undef) - declare_mp_snprint(user_friendly_names, print_yes_no_undef) - --declare_def_warn_handler(bindings_file, set_path) --declare_def_snprint(bindings_file, print_str) -- --declare_def_warn_handler(wwids_file, set_path) --declare_def_snprint(wwids_file, print_str) -- --declare_def_warn_handler(prkeys_file, set_path) --declare_def_snprint(prkeys_file, print_str) -- - declare_def_handler(retain_hwhandler, set_yes_no_undef) - declare_def_snprint_defint(retain_hwhandler, print_yes_no_undef, - DEFAULT_RETAIN_HWHANDLER) -@@ -2064,6 +2034,9 @@ declare_deprecated_handler(disable_changed_wwids, "yes") - declare_deprecated_handler(getuid_callout, "(not set)") - declare_deprecated_handler(multipath_dir, MULTIPATH_DIR) - declare_deprecated_handler(pg_timeout, "(not set)") -+declare_deprecated_handler(bindings_file, DEFAULT_BINDINGS_FILE) -+declare_deprecated_handler(wwids_file, DEFAULT_WWIDS_FILE) -+declare_deprecated_handler(prkeys_file, DEFAULT_PRKEYS_FILE) - - /* - * If you add or remove a keyword also update multipath/multipath.conf.5 -@@ -2106,9 +2079,9 @@ init_keywords(vector keywords) - install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); - install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); - install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline); -- install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file); -- install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file); -- install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); -+ install_keyword("bindings_file", &deprecated_bindings_file_handler, &snprint_deprecated); -+ install_keyword("wwids_file", &deprecated_wwids_file_handler, &snprint_deprecated); -+ install_keyword("prkeys_file", &deprecated_prkeys_file_handler, &snprint_deprecated); - install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err); - install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key); - install_keyword("all_tg_pt", &def_all_tg_pt_handler, &snprint_def_all_tg_pt); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 57e50c12..8368ef7a 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { - put_multipath_config; - }; - --LIBMULTIPATH_20.0.0 { -+LIBMULTIPATH_21.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; -@@ -121,6 +121,7 @@ global: - get_used_hwes; - get_vpd_sgio; - group_by_prio; -+ handle_bindings_file_inotify; - has_dm_info; - init_checkers; - init_config; -@@ -238,8 +239,3 @@ global: - local: - *; - }; -- --LIBMULTIPATH_20.1.0 { --global: -- handle_bindings_file_inotify; --}; -diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c -index a215499d..c66d293b 100644 ---- a/libmultipath/prkey.c -+++ b/libmultipath/prkey.c -@@ -157,8 +157,7 @@ static int do_prkey(int fd, char *wwid, char *keystr, int cmd) - return 0; - } - --int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, -- uint8_t *sa_flags) -+int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags) - { - int fd; - int unused; -@@ -168,7 +167,7 @@ int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, - if (!strlen(mpp->wwid)) - goto out; - -- fd = open_file(conf->prkeys_file, &unused, PRKEYS_FILE_HEADER); -+ fd = open_file(DEFAULT_PRKEYS_FILE, &unused, PRKEYS_FILE_HEADER); - if (fd < 0) - goto out; - ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ); -@@ -201,7 +200,7 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, - sa_flags &= MPATH_F_APTPL_MASK; - } - -- fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER); -+ fd = open_file(DEFAULT_PRKEYS_FILE, &can_write, PRKEYS_FILE_HEADER); - if (fd < 0) - goto out; - if (!can_write) { -diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h -index a16de106..43afd5e4 100644 ---- a/libmultipath/prkey.h -+++ b/libmultipath/prkey.h -@@ -16,9 +16,8 @@ - int print_reservation_key(struct strbuf *buff, - struct be64 key, uint8_t flags, int source); - int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); --int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, -- uint8_t sa_flags); --int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, -- uint8_t *sa_flags); -+int set_prkey(struct config *conf, struct multipath *mpp, -+ uint64_t prkey, uint8_t sa_flags); -+int get_prkey(struct multipath *mpp, uint64_t *prkey, uint8_t *sa_flags); - - #endif /* _PRKEY_H */ -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 354e883f..44241e2a 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -401,8 +401,7 @@ int select_alias(struct config *conf, struct multipath * mp) - - select_alias_prefix(conf, mp); - -- mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, -- mp->alias_old, mp->alias_prefix, -+ mp->alias = get_user_friendly_alias(mp->wwid, mp->alias_old, mp->alias_prefix, - conf->bindings_read_only); - - if (mp->alias && !strncmp(mp->alias, mp->alias_old, WWID_SIZE)) -@@ -992,7 +991,7 @@ int select_reservation_key(struct config *conf, struct multipath *mp) - out: - if (mp->prkey_source == PRKEY_SOURCE_FILE) { - from_file = " (from prkeys file)"; -- if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0) -+ if (get_prkey(mp, &prkey, &mp->sa_flags) != 0) - put_be64(mp->reservation_key, 0); - else - put_be64(mp->reservation_key, prkey); -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 89bb60ca..591cd09b 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -94,12 +94,8 @@ replace_wwids(vector mp) - struct multipath * mpp; - size_t len; - int ret = -1; -- struct config *conf; - -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); -- pthread_cleanup_pop(1); -+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); - if (fd < 0) - goto out; - -@@ -200,7 +196,6 @@ remove_wwid(char *wwid) { - int len, can_write; - char *str; - int ret = -1; -- struct config *conf; - - len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */ - str = malloc(len); -@@ -216,10 +211,7 @@ remove_wwid(char *wwid) { - goto out; - } - condlog(3, "removing line '%s' from wwids file", str); -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); -- pthread_cleanup_pop(1); -+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); - - if (fd < 0) { - ret = -1; -@@ -244,12 +236,8 @@ check_wwids_file(char *wwid, int write_wwid) - { - int fd, can_write, found, ret; - FILE *f; -- struct config *conf; - -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER); -- pthread_cleanup_pop(1); -+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); - if (fd < 0) - return -1; - -diff --git a/multipath/main.c b/multipath/main.c -index b91289e8..9e1c5052 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -856,7 +856,7 @@ main (int argc, char *argv[]) - libmp_verbosity = atoi(optarg); - break; - case 'b': -- conf->bindings_file = strdup(optarg); -+ condlog(1, "option -b ignored"); - break; - case 'B': - conf->bindings_read_only = 1; -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 20df2232..d320a88f 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -794,35 +794,28 @@ The default is: \fB\fR - . - .TP - .B bindings_file --(Deprecated) This option is deprecated, and will be removed in a future release. --The full pathname of the binding file to be used when the user_friendly_names --option is set. -+(Deprecated) This option is not supported any more, and will be ignored. - .RS - .TP --The default is: \fB@STATE_DIR@/bindings\fR -+The compiled-in value is: \fB@STATE_DIR@/bindings\fR - .RE - . - . - .TP - .B wwids_file --(Deprecated) This option is deprecated, and will be removed in a future release. --The full pathname of the WWIDs file, which is used by multipath to keep track --of the WWIDs for LUNs it has created multipath devices on in the past. -+(Deprecated) This option is not supported any more, and will be ignored. - .RS - .TP --The default is: \fB@STATE_DIR@/wwids\fR -+The compiled-in value is: \fB@STATE_DIR@/wwids\fR - .RE - . - . - .TP - .B prkeys_file --(Deprecated) This option is deprecated, and will be removed in a future release. --The full pathname of the prkeys file, which is used by multipathd to keep --track of the persistent reservation key used for a specific WWID, when --\fIreservation_key\fR is set to \fBfile\fR. -+(Deprecated) This option is not supported any more, and will be ignored. - .RS - .TP --The default is: \fB@STATE_DIR@/prkeys\fR -+The compiled-in value is: \fB@STATE_DIR@/prkeys\fR - .RE - . - . -@@ -989,6 +982,10 @@ The default is: \fB\fR - .TP - .B config_dir - (Deprecated) This option is not supported any more, and the value is ignored. -+.RS -+.TP -+The compiled-in value is: \fB@CONFIGDIR@\fR -+.RE - . - . - .TP -diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c -index d1f8f234..4d6f258c 100644 ---- a/multipathd/uxlsnr.c -+++ b/multipathd/uxlsnr.c -@@ -203,7 +203,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - int dir_reset = 0; - int conf_reset = 0; - int mp_reset = 0; -- char *bindings_file __attribute__((cleanup(cleanup_charp))) = NULL; - - if (notify_fd == -1) - return; -@@ -221,7 +220,6 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - if (wds->mp_wd == -1) - mp_reset = 1; - } -- bindings_file = strdup(conf->bindings_file); - put_multipath_config(conf); - - if (dir_reset) { -@@ -242,17 +240,12 @@ static void reset_watch(int notify_fd, struct watch_descriptors *wds, - if (wds->conf_wd == -1) - condlog(3, "didn't set up notifications on /etc/multipath.conf: %m"); - } -- if (mp_reset && bindings_file) { -- char *slash = strrchr(bindings_file, '/'); -- -- if (slash && slash > bindings_file) { -- *slash = '\0'; -- wds->mp_wd = inotify_add_watch(notify_fd, bindings_file, -- IN_MOVED_TO|IN_ONLYDIR); -- if (wds->mp_wd == -1) -+ if (mp_reset) { -+ wds->mp_wd = inotify_add_watch(notify_fd, STATE_DIR, -+ IN_MOVED_TO|IN_ONLYDIR); -+ if (wds->mp_wd == -1) - condlog(3, "didn't set up notifications on %s: %m", -- bindings_file); -- } -+ STATE_DIR); - } - } - -diff --git a/tests/alias.c b/tests/alias.c -index 94df36d8..f893d174 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -1264,10 +1264,10 @@ static void al_a(void **state) - will_return(__wrap_write, ln); - will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); - will_return(__wrap_rename, 0); -- expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); - expect_condlog(3, NEW_STR("MPATHa", "WWIDa")); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); - check_bindings_size(1); -@@ -1283,10 +1283,10 @@ static void al_zz(void **state) - will_return(__wrap_write, ln); - will_return(__wrap_write, strlen(BINDINGS_FILE_HEADER) + strlen(ln)); - will_return(__wrap_rename, 0); -- expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); - expect_condlog(3, NEW_STR("MPATHzz", "WWIDzz")); - -- alias = allocate_binding("foo", "WWIDzz", 26*26 + 26, "MPATH"); -+ alias = allocate_binding("WWIDzz", 26*26 + 26, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHzz"); - check_bindings_size(1); -@@ -1298,7 +1298,7 @@ static void al_0(void **state) - char *alias; - - expect_condlog(0, "allocate_binding: cannot allocate new binding for id 0\n"); -- alias = allocate_binding(0, "WWIDa", 0, "MPATH"); -+ alias = allocate_binding("WWIDa", 0, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1308,7 +1308,7 @@ static void al_m2(void **state) - char *alias; - - expect_condlog(0, "allocate_binding: cannot allocate new binding for id -2\n"); -- alias = allocate_binding(0, "WWIDa", -2, "MPATH"); -+ alias = allocate_binding("WWIDa", -2, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1325,10 +1325,10 @@ static void al_write_partial(void **state) - will_return(__wrap_write, ln + sizeof(ln) - 2); - will_return(__wrap_write, 1); - will_return(__wrap_rename, 0); -- expect_condlog(1, "updated bindings file foo"); -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); - expect_condlog(3, "Created new binding [MPATHa] for WWID [WWIDa]\n"); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); - check_bindings_size(1); -@@ -1350,7 +1350,7 @@ static void al_write_short(void **state) - expect_condlog(1, "failed to write new bindings file"); - expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1366,7 +1366,7 @@ static void al_write_err(void **state) - expect_condlog(1, "failed to write new bindings file"); - expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); - -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1383,7 +1383,7 @@ static void al_rename_err(void **state) - - expect_condlog(0, "update_bindings_file: rename: Read-only file system"); - expect_condlog(1, "allocate_binding: deleting binding MPATHa for WWIDa"); -- alias = allocate_binding("foo", "WWIDa", 1, "MPATH"); -+ alias = allocate_binding("WWIDa", 1, "MPATH"); - assert_ptr_equal(alias, NULL); - check_bindings_size(0); - } -@@ -1415,7 +1415,7 @@ static int test_allocate_binding(void) - strlen(BINDINGS_FILE_HEADER) + (len) + strlen(ln)); \ - will_return(__wrap_rename, err); \ - if (err == 0) { \ -- expect_condlog(1, "updated bindings file x\n"); \ -+ expect_condlog(1, "updated bindings file " DEFAULT_BINDINGS_FILE); \ - expect_condlog(3, NEW_STR(alias, wwid)); \ - } else { \ - expect_condlog(0, "update_bindings_file: rename: " msg "\n"); \ -@@ -1441,7 +1441,7 @@ static void gufa_empty_new_rw(void **state) { - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - - mock_allocate_binding("MPATHa", "WWID0"); -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1454,7 +1454,7 @@ static void gufa_empty_new_ro_1(void **state) { - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_allocate_binding_err("MPATHa", "WWID0", -EROFS, "Read-only file system"); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); - assert_ptr_equal(alias, NULL); - } - -@@ -1465,7 +1465,7 @@ static void gufa_empty_new_ro_2(void **state) { - expect_condlog(3, NOMATCH_WWID_STR("WWID0")); - mock_unused_alias("MPATHa"); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_ptr_equal(alias, NULL); - } - -@@ -1477,7 +1477,7 @@ static void gufa_match_a_unused(void **state) { - mock_unused_alias("MPATHa"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1490,7 +1490,7 @@ static void gufa_match_a_self(void **state) { - mock_self_alias("MPATHa", "WWID0"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1503,7 +1503,7 @@ static void gufa_match_a_used(void **state) { - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", true); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", true); - assert_ptr_equal(alias, NULL); - } - -@@ -1518,7 +1518,7 @@ static void gufa_nomatch_a_c(void **state) { - - mock_allocate_binding_len("MPATHb", "WWID1", strlen(bindings)); - -- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); - } -@@ -1534,7 +1534,7 @@ static void gufa_nomatch_c_a(void **state) { - - mock_allocate_binding_len("MPATHb", "WWID1", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID1", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID1", "", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); - } -@@ -1550,7 +1550,7 @@ static void gufa_nomatch_c_b(void **state) { - - mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID0", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1567,7 +1567,7 @@ static void gufa_nomatch_c_b_used(void **state) { - - mock_allocate_binding_len("MPATHd", "WWID4", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID4", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID4", "", "MPATH", false); - assert_string_equal(alias, "MPATHd"); - free(alias); - } -@@ -1584,7 +1584,7 @@ static void gufa_nomatch_b_f_a(void **state) { - - mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); - assert_string_equal(alias, "MPATHc"); - free(alias); - } -@@ -1599,7 +1599,7 @@ static void gufa_nomatch_b_aa_a(void **state) { - mock_unused_alias("MPATHab"); - mock_allocate_binding_len("MPATHab", "WWID28", get_strbuf_len(&buf)); - -- alias = get_user_friendly_alias("WWID28", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID28", "", "MPATH", false); - assert_string_equal(alias, "MPATHab"); - free(alias); - } -@@ -1616,7 +1616,7 @@ static void gufa_nomatch_b_f_a_sorted(void **state) { - - mock_allocate_binding_len("MPATHc", "WWID7", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID7", "x", "", "MPATH", false); -+ alias = get_user_friendly_alias("WWID7", "", "MPATH", false); - assert_string_equal(alias, "MPATHc"); - free(alias); - } -@@ -1632,7 +1632,7 @@ static void gufa_old_empty(void **state) { - mock_allocate_binding("MPATHz", "WWID0"); - expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHz"); - free(alias); - } -@@ -1644,7 +1644,7 @@ static void gufa_old_match(void **state) { - "MPATHz WWID0"); - expect_condlog(3, FOUND_ALIAS_STR("MPATHz", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHz"); - free(alias); - } -@@ -1661,7 +1661,7 @@ static void gufa_old_match_other(void **state) { - - mock_allocate_binding_len("MPATHa", "WWID0", sizeof(bindings) - 1); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1678,7 +1678,7 @@ static void gufa_old_match_other_used(void **state) { - mock_unused_alias("MPATHb"); - - mock_allocate_binding_len("MPATHb", "WWID0", sizeof(bindings) - 1); -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHb"); - free(alias); - } -@@ -1695,7 +1695,7 @@ static void gufa_old_match_other_wwidmatch(void **state) { - mock_unused_alias("MPATHc"); - expect_condlog(3, EXISTING_STR("MPATHc", "WWID2")); - -- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHc"); - free(alias); - } -@@ -1711,7 +1711,7 @@ static void gufa_old_match_other_wwidmatch_used(void **state) { - expect_condlog(3, FOUND_STR("MPATHc", "WWID2")); - mock_used_alias("MPATHc", "WWID2"); - -- alias = get_user_friendly_alias("WWID2", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID2", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); - } - -@@ -1725,7 +1725,7 @@ static void gufa_old_nomatch_wwidmatch(void **state) { - mock_unused_alias("MPATHa"); - expect_condlog(3, EXISTING_STR("MPATHa", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHa"); - free(alias); - } -@@ -1739,7 +1739,7 @@ static void gufa_old_nomatch_wwidmatch_used(void **state) { - expect_condlog(3, FOUND_STR("MPATHa", "WWID0")); - mock_used_alias("MPATHa", "WWID0"); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_ptr_equal(alias, NULL); - } - -@@ -1754,7 +1754,7 @@ static void gufa_old_nomatch_nowwidmatch(void **state) { - mock_allocate_binding_len("MPATHz", "WWID0", sizeof(bindings) - 1); - expect_condlog(2, ALLOC_STR("MPATHz", "WWID0")); - -- alias = get_user_friendly_alias("WWID0", "x", "MPATHz", "MPATH", false); -+ alias = get_user_friendly_alias("WWID0", "MPATHz", "MPATH", false); - assert_string_equal(alias, "MPATHz"); - free(alias); - } diff --git a/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch b/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch deleted file mode 100644 index 269efcf..0000000 --- a/0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 Sep 2023 11:54:47 +0200 -Subject: [PATCH] libmultipath: avoid -Warray-bounds error in uatomic - operations - -The use of uatomic_xchg() in alias.c causes a -Warray-bounds error -on distributions using gcc 12, such as Fedora 37. This is a similar -error to 2534c4f ("libmultipath: avoid -Warray-bounds error with gcc -12 and musl libc"). This happens only with liburcu 0.13 and earlier, -and only with certain gcc versions. See liburcu commit 835b9ab -("Fix: x86 and s390 uatomic: __hp() macro warning with gcc 11"). - -Enhance the fix for 2534c4f by a adding a workaround for uatomic_xchg(), -and introduce the macro URCU_VERSION (originally only used for multipathd) -globally. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - create-config.mk | 5 +++++ - libmultipath/alias.c | 5 +++-- - libmultipath/lock.h | 21 +++++++++++++-------- - multipathd/Makefile | 2 -- - 5 files changed, 22 insertions(+), 13 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 6e384e68..04bfa56e 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -95,7 +95,7 @@ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 - WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) --CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) \ -+CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -diff --git a/create-config.mk b/create-config.mk -index d1255971..4d318b96 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -73,6 +73,10 @@ TEST_URCU_TYPE_LIMITS = $(shell \ - $(CC) -c -Werror=type-limits -o /dev/null -xc - 2>/dev/null \ - || echo -Wno-type-limits ) - -+URCU_VERSION = $(shell \ -+ $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ -+ awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') -+ - DEFINES := - - ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0) -@@ -168,6 +172,7 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h - @echo creating $@ - @echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@ - @echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@ -+ @echo "D_URCU_VERSION := $(call URCU_VERSION)" >>$@ - @echo "SYSTEMD := $(SYSTEMD)" >>$@ - @echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@ - @echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@ -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index e5d3f151..74431f3f 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -24,6 +24,7 @@ - #include "devmapper.h" - #include "strbuf.h" - #include "time-util.h" -+#include "lock.h" - - /* - * significant parts of this file were taken from iscsi-bindings.c of the -@@ -300,7 +301,7 @@ void handle_bindings_file_inotify(const struct inotify_event *event) - pthread_mutex_unlock(×tamp_mutex); - - if (changed) { -- uatomic_xchg(&bindings_file_changed, 1); -+ uatomic_xchg_int(&bindings_file_changed, 1); - condlog(3, "%s: bindings file must be re-read, new timestamp: %ld.%06ld", - __func__, (long)ts.tv_sec, (long)ts.tv_nsec / 1000); - } else -@@ -775,7 +776,7 @@ static int _read_bindings_file(const struct config *conf, Bindings *bindings, - int rc = 0, ret, fd; - FILE *file; - struct stat st; -- int has_changed = uatomic_xchg(&bindings_file_changed, 0); -+ int has_changed = uatomic_xchg_int(&bindings_file_changed, 0); - - if (!force) { - if (!has_changed) { -diff --git a/libmultipath/lock.h b/libmultipath/lock.h -index 9814be76..ac80d1d8 100644 ---- a/libmultipath/lock.h -+++ b/libmultipath/lock.h -@@ -13,15 +13,20 @@ struct mutex_lock { - int waiters; /* uatomic access only */ - }; - --#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 -+static inline void init_lock(struct mutex_lock *a) -+{ -+ pthread_mutex_init(&a->mutex, NULL); -+ uatomic_set(&a->waiters, 0); -+} -+ -+#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Warray-bounds" - #endif - --static inline void init_lock(struct mutex_lock *a) -+static inline int uatomic_xchg_int(int *ptr, int val) - { -- pthread_mutex_init(&a->mutex, NULL); -- uatomic_set(&a->waiters, 0); -+ return uatomic_xchg(ptr, val); - } - - static inline void lock(struct mutex_lock *a) -@@ -31,6 +36,10 @@ static inline void lock(struct mutex_lock *a) - uatomic_dec(&a->waiters); - } - -+#if defined(__GNUC__) && __GNUC__ == 12 && URCU_VERSION < 0xe00 -+#pragma GCC diagnostic pop -+#endif -+ - static inline int trylock(struct mutex_lock *a) - { - return pthread_mutex_trylock(&a->mutex); -@@ -51,10 +60,6 @@ static inline bool lock_has_waiters(struct mutex_lock *a) - return (uatomic_read(&a->waiters) > 0); - } - --#if !defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ == 12 --#pragma GCC diagnostic pop --#endif -- - #define lock_cleanup_pop(a) pthread_cleanup_pop(1) - - void cleanup_lock (void * data); -diff --git a/multipathd/Makefile b/multipathd/Makefile -index cdba3db1..0ba6ecb7 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -5,8 +5,6 @@ CLI := multipathc - MANPAGES := multipathd.8 - - CPPFLAGS += -I$(multipathdir) -I$(mpathutildir) -I$(mpathpersistdir) -I$(mpathcmddir) -I$(thirdpartydir) \ -- $(shell $(PKG_CONFIG) --modversion liburcu 2>/dev/null | \ -- awk -F. '{ printf("-DURCU_VERSION=0x%06x", 256 * ( 256 * $$1 + $$2) + $$3); }') \ - -DBINDIR='"$(bindir)"' $(SYSTEMD_CPPFLAGS) - - # diff --git a/0039-multipath-tools-fix-spelling.patch b/0039-multipath-tools-fix-spelling.patch deleted file mode 100644 index c0c86f9..0000000 --- a/0039-multipath-tools-fix-spelling.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Fri, 15 Sep 2023 22:22:06 +0200 -Subject: [PATCH] multipath-tools: fix spelling - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - README.md | 4 ++-- - multipath/multipath.conf.5.in | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/README.md b/README.md -index 679e55bf..524c9fb1 100644 ---- a/README.md -+++ b/README.md -@@ -92,7 +92,7 @@ The following variables can be passed to the `make` command line: - The default is `$(prefix)/$(LIB)/multipath`, where `$(LIB)` is `lib64` on - systems that have `/lib64`, and `lib` otherwise. - * `configfile="/some/path`": The path to the main configuration file. -- The defalt is `$(etc_prefix)/etc/multipath.conf`. -+ The default is `$(etc_prefix)/etc/multipath.conf`. - * `configdir="/some/path"` : directory to search for additional configuration files. - This used to be the run-time option `config_dir` in earlier versions. - The default is `$(etc_prefix)/etc/multipath/conf.d`. -@@ -141,7 +141,7 @@ The following variables can be passed to the `make` command line: - found on the build system, and `/lib` otherwise. - - The options `configdir`, `plugindir`, `configfile`, and `statedir` above can --be used for setting indvidual paths where the `prefix` variables don't provide -+be used for setting individual paths where the `prefix` variables don't provide - sufficient control. See `Makefile.inc` for even more fine-grained control. - - [^systemd]: Some systemd installations use separate `prefix` and `rootprefix`. -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index d320a88f..226d0019 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -36,7 +36,7 @@ Files ending in \fI.conf\fR in this directory are read - in alphabetical order, after reading \fI@CONFIGFILE@\fR. - They use the same syntax as \fI@CONFIGFILE@\fR itself, - and support all sections and keywords. If a keyword occurs in the same section --in multiple files, the last occurence will take precedence over all others. -+in multiple files, the last occurrence will take precedence over all others. - . - . - .\" ---------------------------------------------------------------------------- diff --git a/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch b/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch deleted file mode 100644 index 7ed50a3..0000000 --- a/0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch +++ /dev/null @@ -1,300 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Muneendra -Date: Wed, 20 Sep 2023 20:41:15 -0700 -Subject: [PATCH] multipathd: Added support to handle FPIN-Li events for - FC-NVMe - - This patch adds the support to handle FPIN-Li for FC-NVMe. - On receiving the FPIN-Li events this patch moves the devices paths - which are affected due to link integrity to marginal path groups. - The paths which are set to marginal path group will be unset - on receiving the RSCN events - -(mwilck: minor compile fix for 32-bit architectures) - -Signed-off-by: Muneendra -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/fpin_handlers.c | 206 +++++++++++++++++++++++++++---------- - 1 file changed, 151 insertions(+), 55 deletions(-) - -diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c -index aa0f63c9..be087ca0 100644 ---- a/multipathd/fpin_handlers.c -+++ b/multipathd/fpin_handlers.c -@@ -60,18 +60,15 @@ static void _udev_device_unref(void *p) - - - /*set/unset the path state to marginal*/ --static int fpin_set_pathstate(struct path *pp, bool set) -+static void fpin_set_pathstate(struct path *pp, bool set) - { - const char *action = set ? "set" : "unset"; - -- if (!pp || !pp->mpp || !pp->mpp->alias) -- return -1; -- -- condlog(3, "\n%s: %s marginal path %s (fpin)", -- action, pp->mpp->alias, pp->dev_t); -+ condlog(3, "%s: %s marginal path %s (fpin)", -+ pp->mpp ? pp->mpp->alias : "orphan", action, pp->dev_t); - pp->marginal = set; -- pp->mpp->fpin_must_reload = true; -- return 0; -+ if (pp->mpp) -+ pp->mpp->fpin_must_reload = true; - } - - /* This will unset marginal state of a device*/ -@@ -82,14 +79,14 @@ static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs) - pp = find_path_by_dev(vecs->pathvec, devname); - if (!pp) - pp = find_path_by_devt(vecs->pathvec, devname); -- -- fpin_set_pathstate(pp, false); -+ if (pp) -+ fpin_set_pathstate(pp, false); - } - - /*This will set the marginal state of a device*/ --static int fpin_path_setmarginal(struct path *pp) -+static void fpin_path_setmarginal(struct path *pp) - { -- return fpin_set_pathstate(pp, true); -+ fpin_set_pathstate(pp, true); - } - - /* Unsets all the devices in the list from marginal state */ -@@ -183,8 +180,8 @@ static void fpin_set_rport_marginal(struct udev_device *rport_dev) - udev_device_get_syspath(rport_dev)); - } - --/*Add the marginal devices info into the list*/ --static void -+/*Add the marginal devices info into the list and return 0 on success*/ -+static int - fpin_add_marginal_dev_info(uint32_t host_num, char *devname) - { - struct marginal_dev_list *newdev = NULL; -@@ -199,65 +196,160 @@ fpin_add_marginal_dev_info(uint32_t host_num, char *devname) - list_add_tail(&(newdev->node), - &fpin_li_marginal_dev_list_head); - pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); -- } -+ } else -+ return -ENOMEM; -+ return 0; - } - - /* -- * This function goes through the vecs->pathvec, and for -- * each path, check that the host number, -- * the target WWPN associated with the path matches -- * with the els wwpn and sets the path and port state to -+ * This function compares Transport Address Controller Port pn, -+ * Host Transport Address Controller Port pn with the els wwpn ,attached_wwpn -+ * and return 1 (match) or 0 (no match) or a negative error code -+ */ -+static int extract_nvme_addresses_chk_path_pwwn(const char *address, -+ uint64_t els_wwpn, uint64_t els_attached_wwpn) -+ -+{ -+ uint64_t traddr; -+ uint64_t host_traddr; -+ -+ /* -+ * Find the position of "traddr=" and "host_traddr=" -+ * and the address will be in the below format -+ * "traddr=nn-0x200400110dff9400:pn-0x200400110dff9400, -+ * host_traddr=nn-0x200400110dff9400:pn-0x200400110dff9400" -+ */ -+ const char *traddr_start = strstr(address, "traddr="); -+ const char *host_traddr_start = strstr(address, "host_traddr="); -+ -+ if (!traddr_start || !host_traddr_start) -+ return -EINVAL; -+ -+ /* Extract traddr pn */ -+ if (sscanf(traddr_start, "traddr=nn-%*[^:]:pn-%" SCNx64, &traddr) != 1) -+ return -EINVAL; -+ -+ /* Extract host_traddr pn*/ -+ if (sscanf(host_traddr_start, "host_traddr=nn-%*[^:]:pn-%" SCNx64, -+ &host_traddr) != 1) -+ return -EINVAL; -+ condlog(4, "traddr 0x%" PRIx64 " hosttraddr 0x%" PRIx64 " els_wwpn 0x%" -+ PRIx64" els_host_traddr 0x%" PRIx64, -+ traddr, host_traddr, -+ els_wwpn, els_attached_wwpn); -+ if ((host_traddr == els_attached_wwpn) && (traddr == els_wwpn)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * This function check that the Transport Address Controller Port pn, -+ * Host Transport Address Controller Port pn associated with the path matches -+ * with the els wwpn ,attached_wwpn and sets the path state to - * Marginal - */ --static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, -+static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp, -+ uint64_t els_wwpn, uint64_t attached_wwpn) -+{ -+ struct udev_device *ctl = NULL; -+ const char *address = NULL; -+ int ret = 0; -+ -+ ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL); -+ if (ctl == NULL) { -+ condlog(2, "%s: No parent device for ", pp->dev); -+ return; -+ } -+ address = udev_device_get_sysattr_value(ctl, "address"); -+ if (!address) { -+ condlog(2, "%s: unable to get the address ", pp->dev); -+ return; -+ } -+ condlog(4, "\n address %s: dev :%s\n", address, pp->dev); -+ ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn); -+ if (ret <= 0) -+ return; -+ ret = fpin_add_marginal_dev_info(host_num, pp->dev); -+ if (ret < 0) -+ return; -+ fpin_path_setmarginal(pp); -+} -+ -+/* -+ * This function check the host number, the target WWPN -+ * associated with the path matches with the els wwpn and -+ * sets the path and port state to Marginal -+ */ -+static void fpin_check_set_scsi_path_marginal(uint16_t host_num, struct path *pp, - uint64_t els_wwpn) - { -- struct path *pp; -- struct multipath *mpp; -- int i, k; - char rport_id[42]; - const char *value = NULL; - struct udev_device *rport_dev = NULL; - uint64_t wwpn; - int ret = 0; -+ sprintf(rport_id, "rport-%d:%d-%d", -+ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -+ rport_dev = udev_device_new_from_subsystem_sysname(udev, -+ "fc_remote_ports", rport_id); -+ if (!rport_dev) { -+ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, -+ rport_id); -+ return; -+ } -+ pthread_cleanup_push(_udev_device_unref, rport_dev); -+ value = udev_device_get_sysattr_value(rport_dev, "port_name"); -+ if (!value) -+ goto unref; -+ -+ wwpn = strtol(value, NULL, 16); -+ /* -+ * If the port wwpn matches sets the path and port state -+ * to marginal -+ */ -+ if (wwpn == els_wwpn) { -+ ret = fpin_add_marginal_dev_info(host_num, pp->dev); -+ if (ret < 0) -+ goto unref; -+ fpin_path_setmarginal(pp); -+ fpin_set_rport_marginal(rport_dev); -+ } -+unref: -+ pthread_cleanup_pop(1); -+ return; -+ -+} -+ -+/* -+ * This function goes through the vecs->pathvec, and for -+ * each path, it checks and sets the path state to marginal -+ * if the path's associated port wwpn ,hostnum matches with -+ * els wwnpn ,attached_wwpn -+ */ -+static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, -+ uint64_t els_wwpn, uint64_t attached_wwpn) -+{ -+ struct path *pp; -+ struct multipath *mpp; -+ int i, k; -+ int ret = 0; - - pthread_cleanup_push(cleanup_lock, &vecs->lock); - lock(&vecs->lock); - pthread_testcancel(); - - vector_foreach_slot(vecs->pathvec, pp, k) { -- /* Checks the host number and also for the SCSI FCP */ -- if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) -+ if (!pp->mpp) - continue; -- sprintf(rport_id, "rport-%d:%d-%d", -- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -- rport_dev = udev_device_new_from_subsystem_sysname(udev, -- "fc_remote_ports", rport_id); -- if (!rport_dev) { -- condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, -- rport_id); -- continue; -- } -- pthread_cleanup_push(_udev_device_unref, rport_dev); -- value = udev_device_get_sysattr_value(rport_dev, "port_name"); -- if (!value) -- goto unref; -- -- if (value) -- wwpn = strtol(value, NULL, 16); -- /* -- * If the port wwpn matches sets the path and port state -- * to marginal -- */ -- if (wwpn == els_wwpn) { -- ret = fpin_path_setmarginal(pp); -- if (ret < 0) -- goto unref; -- fpin_set_rport_marginal(rport_dev); -- fpin_add_marginal_dev_info(host_num, pp->dev); -+ /*checks if the bus type is nvme and the protocol is FC-NVMe*/ -+ if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) { -+ fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn); -+ } else if ((pp->bus == SYSFS_BUS_SCSI) && -+ (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) && -+ (host_num == pp->sg_id.host_no)) { -+ /* Checks the host number and also for the SCSI FCP */ -+ fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn); - } --unref: -- pthread_cleanup_pop(1); - } - /* walk backwards because reload_and_sync_map() can remove mpp */ - vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { -@@ -286,14 +378,18 @@ fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv, - struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; - int count = 0; - int ret = 0; -+ uint64_t attached_wwpn; - - /* Update the wwn to list */ - wwn_count = be32_to_cpu(li_desc->pname_count); -- condlog(4, "Got wwn count as %d\n", wwn_count); -+ attached_wwpn = be64_to_cpu(li_desc->attached_wwpn); -+ condlog(4, "Got wwn count as %d detecting wwn 0x%" PRIx64 -+ " attached_wwpn 0x%" PRIx64 "\n", -+ wwn_count, be64_to_cpu(li_desc->detecting_wwpn), attached_wwpn); - - for (iter = 0; iter < wwn_count; iter++) { - wwpn = be64_to_cpu(li_desc->pname_list[iter]); -- ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn); -+ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn, attached_wwpn); - if (ret < 0) - condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn); - diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 30c0bbf..5a9b492 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,5 +1,5 @@ Name: device-mapper-multipath -Version: 0.9.6 +Version: 0.9.7 Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 @@ -7,62 +7,22 @@ URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.6.tar.gz -o multipath-tools-0.9.6.tgz -Source0: multipath-tools-0.9.6.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.7.tar.gz -o multipath-tools-0.9.7.tgz +Source0: multipath-tools-0.9.7.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-sysfs_set_scsi_tmo-do-nothing-for-ACT_D.patch -Patch0002: 0002-libmultipath-add-alias_already_taken.patch -Patch0003: 0003-libmultipath-unify-use_existing_alias-and-get_user_f.patch -Patch0004: 0004-libmultipath-never-allocate-an-alias-that-s-already-.patch -Patch0005: 0005-libmultipath-lookup_binding-add-comment-about-the-al.patch -Patch0006: 0006-multipath-tools-test-simplify-debugging-for-condlog-.patch -Patch0007: 0007-multipath-tools-tests-add-tests-for-get_user_friendl.patch -Patch0008: 0008-multipath-tools-test-consistent-use-of-macros-in-ali.patch -Patch0009: 0009-multipath-tools-tests-convert-mock_-failed-used-_ali.patch -Patch0010: 0010-multipath-tools-test-use-mock_bindings_file-consiste.patch -Patch0011: 0011-libmultipath-add-global-variable-for-current-binding.patch -Patch0012: 0012-libmultipath-rename-fix_bindings_file-to-update_bind.patch -Patch0013: 0013-libmultipath-alias.c-move-bindings-related-code-up.patch -Patch0014: 0014-libmultipath-update_bindings_file-take-filename-argu.patch -Patch0015: 0015-libmultipath-update_bindings_file-use-a-single-write.patch -Patch0016: 0016-libmultipath-update_bindings_file-don-t-log-temp-fil.patch -Patch0017: 0017-libmultipath-alias.c-factor-out-read_binding.patch -Patch0018: 0018-libmultipath-keep-bindings-in-memory.patch -Patch0019: 0019-multipath-tools-tests-fix-alias-tests.patch -Patch0020: 0020-libmultipath-dm_get_uuid-return-emtpy-UUID-for-non-e.patch -Patch0021: 0021-libmultipath-adapt-to-new-semantics-of-dm_get_uuid.patch -Patch0022: 0022-libmultipath-sort-aliases-by-length-and-strcmp.patch -Patch0023: 0023-multipath-tools-tests-fix-alias-test-after-sort-orde.patch -Patch0024: 0024-libmultipath-simplify-get_free_id-assuming-total-ord.patch -Patch0025: 0025-multipath-tools-tests-adapt-alias-tests-for-total-or.patch -Patch0026: 0026-multipath-tools-tests-add-test-for-ordering-of-bindi.patch -Patch0027: 0027-multipathd-watch-bindings-file-with-inotify-timestam.patch -Patch0028: 0028-multipath-tools-tests-mock-pthread_mutex_-lock-unloc.patch -Patch0029: 0029-multipath-tools-Makefile-sanitize-paths-for-configur.patch -Patch0030: 0030-multipath-tools-add-compile-time-configuration-for-e.patch -Patch0031: 0031-multipath-tools-man-pages-generate-with-correct-path.patch -Patch0032: 0032-libdmmp-Makefile-fix-bug-in-install-section.patch -Patch0033: 0033-multipath-tools-README.md-improve-documentation-for-.patch -Patch0034: 0034-libmultipath-print-built-in-values-for-deprecated-op.patch -Patch0035: 0035-multipath-add-a-missing-newline.patch -Patch0036: 0036-multipath-tools-allow-prefixes-with-and-w-o-trailing.patch -Patch0037: 0037-libmultipath-deprecate-bindings_file-wwids_file-prke.patch -Patch0038: 0038-libmultipath-avoid-Warray-bounds-error-in-uatomic-op.patch -Patch0039: 0039-multipath-tools-fix-spelling.patch -Patch0040: 0040-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch -Patch0041: 0041-RH-fixup-udev-rules-for-redhat.patch -Patch0042: 0042-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0043: 0043-RH-don-t-start-without-a-config-file.patch -Patch0044: 0044-RH-Fix-nvme-function-missing-argument.patch -Patch0045: 0045-RH-use-rpm-optflags-if-present.patch -Patch0046: 0046-RH-add-mpathconf.patch -Patch0047: 0047-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0048: 0048-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0049: 0049-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0050: 0050-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0051: 0051-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0052: 0052-RH-compile-with-libreadline-support.patch -Patch0053: 0053-RH-Add-mpathcleanup.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0013: 0013-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -149,7 +109,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.6 -p1 +%autosetup -n multipath-tools-0.9.7 -p1 cp %{SOURCE1} . %build @@ -212,7 +172,6 @@ fi %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules %dir /usr/lib/modules-load.d -/usr/lib/modules-load.d/multipath.conf /usr/lib/modules-load.d/scsi_dh.conf %{_tmpfilesdir}/multipath.conf %doc README.md @@ -272,6 +231,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 21 2023 Benjamin Marzinski - 0.9.7-1 +- Update source to upstream version 0.9.7 + * Previous patches 0001-0040 are included in the source tarball +- Rename redhat patches + * Previous patches 0041-0053 are now patches 0001-0013 +- Remove /usr/lib/modules-load.d/multipath.conf + * has been replaced with modprobe@dm_multipath.service unit Wants. + * Fri Sep 22 2023 Benjamin Marzinski - 0.9.6-1 - Update to the head of the upstream staging branch - Rename redhat patches diff --git a/sources b/sources index 5d41f65..89f8f37 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.6.tgz) = 17d2b46ead9df6826b3266035bc077a2f4d4bea01e2cd59e32d3917cda40c320f11bc8572da7ba66251e312b46d9be317737069193d481d202d49f9aa5fd71b9 +SHA512 (multipath-tools-0.9.7.tgz) = 0f4c97179a3de5a0c77893fec229eb183293fed8e5e01a9945b261845ccf5d13f8ef2c2ff0c17c9345217d236275caed4765422ec95aed80821f11658bf96e26 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From f52f69af955c7d182060b0ed07f3bda9b0dabd86 Mon Sep 17 00:00:00 2001 From: Paul Donohue Date: Tue, 28 Nov 2023 17:34:41 -0500 Subject: [PATCH 09/33] device-mapper-multipath-0.9.7-2 Modify 0006-RH-add-mpathconf.patch Modify 0008-RH-reset-default-find_mutipaths-value-to-off.patch * Fix find_multipaths values in docs and mpathconf Signed-off-by: Benjamin Marzinski --- 0006-RH-add-mpathconf.patch | 25 ++++++++++--------- ...-default-find_mutipaths-value-to-off.patch | 19 ++++++++++++-- device-mapper-multipath.spec | 7 +++++- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/0006-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch index 7782f65..fd47a6c 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -10,6 +10,7 @@ command line. But, mostly it is used to get a multipath.conf file with the OS defaults, and to enable and disable multipathing via a single command. +Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + @@ -69,7 +70,7 @@ index 504d6892..9f14036c 100644 diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..319664b1 +index 00000000..ce430075 --- /dev/null +++ b/multipath/mpathconf @@ -0,0 +1,658 @@ @@ -106,7 +107,7 @@ index 00000000..319664b1 + +defaults { + user_friendly_names yes -+ find_multipaths yes ++ find_multipaths on +}" + +CONFIGFILE="/etc/multipath.conf" @@ -124,7 +125,7 @@ index 00000000..319664b1 + echo "Disable: --disable" + echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " -+ echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set find_multipaths (Default on): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Set recheck_wwid (Defaut n): --recheck_wwid " @@ -328,11 +329,11 @@ index 00000000..319664b1 + exit 1 + fi + if [ "$FIND" = "y" ]; then -+ FIND="yes" ++ FIND="on" + elif [ "$FIND" = "n" ]; then -+ FIND="no" -+ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then -+ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" ++ FIND="off" ++ elif [ -n "$FIND" ] && [ "$FIND" != "on" -a "$FIND" != "yes" -a "$FIND" != "off" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'on' 'yes' 'y' 'off' 'no' 'n' 'strict' 'greedy' or 'smart'" + exit 1 + fi + if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then @@ -497,7 +498,7 @@ index 00000000..319664b1 + echo "multipath is disabled" + fi + if [ -z "$HAVE_FIND" ]; then -+ echo "find_multipaths is no" ++ echo "find_multipaths is off" + else + echo "find_multipaths is $HAVE_FIND" + fi @@ -733,7 +734,7 @@ index 00000000..319664b1 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..9c2fb835 +index 00000000..ea025f31 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,151 @@ @@ -779,10 +780,10 @@ index 00000000..9c2fb835 +.B user_friendly_names +set and +.B find_multipaths -+set to \fByes\fP. To disable these, use the ++set to \fBon\fP. To disable these, use the +.B --user_friendly_names n +and -+.B --find_multipaths n ++.B --find_multipaths off +options +.SH COMMANDS +.TP @@ -825,7 +826,7 @@ index 00000000..9c2fb835 +sets an existing \fBrecheck_wwid\fP line to \fBno\fP. This command can be used +along with any other command. +.TP -+.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } ++.B --find_multipaths\fP { \fBon\fP | \fByes\fP | \fBy\fP | \fBoff\fP | \fBno\fP | \fBn\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } +If set to \fB\fP, this adds the line +.B find_multipaths +to the diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch index 4e1253c..cf7317e 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -6,10 +6,12 @@ Subject: [PATCH] RH: reset default find_mutipaths value to off Upstream has changed to default find_multipaths to "strict". For now Redhat will retain the previous default of "off". +Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- - libmultipath/defaults.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + libmultipath/defaults.h | 2 +- + multipath/multipath.conf.5.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h index 64b633f2..5bda9f93 100644 @@ -24,3 +26,16 @@ index 64b633f2..5bda9f93 100644 #define DEFAULT_FAST_IO_FAIL 5 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 87b3b2a5..8e246571 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1213,7 +1213,7 @@ as non-multipath and passed on to upper layers. + \fBNote:\fR this may cause delays during device detection if + there are single-path devices which aren\'t blacklisted. + .TP +-The default is: \fBstrict\fR ++The default is: \fBoff\fR + .RE + . + . diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 5a9b492..aea93d7 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,11 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 28 2023 Paul Donohue - 0.9.7-2 +- Modify 0006-RH-add-mpathconf.patch +- Modify 0008-RH-reset-default-find_mutipaths-value-to-off.patch + * Fix find_multipaths values in docs and mpathconf + * Tue Nov 21 2023 Benjamin Marzinski - 0.9.7-1 - Update source to upstream version 0.9.7 * Previous patches 0001-0040 are included in the source tarball From 0f3122f75fe934276c0e8672f11b8d0a8abada11 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 29 Nov 2023 22:24:39 -0500 Subject: [PATCH 10/33] device-mapper-multipath-0.9.7-3 Fix multipath_conf_syntax test Fix restate_module test Fix find_multipaths test --- device-mapper-multipath.spec | 6 +++++- tests/find_multipaths/main.sh | 1 + tests/multipath_conf_syntax/main.sh | 2 +- tests/restate_module/main.sh | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index aea93d7..1fdaa06 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Nov 29 2023 Benjamin Marzinski - 0.9.7-3 +- Fix multipath_conf_syntax test +- Fix restate_module test + * Tue Nov 28 2023 Paul Donohue - 0.9.7-2 - Modify 0006-RH-add-mpathconf.patch - Modify 0008-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/tests/find_multipaths/main.sh b/tests/find_multipaths/main.sh index a39af79..4d94c87 100755 --- a/tests/find_multipaths/main.sh +++ b/tests/find_multipaths/main.sh @@ -40,6 +40,7 @@ rpm -q device-mapper-multipath || yum install -y device-mapper-multipath # test with find_multipath=y, will not multipath for the single device; reload/start the service to enable the config cleanup trun "rm -f /etc/multipath.conf" +trun "rm -f /etc/multipath/wwids" trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd n" sed -i '/^blacklist[[:space:]]*{/ a\ device {\n vendor ".*"\n product ".*"\n } diff --git a/tests/multipath_conf_syntax/main.sh b/tests/multipath_conf_syntax/main.sh index 331d65e..fb303c3 100755 --- a/tests/multipath_conf_syntax/main.sh +++ b/tests/multipath_conf_syntax/main.sh @@ -119,7 +119,7 @@ tok "multipath -ll | grep mypath" # test wrong alias keyword trun "sed -i 's/alias.*$/alia mypath/g' /etc/multipath.conf" -tok "multipath 2>&1 | grep 'invalid keyword: alia'" +tok "multipath 2>&1 | grep 'invalid keyword in the multipath section: alia'" trun "multipath -r" tok "multipath -ll | grep mpath" trun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index 7f3279d..565e59c 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -69,7 +69,7 @@ tlog "Checking if active path count equals 2" assert "[[ $pathcount -eq 2 ]]" tlog "offline one path device" -pathname=`multipathd show paths raw format "%d %m" | grep ${mpathdev} | head -1 | awk '{print $1}'` +pathname=`multipathd show paths raw format "%d %m %p" | grep ${mpathdev} | sort -k 3n | head -1 | awk '{print $1}'` tlog "path to offline: ${pathname}" trun "echo 'offline' > /sys/block/${pathname}/device/state" tlog "waiting for multipathd to fail path" From b0b20d4f7b4de67597a1db368eb183c938714547 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 30 Nov 2023 16:30:05 -0500 Subject: [PATCH 11/33] device-mapper-multipath-0.9.7-4 Use modulesloaddir macro for installing scsi_dh.conf --- device-mapper-multipath.spec | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 1fdaa06..2a92a06 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -171,8 +171,8 @@ fi %{_mandir}/man8/mpathpersist.8* %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules -%dir /usr/lib/modules-load.d -/usr/lib/modules-load.d/scsi_dh.conf +%dir %{_modulesloaddir} +%{_modulesloaddir}/scsi_dh.conf %{_tmpfilesdir}/multipath.conf %doc README.md %doc multipath.conf @@ -231,6 +231,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Nov 30 2023 Benjamin Marzinski - 0.9.7-4 +- Use modulesloaddir macro for installing scsi_dh.conf + * Wed Nov 29 2023 Benjamin Marzinski - 0.9.7-3 - Fix multipath_conf_syntax test - Fix restate_module test From 835a8a43de1620fcb450510713cbdeb859b318d5 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 16 Jan 2024 22:54:08 -0500 Subject: [PATCH 12/33] device-mapper-multipath-0.9.7-5 Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * Fix auto_resize code to avoid a segfault Add 0015-multipathd-fix-auto-resize-configuration.patch * Fix auto_resize default value --- ...ull-pointer-dereference-in-uev_updat.patch | 27 ++++++++++++ ...ipathd-fix-auto-resize-configuration.patch | 42 +++++++++++++++++++ device-mapper-multipath.spec | 10 ++++- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch create mode 100644 0015-multipathd-fix-auto-resize-configuration.patch diff --git a/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch b/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch new file mode 100644 index 0000000..7655591 --- /dev/null +++ b/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 16 Jan 2024 00:54:37 -0500 +Subject: [PATCH] multipathd: fix null pointer dereference in uev_update_path + +The Auto-resize code added a check that deferences pp->mpp without +checking that it's non-NULL. Fix it. + +Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 230c9d10..57c04364 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1653,7 +1653,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + } + } + } +- if (auto_resize != AUTO_RESIZE_NEVER && ++ if (auto_resize != AUTO_RESIZE_NEVER && mpp && + !mpp->wait_for_udev) { + struct pathgroup *pgp; + struct path *pp2; diff --git a/0015-multipathd-fix-auto-resize-configuration.patch b/0015-multipathd-fix-auto-resize-configuration.patch new file mode 100644 index 0000000..35e4d48 --- /dev/null +++ b/0015-multipathd-fix-auto-resize-configuration.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 16 Jan 2024 01:11:02 -0500 +Subject: [PATCH] multipathd: fix auto-resize configuration + +The code acted like AUTO_RESIZE_UNDEFINED didn't exist, but since +conf->auto_resize was never set to AUTO_RESIZE_NEVER, the default was in +fact AUTO_RESIZE_UNDEFINED, which ended up getting treated like +AUTO_RESIZE_GROW_SHRINK. Remove AUTO_RESIZE_UNDEFINED and explicitly +default auto_resize tp AUTO_RESIZE_NEVER. + +Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 1 + + libmultipath/structs.h | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 4544f484..3d5943d3 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -927,6 +927,7 @@ int _init_config (const char *file, struct config *conf) + conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; + conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; + conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT; ++ conf->auto_resize = DEFAULT_AUTO_RESIZE; + conf->remove_retries = 0; + conf->ghost_delay = DEFAULT_GHOST_DELAY; + conf->all_tg_pt = DEFAULT_ALL_TG_PT; +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index a1aac1b4..734905e2 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -180,7 +180,6 @@ enum queue_mode_states { + }; + + enum auto_resize_state { +- AUTO_RESIZE_UNDEF = 0, + AUTO_RESIZE_NEVER, + AUTO_RESIZE_GROW_ONLY, + AUTO_RESIZE_GROW_SHRINK, diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2a92a06..b448595 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -23,6 +23,8 @@ Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch Patch0012: 0012-RH-compile-with-libreadline-support.patch Patch0013: 0013-RH-Add-mpathcleanup.patch +Patch0014: 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch +Patch0015: 0015-multipathd-fix-auto-resize-configuration.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -231,6 +233,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jan 16 2024 Benjamin Marzinski - 0.9.7-5 +- Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch + * Fix auto_resize code to avoid a segfault +- Add 0015-multipathd-fix-auto-resize-configuration.patch + * Fix auto_resize default value + * Thu Nov 30 2023 Benjamin Marzinski - 0.9.7-4 - Use modulesloaddir macro for installing scsi_dh.conf From c9568c86e6bd6a57461f3ca10225a45b57a664ca Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jan 2024 17:03:18 +0000 Subject: [PATCH 13/33] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b448595..2b4e20d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Jan 19 2024 Fedora Release Engineering - 0.9.7-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Tue Jan 16 2024 Benjamin Marzinski - 0.9.7-5 - Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * Fix auto_resize code to avoid a segfault From 6956fa4aa7f800ccf59fd8d4569975fd36fd9f11 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 24 Jan 2024 09:20:08 +0000 Subject: [PATCH 14/33] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2b4e20d..3cf8fb0 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.7 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jan 24 2024 Fedora Release Engineering - 0.9.7-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Fri Jan 19 2024 Fedora Release Engineering - 0.9.7-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 6496193f3f25e1033cd68e6248baaa16bd4bf4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 17 Apr 2024 22:49:31 +0200 Subject: [PATCH 15/33] Stop harcoding paths Preparation for https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin. Packages must honour macros for directories, in particular %_sbindir may be set to /usr/bin. --- device-mapper-multipath.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 3cf8fb0..78bef5a 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -115,7 +115,6 @@ device-mapper-multipath's libdmmp C API library cp %{SOURCE1} . %build -%define _sbindir /usr/sbin %define _libdir /usr/%{_lib} %define _libmpathdir %{_libdir}/multipath %define _pkgconfdir %{_libdir}/pkgconfig @@ -146,7 +145,7 @@ rm -rf %{buildroot}/%{_initrddir} %postun if [ $1 -ge 1 ] ; then - /sbin/multipathd forcequeueing daemon > /dev/null 2>&1 || : + multipathd forcequeueing daemon > /dev/null 2>&1 || : fi %systemd_postun_with_restart multipathd.service From 588b3f63e9e24d8b4e5e810601fd417301f95e5a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 20 May 2024 22:01:48 -0400 Subject: [PATCH 16/33] device-mapper-multipath-0.9.8-1 Update source to upstream version 0.9.8 plus latest staging branch * Previous patches 0014 & 0015 are included in the source tarball * patches 0001-0044 are from the upstream staging branch. Rename redhat patches * Previous patches 0001-0013 are now patches 0045-0057 --- .gitignore | 1 + ...s-fix-misspelled-DM_UDEV_DISABLE_OTH.patch | 27 ++ ...ondlog-level-for-setscheduler-error-.patch | 27 ++ ...e-multipathd-scheduling-configurable.patch | 87 +++++ ...til-really-always-use-glibc-basename.patch | 144 ++++++++ ...multipathd-set-priority-to-RLIMIT_RT.patch | 134 +++++++ ...PUWeight-to-1000-and-LimitRTPRIO-to-.patch | 33 ++ ...s-explain-logic-for-device-becoming-.patch | 30 ++ ...s-don-t-import-DM_NOSCAN-from-udev-d.patch | 37 ++ ...s-don-t-import-ID_FS_VERSION-from-ud.patch | 27 ++ ...s-adapt-MPATH_DEVICE_READY-0-logic-t.patch | 67 ++++ ...s-adapt-coldplug-event-handling-ro-1.patch | 43 +++ ...s-don-t-import-properties-with-new-1.patch | 36 ++ ...s-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch | 75 ++++ ...ules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch | 55 +++ ...ull-pointer-dereference-in-uev_updat.patch | 27 -- ...path.rules-simplify-PATH_FAILED-case.patch | 38 ++ ...ipathd-fix-auto-resize-configuration.patch | 42 --- ...ules-make-label-names-more-intuitive.patch | 109 ++++++ 0017-kpartx.rules-ignore-DM_SUSPENDED.patch | 29 ++ ...tests-fix-CI-failures-on-arm-v7-with.patch | 270 ++++++++++++++ ...tests-fix-CI-failures-with-clang-on-.patch | 246 +++++++++++++ ...GitHub-actions-fixes-for-spelling-CI.patch | 31 ++ ...-run-workflows-if-workflow-file-has-.patch | 146 ++++++++ 0022-multipath-tools-add-TGTDIR-option.patch | 106 ++++++ ...ath-move-get_udev_for_mpp-to-sysfs.c.patch | 87 +++++ ...ibmultipath-add-mp_find_path_by_devt.patch | 60 +++ ...ath-fix-max_sectors_kb-on-adding-pat.patch | 33 ++ ...y-set-max_sectors_kb-on-map-creation.patch | 122 ++++++ ...th-set-max_sectors_kb-in-adopt_paths.patch | 233 ++++++++++++ ...-wildcard-k-for-printing-max_sectors.patch | 89 +++++ ...-update-documentation-for-max_sector.patch | 57 +++ ...th-tools-simplify-comment-in-hwtable.patch | 34 ++ ...tools-unify-text-in-multipath.conf.5.patch | 75 ++++ ...ltipath-tools-update-man-pages-dates.patch | 86 +++++ 0033-libmultipath-export-partmap_in_use.patch | 53 +++ ...nge-flush_on_last_del-to-fix-a-multi.patch | 346 ++++++++++++++++++ ...ove-redundant-config-option-from-Inf.patch | 31 ++ ...-dev_loss_tmo-to-avoid-race-with-no_.patch | 40 ++ ...x-deferred_remove-function-arguments.patch | 107 ++++++ ...e-bitwise-flags-for-map-flushing-API.patch | 212 +++++++++++ ...e-bitwise-flags-for-dm_simplecmd-API.patch | 117 ++++++ ...dd-argument-names-to-some-prototypes.patch | 34 ++ 0041-libmultipath-bump-version-to-0.9.9.patch | 27 ++ ...kflows-native.yaml-run-for-Fedora-40.patch | 24 ++ 0043-update-NEWS.md.patch | 134 +++++++ ...ultipath.conf.5.in-fix-man-page-date.patch | 24 ++ ... 0045-RH-fixup-udev-rules-for-redhat.patch | 16 +- ...property-blacklist-exception-builtin.patch | 6 +- ...RH-don-t-start-without-a-config-file.patch | 20 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0049-RH-use-rpm-optflags-if-present.patch | 10 +- ...hconf.patch => 0050-RH-add-mpathconf.patch | 13 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 10 +- ...-default-find_mutipaths-value-to-off.patch | 6 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 18 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- ...up.patch => 0057-RH-Add-mpathcleanup.patch | 8 +- device-mapper-multipath.spec | 91 ++++- sources | 2 +- 62 files changed, 3951 insertions(+), 145 deletions(-) create mode 100644 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch create mode 100644 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch create mode 100644 0003-multipathd-make-multipathd-scheduling-configurable.patch create mode 100644 0004-libmpathutil-really-always-use-glibc-basename.patch create mode 100644 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch create mode 100644 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch create mode 100644 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch create mode 100644 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch create mode 100644 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch create mode 100644 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch create mode 100644 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch create mode 100644 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch create mode 100644 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch create mode 100644 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch delete mode 100644 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch create mode 100644 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch delete mode 100644 0015-multipathd-fix-auto-resize-configuration.patch create mode 100644 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch create mode 100644 0017-kpartx.rules-ignore-DM_SUSPENDED.patch create mode 100644 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch create mode 100644 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch create mode 100644 0020-GitHub-actions-fixes-for-spelling-CI.patch create mode 100644 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch create mode 100644 0022-multipath-tools-add-TGTDIR-option.patch create mode 100644 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch create mode 100644 0024-libmultipath-add-mp_find_path_by_devt.patch create mode 100644 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch create mode 100644 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch create mode 100644 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch create mode 100644 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch create mode 100644 0029-multipath.conf-5-update-documentation-for-max_sector.patch create mode 100644 0030-multipath-tools-simplify-comment-in-hwtable.patch create mode 100644 0031-multipath-tools-unify-text-in-multipath.conf.5.patch create mode 100644 0032-multipath-tools-update-man-pages-dates.patch create mode 100644 0033-libmultipath-export-partmap_in_use.patch create mode 100644 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch create mode 100644 0035-libmultipath-remove-redundant-config-option-from-Inf.patch create mode 100644 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch create mode 100644 0037-libmultipath-fix-deferred_remove-function-arguments.patch create mode 100644 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch create mode 100644 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch create mode 100644 0040-libmultipath-add-argument-names-to-some-prototypes.patch create mode 100644 0041-libmultipath-bump-version-to-0.9.9.patch create mode 100644 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch create mode 100644 0043-update-NEWS.md.patch create mode 100644 0044-multipath.conf.5.in-fix-man-page-date.patch rename 0001-RH-fixup-udev-rules-for-redhat.patch => 0045-RH-fixup-udev-rules-for-redhat.patch (86%) rename 0002-RH-Remove-the-property-blacklist-exception-builtin.patch => 0046-RH-Remove-the-property-blacklist-exception-builtin.patch (96%) rename 0003-RH-don-t-start-without-a-config-file.patch => 0047-RH-don-t-start-without-a-config-file.patch (92%) rename 0004-RH-Fix-nvme-function-missing-argument.patch => 0048-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0005-RH-use-rpm-optflags-if-present.patch => 0049-RH-use-rpm-optflags-if-present.patch (87%) rename 0006-RH-add-mpathconf.patch => 0050-RH-add-mpathconf.patch (98%) rename 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (96%) rename 0008-RH-reset-default-find_mutipaths-value-to-off.patch => 0052-RH-reset-default-find_mutipaths-value-to-off.patch (91%) rename 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (84%) rename 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) rename 0012-RH-compile-with-libreadline-support.patch => 0056-RH-compile-with-libreadline-support.patch (96%) rename 0013-RH-Add-mpathcleanup.patch => 0057-RH-Add-mpathcleanup.patch (96%) diff --git a/.gitignore b/.gitignore index f698d08..80e9936 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.5.tgz /multipath-tools-0.9.6.tgz /multipath-tools-0.9.7.tgz +/multipath-tools-0.9.8.tgz diff --git a/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch b/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch new file mode 100644 index 0000000..4b9d7fc --- /dev/null +++ b/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 18:16:32 +0100 +Subject: [PATCH] 11-dm-mpath.rules: fix misspelled + DM_UDEV_DISABLE_OTHER_RULES_FLAG + +Fixes: b3582da ("11-dm-mpath.rules: use import logic like 13-dm-disk.rules") +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index d364f9bc..d9585abf 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -116,7 +116,7 @@ LABEL="scan_import" + ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + + # Don't import the properties from db if we will run blkid later. +-ENV{DM_NOSCAN}!="1", ENV{DM_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" ++ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + + IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" diff --git a/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch b/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch new file mode 100644 index 0000000..8a6ff99 --- /dev/null +++ b/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 1 Mar 2024 19:37:29 -0500 +Subject: [PATCH] multipathd: use condlog level for setscheduler error message + +condlog uses its own log levels, so LOG_WARNING makes no sense. It +actually translates to a message sent at the LOG_DEBUG level. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 6193e691..85ac540f 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3178,7 +3178,7 @@ setscheduler (void) + res = sched_setscheduler (0, SCHED_RR, &sched_param); + + if (res == -1) +- condlog(LOG_WARNING, "Could not set SCHED_RR at priority 99"); ++ condlog(2, "Could not set SCHED_RR at priority 99"); + return; + } + diff --git a/0003-multipathd-make-multipathd-scheduling-configurable.patch b/0003-multipathd-make-multipathd-scheduling-configurable.patch new file mode 100644 index 0000000..8529152 --- /dev/null +++ b/0003-multipathd-make-multipathd-scheduling-configurable.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 1 Mar 2024 19:37:30 -0500 +Subject: [PATCH] multipathd: make multipathd scheduling configurable + +Currently multipathd always tries to run as a realtime process with a +priority of 99. This is excessive. As a first step towards fixing this, +make it possible at compile time to lower the priority or keep +multipathd from making itself a realtime process. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + Makefile.inc | 6 ++++++ + README.md | 3 +++ + multipathd/Makefile | 3 +++ + multipathd/main.c | 5 +++-- + 4 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 5668e638..6d206281 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -18,6 +18,12 @@ READLINE := + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac + SCSI_DH_MODULES_PRELOAD := + ++# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd ++# change its scheduling policy to SCHED_RR and its priority to the specified ++# value. set to 0 to stop multipathd from changing the scheduling policy and ++# priority it was started with. ++SCHED_RT_PRIO := 99 ++ + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) + + # PKG_CONFIG must be read from the environment to enable compilation +diff --git a/README.md b/README.md +index d4f35f57..bb41bf0e 100644 +--- a/README.md ++++ b/README.md +@@ -98,6 +98,9 @@ The following variables can be passed to the `make` command line: + By default, command line editing is disabled. + Note that using libreadline may + [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). ++ * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority ++ multipathd will attempt to run with. for value 0, disable multipathd ++ changing itself to a realtime process. + * `ENABLE_LIBDMMP=0`: disable building libdmmp + * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event + polling API. For use with pre-5.0 kernels that don't support dmevent polling +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 997b40cf..7300f07a 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -57,6 +57,9 @@ $(CLI): $(CLI_OBJS) + cli_handlers.o: cli_handlers.c + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + ++main.o: main.c ++ $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< ++ + install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +diff --git a/multipathd/main.c b/multipathd/main.c +index 85ac540f..9486a8a3 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3172,7 +3172,7 @@ setscheduler (void) + { + int res; + static struct sched_param sched_param = { +- .sched_priority = 99 ++ .sched_priority = SCHED_RT_PRIO + }; + + res = sched_setscheduler (0, SCHED_RR, &sched_param); +@@ -3471,7 +3471,8 @@ child (__attribute__((unused)) void *param) + if (!vecs) + goto failed; + +- setscheduler(); ++ if (SCHED_RT_PRIO) ++ setscheduler(); + set_oom_adj(); + #ifdef FPIN_EVENT_HANDLER + if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) diff --git a/0004-libmpathutil-really-always-use-glibc-basename.patch b/0004-libmpathutil-really-always-use-glibc-basename.patch new file mode 100644 index 0000000..78f8859 --- /dev/null +++ b/0004-libmpathutil-really-always-use-glibc-basename.patch @@ -0,0 +1,144 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 3 Apr 2024 18:55:54 +0200 +Subject: [PATCH] libmpathutil: really always use glibc basename() + +Despite 03a5456 ("libmultipath: always use glibc basename()"), we +still call the system library's basename() from libmultipath. +musl libc until 1.24 provided a prototype for basename() in string.h, +which was not correct and was resolved to the destructive POSIX +basename(). musl libc 1.25 removed this prototype. + +While the remaining code path doesn't strictly depend on the non-destructive +behavior of glibc's basename(), it's cleaner and safer to use the same +implementation everywhere. + +Fixes: 03a5456 ("libmultipath: always use glibc basename()") +Fixes: https://github.com/opensvc/multipath-tools/pull/84 + +Signed-off-by: Martin Wilck +Reviewed-by: Khem Raj +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathutil/libmpathutil.version | 4 ++++ + libmpathutil/util.c | 5 +---- + libmpathutil/util.h | 5 +++++ + tests/util.c | 31 +++++++++++++++++++++++++++++++ + 4 files changed, 41 insertions(+), 4 deletions(-) + +diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version +index 80d64a3e..fee74a32 100644 +--- a/libmpathutil/libmpathutil.version ++++ b/libmpathutil/libmpathutil.version +@@ -129,3 +129,7 @@ LIBMPATHUTIL_2.0 { + vector_move_up; + vector_sort; + }; ++ ++LIBMPATHUTIL_2.1 { ++ libmp_basename; ++}; +diff --git a/libmpathutil/util.c b/libmpathutil/util.c +index 9d147fca..23d303f9 100644 +--- a/libmpathutil/util.c ++++ b/libmpathutil/util.c +@@ -32,18 +32,15 @@ strchop(char *str) + return i; + } + +-#ifndef __GLIBC__ + /* + * glibc's non-destructive version of basename() + * License: LGPL-2.1-or-later + */ +-static const char *__basename(const char *filename) ++const char *libmp_basename(const char *filename) + { + char *p = strrchr(filename, '/'); + return p ? p + 1 : filename; + } +-#define basename(x) __basename(x) +-#endif + + int + basenamecpy (const char *src, char *dst, size_t size) +diff --git a/libmpathutil/util.h b/libmpathutil/util.h +index de9fcfdd..4997fed6 100644 +--- a/libmpathutil/util.h ++++ b/libmpathutil/util.h +@@ -12,6 +12,11 @@ + #include + + size_t strchop(char *); ++ ++const char *libmp_basename(const char *filename); ++#ifndef __GLIBC__ ++#define basename(x) libmp_basename(x) ++#endif + int basenamecpy (const char *src, char *dst, size_t size); + int filepresent (const char *run); + char *get_next_string(char **temp, const char *split_char); +diff --git a/tests/util.c b/tests/util.c +index d6083dce..4850ddcb 100644 +--- a/tests/util.c ++++ b/tests/util.c +@@ -16,6 +16,7 @@ + * + */ + ++#define _GNU_SOURCE + #include + #include + #include +@@ -23,6 +24,7 @@ + #include + #include + #include ++#include + #include "util.h" + + #include "globals.c" +@@ -163,6 +165,34 @@ static int test_basenamecpy(void) + return cmocka_run_group_tests(tests, NULL, NULL); + } + ++static void test_basename_01(void **state) ++{ ++ const char *path = "/foo/bar"; ++ const char *base; ++ ++ base = basename(path); ++ assert_string_equal(base, "bar"); ++ assert_string_equal(path, "/foo/bar"); ++} ++ ++static void test_basename_02(void **state) ++{ ++ const char *path = "/foo/bar/"; ++ const char *base; ++ ++ base = basename(path); ++ assert_string_equal(base, ""); ++ assert_string_equal(path, "/foo/bar/"); ++} ++ ++static int test_basename(void) { ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_basename_01), ++ cmocka_unit_test(test_basename_02), ++ }; ++ return cmocka_run_group_tests(tests, NULL, NULL); ++} ++ + /* + * On big endian systems, if bitfield_t is 32bit, we need + * to swap the two 32 bit parts of a 64bit value to make +@@ -946,6 +976,7 @@ int main(void) + + init_test_verbosity(-1); + ret += test_basenamecpy(); ++ ret += test_basename(); + ret += test_bitmasks(); + ret += test_strlcpy(); + ret += test_strlcat(); diff --git a/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch b/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch new file mode 100644 index 0000000..fd12767 --- /dev/null +++ b/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Apr 2024 18:56:12 -0400 +Subject: [PATCH] multipathd: make multipathd set priority to RLIMIT_RTPRIO + +With this change, if the SCHED_RT_PRIO compiler flag has been removed. +Instead multipathd will call getrlimit(RLIMIT_RTPRIO, ...) and look at +the hard limit. It it's 0, multipath will do nothing. Otherwise it will +change its scheduling policy to SCHED_RR and its priority to the hard +limit. + +This allows users to change the priority of that multipathd runs with by +adding + +LimitRTPRIO= + +to the [Service] section of the multipathd.service unit file. Setting +LimitRTPRIO=0 will make multipathd run as a normal process, while +setting LimitRTPRIO=infinity will make it use the maximum SCHED_RR prio, +which is 99. + +To keep the existing behavior, multipathd.service now sets +LimitRTPRIO=infinity + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + Makefile.inc | 6 ------ + README.md | 3 --- + multipathd/Makefile | 3 --- + multipathd/main.c | 22 +++++++++++++++------- + multipathd/multipathd.service.in | 1 + + 5 files changed, 16 insertions(+), 19 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 6d206281..5668e638 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -18,12 +18,6 @@ READLINE := + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac + SCSI_DH_MODULES_PRELOAD := + +-# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd +-# change its scheduling policy to SCHED_RR and its priority to the specified +-# value. set to 0 to stop multipathd from changing the scheduling policy and +-# priority it was started with. +-SCHED_RT_PRIO := 99 +- + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) + + # PKG_CONFIG must be read from the environment to enable compilation +diff --git a/README.md b/README.md +index bb41bf0e..d4f35f57 100644 +--- a/README.md ++++ b/README.md +@@ -98,9 +98,6 @@ The following variables can be passed to the `make` command line: + By default, command line editing is disabled. + Note that using libreadline may + [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). +- * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority +- multipathd will attempt to run with. for value 0, disable multipathd +- changing itself to a realtime process. + * `ENABLE_LIBDMMP=0`: disable building libdmmp + * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event + polling API. For use with pre-5.0 kernels that don't support dmevent polling +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 7300f07a..997b40cf 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -57,9 +57,6 @@ $(CLI): $(CLI_OBJS) + cli_handlers.o: cli_handlers.c + $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< + +-main.o: main.c +- $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< +- + install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) +diff --git a/multipathd/main.c b/multipathd/main.c +index 9486a8a3..dd17d5c3 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -3171,14 +3171,23 @@ static void + setscheduler (void) + { + int res; +- static struct sched_param sched_param = { +- .sched_priority = SCHED_RT_PRIO +- }; ++ static struct sched_param sched_param; ++ struct rlimit rlim; ++ ++ if (getrlimit(RLIMIT_RTPRIO, &rlim) < 0 || rlim.rlim_max == 0) ++ return; ++ ++ sched_param.sched_priority = rlim.rlim_max > INT_MAX ? INT_MAX : ++ rlim.rlim_max; ++ res = sched_get_priority_max(SCHED_RR); ++ if (res > 0 && res < sched_param.sched_priority) ++ sched_param.sched_priority = res; + +- res = sched_setscheduler (0, SCHED_RR, &sched_param); ++ res = sched_setscheduler(0, SCHED_RR, &sched_param); + + if (res == -1) +- condlog(2, "Could not set SCHED_RR at priority 99"); ++ condlog(2, "Could not set SCHED_RR at priority %d", ++ sched_param.sched_priority); + return; + } + +@@ -3471,8 +3480,7 @@ child (__attribute__((unused)) void *param) + if (!vecs) + goto failed; + +- if (SCHED_RT_PRIO) +- setscheduler(); ++ setscheduler(); + set_oom_adj(); + #ifdef FPIN_EVENT_HANDLER + if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 6d03ff71..18bb367e 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -19,6 +19,7 @@ NotifyAccess=main + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + TasksMax=infinity ++LimitRTPRIO=infinity + + [Install] + WantedBy=sysinit.target diff --git a/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch b/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch new file mode 100644 index 0000000..0cbe997 --- /dev/null +++ b/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 15 Apr 2024 19:43:06 -0400 +Subject: [PATCH] multipathd: Set CPUWeight to 1000 and LimitRTPRIO to 10 + +If multipathd doesn't become a real time process, it was scheduled as a +normal process, without any priority increase. Bump up the CPUWeight so +that even as a normal process, it will still run with increased +priority. + +If multipathd did become a real time process, it set itself to the +highest priority, which is excessive. A priority of 10 is plenty. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/multipathd.service.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 18bb367e..a63ddd9a 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -19,7 +19,8 @@ NotifyAccess=main + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + TasksMax=infinity +-LimitRTPRIO=infinity ++LimitRTPRIO=10 ++CPUWeight=1000 + + [Install] + WantedBy=sysinit.target diff --git a/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch b/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch new file mode 100644 index 0000000..6241459 --- /dev/null +++ b/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 19:53:14 +0100 +Subject: [PATCH] 11-dm-mpath.rules: explain logic for device becoming ready + while suspended + +Add a comment to explain why we must set MPATH_DEVICE_READY=0 when +we see a device becoming ready (number of active paths 0 -> 1) while +the device is suspended. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index d9585abf..b8d19d01 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -98,6 +98,8 @@ ENV{MPATH_DEVICE_READY}=="0", \ + # If the device comes back online, set DM_ACTIVATION so that + # upper layers do a rescan. If the device is currently suspended, + # we have to postpone the activation until the next event. ++# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the ++# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. + ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" + ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" + ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" diff --git a/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch b/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch new file mode 100644 index 0000000..3900b39 --- /dev/null +++ b/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 19:57:59 +0100 +Subject: [PATCH] 11-dm-mpath.rules: don't import DM_NOSCAN from udev db + +DM_NOSCAN is our "output" flag for 13-dm-disk.rules, and it should +be treated the same way as DM_UDEV_DISABLE_OTHER_RULES_FLAG, which +isn't imported from the udev database. The state that we need to +remember is MPATH_DEVICE_READY, which we've already imported above, +and we will set the "output" flags accordingly in the "force_activation" +code path further down. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index b8d19d01..eb12b0c6 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -18,9 +18,11 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 + + # If this uevent didn't come from dm, don't try to update the + # device state ++# Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the ++# device below at force_activation, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ +- IMPORT{db}="DM_NOSCAN", IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ +- GOTO="scan_import" ++ IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ ++ GOTO="force_activation" + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + diff --git a/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch b/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch new file mode 100644 index 0000000..933a43a --- /dev/null +++ b/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 21:02:49 +0100 +Subject: [PATCH] 11-dm-mpath.rules: don't import ID_FS_VERSION from udev db + +Use the same set of properties to import as 13-dm-disk.rules. +ID_FS_VERSION isn't used in any udev rule I am aware of. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index eb12b0c6..4386b6ca 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -126,7 +126,6 @@ IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" + IMPORT{db}="ID_FS_UUID_ENC" + IMPORT{db}="ID_FS_LABEL_ENC" +-IMPORT{db}="ID_FS_VERSION" + IMPORT{db}="ID_PART_ENTRY_NAME" + IMPORT{db}="ID_PART_ENTRY_UUID" + IMPORT{db}="ID_PART_ENTRY_SCHEME" diff --git a/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch b/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch new file mode 100644 index 0000000..97b3901 --- /dev/null +++ b/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 20:53:50 +0100 +Subject: [PATCH] 11-dm-mpath.rules: adapt MPATH_DEVICE_READY=0 logic to + 10-dm.rules update + +With the late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG isn't +restored from the udev database any more, so we don't need to restore +the flag to its original state before it is saved to the db. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 4386b6ca..2f909c3a 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -19,7 +19,7 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 + # If this uevent didn't come from dm, don't try to update the + # device state + # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the +-# device below at force_activation, which is correct. ++# device below at mpath_is_ready, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ + IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ + GOTO="force_activation" +@@ -84,25 +84,27 @@ ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ + + LABEL="force_activation" + ++ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + # Do not initiate scanning if no path is available, + # otherwise there would be a hang or IO error on access. + # We'd like to avoid this, especially within udev processing. +-ENV{MPATH_DEVICE_READY}=="0", ENV{DM_NOSCAN}="1" +- +-# Skip all foreign rules if no path is available. ++# This is communicated to later rules in DM_NOSCAN. ++# Likewise, skip all foreign rules if no path is available. + # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this +-# to upper layers. The original value will be restored in a late +-# udev rule. +-ENV{MPATH_DEVICE_READY}=="0", \ +- ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}", \ +- ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++# to upper layers. With dm rules < v3, save the original value here; ++# it will be restored in a late udev rule. ++ENV{DM_UDEV_RULES_VSN}=="1|2", \ ++ ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" ++ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++GOTO="dont_activate" ++ ++LABEL="mpath_is_ready" + + # If the device comes back online, set DM_ACTIVATION so that + # upper layers do a rescan. If the device is currently suspended, + # we have to postpone the activation until the next event. + # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the + # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. +-ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" + ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" + ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" + diff --git a/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch b/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch new file mode 100644 index 0000000..938a07f --- /dev/null +++ b/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 20:55:40 +0100 +Subject: [PATCH] 11-dm-mpath.rules: adapt coldplug event handling ro + 10-dm.rules update + +With late late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG is +never restored from the udev db. Thus we don't need to clear it here +any more for coldplug events. Also, we must use .DM_SUSPENDED instead of +DM_SUSPENDED as input flag with the v3 rule set (other occurences of +DM_SUSPENDED will be replaced in a follow-up patch). + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 2f909c3a..5f547cab 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -9,12 +9,17 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ + ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" + +-# Coldplug event. DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored ++# Coldplug event. Import previously set properties. ++ACTION!="add", GOTO="mpath_coldplug_end" ++ENV{DM_ACTIVATION}!="1", GOTO="mpath_coldplug_end" ++ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" ++# With DM rules < v3, DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored + # from DB in 10-dm.rules. If the device is not suspended, clear the flag. + # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically + # equivalent to DM_SUSPENDED==1 || DISK_RO==1 +-ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ ++ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" ++LABEL="mpath_coldplug_end" + + # If this uevent didn't come from dm, don't try to update the + # device state diff --git a/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch b/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch new file mode 100644 index 0000000..f4e69cf --- /dev/null +++ b/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 20:58:47 +0100 +Subject: [PATCH] 11-dm-mpath.rules: don't import properties with new + 13-dm-disk.rules + +With the late changes to 13-dm-disk.rules, we don't need to import any +blkid-generated properties from the udev database, because they will +be imported later. + +Except for ID_FS_TYPE, this actually holds since lvm2 commit 94f77a4 ("udev: +import previous results of blkid when in suspended state"), included in lvm2 +2.03.19, but we have no simple way to detect the version of the lvm2 rules. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 5f547cab..95126bf2 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -126,6 +126,10 @@ LABEL="scan_import" + # have never been properly set. Don't import them. + ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + ++# DM rules v3 will import missing properties on 13-dm-disk.rules. ++# No need to do it here. ++ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" ++ + # Don't import the properties from db if we will run blkid later. + ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + diff --git a/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch b/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch new file mode 100644 index 0000000..e922427 --- /dev/null +++ b/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 22:33:59 +0100 +Subject: [PATCH] 11-dm-mpath.rules: replace DM_SUSPENDED by .DM_SUSPENDED + +With the late changes to the device mapper rules, DM_SUSPENDED +is not exported any more. Use .DM_SUSPENDED instead. + +Note that although 11-dm-mpath.rules is not a part of lvm2, it +can be considered as part of the device-mapper layer (everything +before 13-dm-disk.rules can), and is thus allowed to use +.DM_SUSPENDED. In practice .DM_SUSPENDED is equivalent to +DM_UDEV_DISABLE_OTHER_RULES_FLAG for multipath devices, but +using .DM_SUSPENDED here makes the intention more obvious. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 95126bf2..efc6416f 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -4,8 +4,11 @@ ENV{DM_UUID}!="mpath-?*", GOTO="mpath_end" + + IMPORT{db}="MPATH_DEVICE_READY" + ++# device-mapper rules v2 compatibility ++ENV{.DM_SUSPENDED}!="?*", ENV{.DM_SUSPENDED}="$env{DM_SUSPENDED}" ++ + # Coldplug event while device is suspended (e.g. during a reload) +-ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ ++ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{.DM_SUSPENDED}=="1", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ + ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" + +@@ -17,7 +20,7 @@ ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" + # from DB in 10-dm.rules. If the device is not suspended, clear the flag. + # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically + # equivalent to DM_SUSPENDED==1 || DISK_RO==1 +-ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ ++ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" + LABEL="mpath_coldplug_end" + +@@ -68,7 +71,7 @@ LABEL="mpath_action" + # Activation might have been partially skipped. Activate the device now, + # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. + IMPORT{db}="DM_COLDPLUG_SUSPENDED" +-ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{DM_SUSPENDED}!="1", \ ++ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ + GOTO="force_activation" +@@ -111,7 +114,7 @@ LABEL="mpath_is_ready" + # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the + # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. + ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" +-ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" ++ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" + + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" + LABEL="dont_activate" +@@ -145,7 +148,7 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" + LABEL="import_end" + + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now +-ENV{DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" ++ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" + + # Multipath maps should take precedence over their members. + ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" diff --git a/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch b/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch new file mode 100644 index 0000000..a5eecaf --- /dev/null +++ b/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 23:23:53 +0100 +Subject: [PATCH] 11-dm-mpath.rules: replace DM_NOSCAN by .DM_NOSCAN + +We don't need to restore DM_NOSCAN from the db anymore, so we can rename +it to .DM_NOSCAN, making it a temporary property. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index efc6416f..3ae3c054 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -96,14 +96,14 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + # Do not initiate scanning if no path is available, + # otherwise there would be a hang or IO error on access. + # We'd like to avoid this, especially within udev processing. +-# This is communicated to later rules in DM_NOSCAN. ++# This is communicated to later rules in .DM_NOSCAN. + # Likewise, skip all foreign rules if no path is available. + # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this + # to upper layers. With dm rules < v3, save the original value here; + # it will be restored in a late udev rule. + ENV{DM_UDEV_RULES_VSN}=="1|2", \ + ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" +-ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" ++ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + GOTO="dont_activate" + + LABEL="mpath_is_ready" +@@ -134,7 +134,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" + + # Don't import the properties from db if we will run blkid later. +-ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" ++ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + + IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" +@@ -150,6 +150,9 @@ LABEL="import_end" + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now + ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" + ++# device-mapper rules v2 compatibility for 13-dm-disk.rules ++ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_NOSCAN}="$env{.DM_NOSCAN}" ++ + # Multipath maps should take precedence over their members. + ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" + diff --git a/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch b/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch deleted file mode 100644 index 7655591..0000000 --- a/0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 16 Jan 2024 00:54:37 -0500 -Subject: [PATCH] multipathd: fix null pointer dereference in uev_update_path - -The Auto-resize code added a check that deferences pp->mpp without -checking that it's non-NULL. Fix it. - -Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 230c9d10..57c04364 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1653,7 +1653,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - } - } - } -- if (auto_resize != AUTO_RESIZE_NEVER && -+ if (auto_resize != AUTO_RESIZE_NEVER && mpp && - !mpp->wait_for_udev) { - struct pathgroup *pgp; - struct path *pp2; diff --git a/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch b/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch new file mode 100644 index 0000000..ce393ae --- /dev/null +++ b/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Mar 2024 21:17:51 +0100 +Subject: [PATCH] 11-dm-mpath.rules: simplify PATH_FAILED case + +This combination of a GOTO and a simple rule can be combined +into a single rule. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 3ae3c054..4777fbec 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -56,14 +56,10 @@ PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" + ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" + LABEL="paths_ok" + +-# Don't mark a device ready on a PATH_FAILED event. even if +-# DM_NR_VALID_PATHS is greater than 0. Just keep the existing +-# value +-ENV{DM_ACTION}=="PATH_FAILED", GOTO="mpath_action" +- +-# This event is either a PATH_REINSTATED or a table reload where +-# there are active paths. Mark the device ready +-ENV{MPATH_DEVICE_READY}="1" ++# For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. ++# If it's not PATH_FAILED, this event is either a PATH_REINSTATED or a ++# table reload where there are active paths. Mark the device ready. ++ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" + + LABEL="mpath_action" + diff --git a/0015-multipathd-fix-auto-resize-configuration.patch b/0015-multipathd-fix-auto-resize-configuration.patch deleted file mode 100644 index 35e4d48..0000000 --- a/0015-multipathd-fix-auto-resize-configuration.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 16 Jan 2024 01:11:02 -0500 -Subject: [PATCH] multipathd: fix auto-resize configuration - -The code acted like AUTO_RESIZE_UNDEFINED didn't exist, but since -conf->auto_resize was never set to AUTO_RESIZE_NEVER, the default was in -fact AUTO_RESIZE_UNDEFINED, which ended up getting treated like -AUTO_RESIZE_GROW_SHRINK. Remove AUTO_RESIZE_UNDEFINED and explicitly -default auto_resize tp AUTO_RESIZE_NEVER. - -Fixes: 981b83ad1 ("multipathd: Add auto_resize config option") -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 1 + - libmultipath/structs.h | 1 - - 2 files changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 4544f484..3d5943d3 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -927,6 +927,7 @@ int _init_config (const char *file, struct config *conf) - conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; - conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; - conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT; -+ conf->auto_resize = DEFAULT_AUTO_RESIZE; - conf->remove_retries = 0; - conf->ghost_delay = DEFAULT_GHOST_DELAY; - conf->all_tg_pt = DEFAULT_ALL_TG_PT; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a1aac1b4..734905e2 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -180,7 +180,6 @@ enum queue_mode_states { - }; - - enum auto_resize_state { -- AUTO_RESIZE_UNDEF = 0, - AUTO_RESIZE_NEVER, - AUTO_RESIZE_GROW_ONLY, - AUTO_RESIZE_GROW_SHRINK, diff --git a/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch b/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch new file mode 100644 index 0000000..e81f04f --- /dev/null +++ b/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 21:54:26 +0100 +Subject: [PATCH] 11-dm-mpath.rules: make label names more intuitive + +The labels "dont_activate" and "scan_import" denote the same code line. +Remove "dont_activate". Improve two misleading label names. + +Substitutions: + dont_activate -> scan_import + force_activation -> check_mpath_ready + mpath_action -> check_mpath_unchanged + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 4777fbec..0562eddf 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -30,7 +30,7 @@ LABEL="mpath_coldplug_end" + # device below at mpath_is_ready, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ + IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ +- GOTO="force_activation" ++ GOTO="check_mpath_ready" + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + +@@ -38,13 +38,13 @@ ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + # table with no active devices. If this happens, mark the + # device not ready + ENV{DM_SUBSYSTEM_UDEV_FLAG2}=="1", ENV{MPATH_DEVICE_READY}="0", \ +- GOTO="mpath_action" ++ GOTO="check_mpath_unchanged" + + # If the last path has failed mark the device not ready + # Note that DM_NR_VALID_PATHS is only set for PATH_FAILED|PATH_REINSTATED + # events. + # This may not be reliable, as events aren't necessarily received in order. +-ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" ++ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" + + # Don't run multipath -U during "coldplug" after switching root, + # because paths are just being added to the udev db. +@@ -53,7 +53,8 @@ ACTION=="add", ENV{.MPATH_DEVICE_READY_OLD}=="1", GOTO="paths_ok" + # Check the map state directly with multipath -U. + # This doesn't attempt I/O on the device. + PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" +-ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" ++ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" ++ + LABEL="paths_ok" + + # For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. +@@ -61,7 +62,7 @@ LABEL="paths_ok" + # table reload where there are active paths. Mark the device ready. + ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" + +-LABEL="mpath_action" ++LABEL="check_mpath_unchanged" + + # A previous coldplug event occurred while the device was suspended. + # Activation might have been partially skipped. Activate the device now, +@@ -70,7 +71,7 @@ IMPORT{db}="DM_COLDPLUG_SUSPENDED" + ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ +- GOTO="force_activation" ++ GOTO="check_mpath_ready" + + # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. + # Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its +@@ -86,7 +87,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ + ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ + ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" + +-LABEL="force_activation" ++LABEL="check_mpath_ready" + + ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + # Do not initiate scanning if no path is available, +@@ -100,7 +101,7 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" + ENV{DM_UDEV_RULES_VSN}=="1|2", \ + ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" + ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" +-GOTO="dont_activate" ++GOTO="scan_import" + + LABEL="mpath_is_ready" + +@@ -109,11 +110,10 @@ LABEL="mpath_is_ready" + # we have to postpone the activation until the next event. + # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the + # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. +-ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" +-ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" ++ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" ++ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" + + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" +-LABEL="dont_activate" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or diff --git a/0017-kpartx.rules-ignore-DM_SUSPENDED.patch b/0017-kpartx.rules-ignore-DM_SUSPENDED.patch new file mode 100644 index 0000000..3b0ac76 --- /dev/null +++ b/0017-kpartx.rules-ignore-DM_SUSPENDED.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 1 Mar 2024 21:17:26 +0100 +Subject: [PATCH] kpartx.rules: ignore DM_SUSPENDED + +DM_SUSPENDED=1 implies DM_UDEV_DISABLE_OTHER_RULES_FLAG=1, no +need to check it again. The DM_NOSCAN check needs to remain in +order to keep compatibility with dm rules v2. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + kpartx/kpartx.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 1969dee0..8dd3369c 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -27,7 +27,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" + ENV{MPATH_UNCHANGED}=="1", GOTO="mpath_kpartx_end" + + # Don't run kpartx now if we know it will fail or hang. +-ENV{DM_SUSPENDED}=="1", GOTO="mpath_kpartx_end" ++# This is required for device mapper rules v2 compatibility. + ENV{DM_NOSCAN}=="1", GOTO="mpath_kpartx_end" + + # Run kpartx diff --git a/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch b/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch new file mode 100644 index 0000000..2840cec --- /dev/null +++ b/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch @@ -0,0 +1,270 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 4 Apr 2024 23:23:28 +0200 +Subject: [PATCH] multipath-tools tests: fix CI failures on arm/v7 with glibc + 2.37 + +glibc 2.37 has added several new wrappers around the ioctl and +io_getevents system calls on 32 bit systems, to deal with 64bit +time_t. These aren't resolved with cmocka's wrapping technique. + +Fix this with C preprocessor trickery, similar to +7b217f8 ("multipath-tools: Makefile.inc: set _FILE_OFFSET_BITS=64"). + +Note: the directio test with DIO_TEST_DEV for fails under qemu-linux-user +with foreign-arch binfmt, because aio-related system calls are unsupported +by qemu-linux-user. See https://gitlab.com/qemu-project/qemu/-/issues/210. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/directio.c | 28 ++++++++++++++-------------- + tests/vpd.c | 35 ++++++++++++++++++----------------- + tests/wrap64.h | 25 ++++++++++++++++++++++++- + 3 files changed, 56 insertions(+), 32 deletions(-) + +diff --git a/tests/directio.c b/tests/directio.c +index cbedcc9c..d5f84f10 100644 +--- a/tests/directio.c ++++ b/tests/directio.c +@@ -41,13 +41,13 @@ struct timespec full_timeout = { .tv_sec = -1 }; + #define ioctl_request_t int + #endif + +-int __real_ioctl(int fd, ioctl_request_t request, void *argp); ++int REAL_IOCTL(int fd, ioctl_request_t request, void *argp); + +-int __wrap_ioctl(int fd, ioctl_request_t request, void *argp) ++int WRAP_IOCTL(int fd, ioctl_request_t request, void *argp) + { + #ifdef DIO_TEST_DEV + mock_type(int); +- return __real_ioctl(fd, request, argp); ++ return REAL_IOCTL(fd, request, argp); + #else + int *blocksize = (int *)argp; + +@@ -148,10 +148,10 @@ int __wrap_io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt) + #endif + } + +-int __real_io_getevents(io_context_t ctx, long min_nr, long nr, ++int REAL_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, + struct io_event *events, struct timespec *timeout); + +-int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, ++int WRAP_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, + struct io_event *events, struct timespec *timeout) + { + int nr_evs; +@@ -169,8 +169,8 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, + #ifdef DIO_TEST_DEV + mock_ptr_type(struct timespec *); + mock_ptr_type(struct io_event *); +- assert_int_equal(nr_evs, __real_io_getevents(ctx, min_nr, nr_evs, +- events, timeout)); ++ assert_int_equal(nr_evs, REAL_IO_GETEVENTS(ctx, min_nr, nr_evs, ++ events, timeout)); + #else + sleep_tmo = mock_ptr_type(struct timespec *); + if (sleep_tmo) { +@@ -193,7 +193,7 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, + + static void return_io_getevents_none(void) + { +- will_return(__wrap_io_getevents, 0); ++ wrap_will_return(WRAP_IO_GETEVENTS, 0); + } + + static void return_io_getevents_nr(struct timespec *ts, int nr, +@@ -207,15 +207,15 @@ static void return_io_getevents_nr(struct timespec *ts, int nr, + mock_events[i + ev_off].res = reqs[i]->blksize; + } + while (nr > 0) { +- will_return(__wrap_io_getevents, (nr > 128)? 128 : nr); +- will_return(__wrap_io_getevents, ts); +- will_return(__wrap_io_getevents, &mock_events[off + ev_off]); ++ wrap_will_return(WRAP_IO_GETEVENTS, (nr > 128)? 128 : nr); ++ wrap_will_return(WRAP_IO_GETEVENTS, ts); ++ wrap_will_return(WRAP_IO_GETEVENTS, &mock_events[off + ev_off]); + ts = NULL; + off += 128; + nr -= 128; + } + if (nr == 0) +- will_return(__wrap_io_getevents, 0); ++ wrap_will_return(WRAP_IO_GETEVENTS, 0); + ev_off += i; + } + +@@ -251,7 +251,7 @@ static void do_libcheck_init(struct checker *c, int blocksize, + struct directio_context * ct; + + c->fd = test_fd; +- will_return(__wrap_ioctl, blocksize); ++ wrap_will_return(WRAP_IOCTL, blocksize); + assert_int_equal(libcheck_init(c), 0); + ct = (struct directio_context *)c->context; + assert_non_null(ct); +@@ -762,7 +762,7 @@ int main(void) + { + int ret = 0; + +- init_test_verbosity(2); ++ init_test_verbosity(5); + ret += test_directio(); + return ret; + } +diff --git a/tests/vpd.c b/tests/vpd.c +index 1b2d62d6..e3212e61 100644 +--- a/tests/vpd.c ++++ b/tests/vpd.c +@@ -20,6 +20,7 @@ + #include "vector.h" + #include "structs.h" + #include "discovery.h" ++#include "wrap64.h" + #include "globals.c" + + #define VPD_BUFSIZ 4096 +@@ -58,7 +59,7 @@ static const char vendor_id[] = "Linux"; + static const char test_id[] = + "A123456789AbcDefB123456789AbcDefC123456789AbcDefD123456789AbcDef"; + +-int __wrap_ioctl(int fd, unsigned long request, void *param) ++int WRAP_IOCTL(int fd, unsigned long request, void *param) + { + int len; + struct sg_io_hdr *io_hdr; +@@ -428,8 +429,8 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state) \ + /* Replace spaces, like code under test */ \ + exp_subst = subst_spaces(exp_wwid); \ + free(exp_wwid); \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen, \ + exp_len, ret, '1', 0, false, \ +@@ -458,8 +459,8 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \ + exp_len--; \ + if (exp_len >= wlen) \ + exp_len = wlen - 1; \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen, \ + exp_len, ret, byte0[type], 0, \ +@@ -495,8 +496,8 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state) \ + \ + n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, \ + 3, naa, 0); \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen, \ + exp_len, ret, '3', '0' + naa, true, \ +@@ -518,8 +519,8 @@ static void test_vpd_naa_##NAA##_badlen_##BAD(void **state) \ + n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 3, NAA, 0); \ + \ + vt->vpdbuf[7] = BAD; \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ + assert_int_equal(-ret, -ERR); \ + } +@@ -545,11 +546,11 @@ static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state) \ + /* overwrite the page size to DEFAULT_SGIO_LEN + 1 */ \ + put_unaligned_be16(255, vt->vpdbuf + 2); \ + /* this causes get_vpd_sgio to do a second ioctl */ \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + } \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml, \ + exp_len, ret, '2', 0, true, \ +@@ -571,8 +572,8 @@ static void test_vpd_eui_badlen_##LEN##_##BAD(void **state) \ + n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 2, 0, LEN); \ + \ + vt->vpdbuf[7] = BAD; \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ + assert_int_equal(ret, ERR); \ + if (ERR >= 0) \ +@@ -600,8 +601,8 @@ static void test_vpd80_ ## size ## _ ## len ## _ ## wlen(void **state) \ + exp_len = wlen - 1; \ + n = create_vpd80(vt->vpdbuf, sizeof(vt->vpdbuf), input, \ + size, len); \ +- will_return(__wrap_ioctl, n); \ +- will_return(__wrap_ioctl, vt->vpdbuf); \ ++ wrap_will_return(WRAP_IOCTL, n); \ ++ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ + ret = get_vpd_sgio(10, 0x80, 0, vt->wwid, wlen); \ + assert_correct_wwid("test_vpd80_" #size "_" #len "_" #wlen, \ + exp_len, ret, 0, 0, false, \ +diff --git a/tests/wrap64.h b/tests/wrap64.h +index 8c91d279..b0a4d831 100644 +--- a/tests/wrap64.h ++++ b/tests/wrap64.h +@@ -1,5 +1,7 @@ + #ifndef _WRAP64_H + #define _WRAP64_H 1 ++#include ++#include + #include "util.h" + + /* +@@ -31,7 +33,9 @@ + * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. + * https://savannah.gnu.org/forum/forum.php?forum_id=9205 + */ +-#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) ++#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 ++#define WRAP_FCNTL_NAME __fcntl_time64 ++#elif defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) + #define WRAP_FCNTL_NAME WRAP_NAME(fcntl) + #else + #define WRAP_FCNTL_NAME fcntl +@@ -39,6 +43,25 @@ + #define WRAP_FCNTL CONCAT2(__wrap_, WRAP_FCNTL_NAME) + #define REAL_FCNTL CONCAT2(__real_, WRAP_FCNTL_NAME) + ++/* ++ * glibc 2.37 uses __ioctl_time64 for ioctl ++ */ ++#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 ++#define WRAP_IOCTL_NAME __ioctl_time64 ++#else ++#define WRAP_IOCTL_NAME ioctl ++#endif ++#define WRAP_IOCTL CONCAT2(__wrap_, WRAP_IOCTL_NAME) ++#define REAL_IOCTL CONCAT2(__real_, WRAP_IOCTL_NAME) ++ ++#if defined(__NR_io_pgetevents) && __BITS_PER_LONG == 32 && defined(_TIME_BITS) && _TIME_BITS == 64 ++#define WRAP_IO_GETEVENTS_NAME io_getevents_time64 ++#else ++#define WRAP_IO_GETEVENTS_NAME io_getevents ++#endif ++#define WRAP_IO_GETEVENTS CONCAT2(__wrap_, WRAP_IO_GETEVENTS_NAME) ++#define REAL_IO_GETEVENTS CONCAT2(__real_, WRAP_IO_GETEVENTS_NAME) ++ + /* + * will_return() is itself a macro that uses CPP "stringizing". We need a + * macro indirection to make sure the *value* of WRAP_FUNC() is stringized diff --git a/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch b/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch new file mode 100644 index 0000000..d1dedac --- /dev/null +++ b/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch @@ -0,0 +1,246 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 5 Apr 2024 22:21:43 +0200 +Subject: [PATCH] multipath-tools tests: fix CI failures with clang on Fedora + Rawhide + +Fedora's glibc 2.39 includes the following patch: + +https://patches.linaro.org/project/libc-alpha/patch/20240208184622.332678-10-adhemerval.zanella@linaro.org/ + +It causes open("file", O_RDONLY) to resolve to __open64_2(), +whereas it resolves to open64() with gcc, causing CI failures because of +wrong wrapper substitutions. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/dmevents.c | 6 ++--- + tests/sysfs.c | 58 ++++++++++++++++++++++++------------------------ + tests/test-lib.c | 6 ++--- + tests/wrap64.h | 14 ++++++++++++ + 4 files changed, 49 insertions(+), 35 deletions(-) + +diff --git a/tests/dmevents.c b/tests/dmevents.c +index 540bf0d3..395b16d7 100644 +--- a/tests/dmevents.c ++++ b/tests/dmevents.c +@@ -207,7 +207,7 @@ static int teardown(void **state) + return 0; + } + +-int WRAP_FUNC(open)(const char *pathname, int flags) ++int WRAP_OPEN(const char *pathname, int flags) + { + assert_ptr_equal(pathname, "/dev/mapper/control"); + assert_int_equal(flags, O_RDWR); +@@ -389,7 +389,7 @@ static void test_init_waiter_bad1(void **state) + struct test_data *datap = (struct test_data *)(*state); + if (datap == NULL) + skip(); +- wrap_will_return(WRAP_FUNC(open), -1); ++ wrap_will_return(WRAP_OPEN, -1); + assert_int_equal(init_dmevent_waiter(&datap->vecs), -1); + assert_ptr_equal(waiter, NULL); + } +@@ -400,7 +400,7 @@ static void test_init_waiter_good0(void **state) + struct test_data *datap = (struct test_data *)(*state); + if (datap == NULL) + skip(); +- wrap_will_return(WRAP_FUNC(open), 2); ++ wrap_will_return(WRAP_OPEN, 2); + assert_int_equal(init_dmevent_waiter(&datap->vecs), 0); + assert_ptr_not_equal(waiter, NULL); + } +diff --git a/tests/sysfs.c b/tests/sysfs.c +index fc256d87..c623d1bb 100644 +--- a/tests/sysfs.c ++++ b/tests/sysfs.c +@@ -29,7 +29,7 @@ char *__wrap_udev_device_get_syspath(struct udev_device *ud) + return val; + } + +-int WRAP_FUNC(open)(const char *pathname, int flags) ++int WRAP_OPEN(const char *pathname, int flags) + { + int ret; + +@@ -167,10 +167,10 @@ static void test_sagv_open_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); + errno = ENOENT; +- wrap_will_return(WRAP_FUNC(open), -1); ++ wrap_will_return(WRAP_OPEN, -1); + expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' cannot be opened"); + assert_int_equal(sysfs_attr_get_value((void *)state, "bar", + buf, sizeof(buf)), -ENOENT); +@@ -182,9 +182,9 @@ static void test_sagv_read_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, sizeof(buf)); + errno = EISDIR; +@@ -197,9 +197,9 @@ static void test_sagv_read_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/baz'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/baz"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, sizeof(buf)); + errno = EPERM; +@@ -223,9 +223,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) + memset(buf, '.', sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, bufsz); + will_return(__wrap_read, sizeof(input) - 1); +@@ -250,9 +250,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) + memset(buf, '.', sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/baz'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/baz"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, bufsz); + will_return(__wrap_read, sizeof(input) - 1); +@@ -301,9 +301,9 @@ static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) + memset(buf, '.', sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_RDONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_RDONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_read, fd, TEST_FD); + expect_value(__wrap_read, count, bufsz); + will_return(__wrap_read, sizeof(input) - 1); +@@ -386,10 +386,10 @@ static void test_sasv_open_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_WRONLY); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_WRONLY); + errno = EPERM; +- wrap_will_return(WRAP_FUNC(open), -1); ++ wrap_will_return(WRAP_OPEN, -1); + expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' cannot be opened"); + assert_int_equal(sysfs_attr_set_value((void *)state, "bar", + buf, sizeof(buf)), -EPERM); +@@ -401,9 +401,9 @@ static void test_sasv_write_fail(void **state) + + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_WRONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_WRONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_write, fd, TEST_FD); + expect_value(__wrap_write, count, sizeof(buf)); + errno = EISDIR; +@@ -422,9 +422,9 @@ static void _test_sasv_write(void **state, unsigned int n_written) + assert_in_range(n_written, 0, sizeof(buf)); + will_return(__wrap_udev_device_get_syspath, "/foo"); + expect_condlog(4, "open '/foo/bar'"); +- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); +- expect_value(WRAP_FUNC(open), flags, O_WRONLY); +- wrap_will_return(WRAP_FUNC(open), TEST_FD); ++ expect_string(WRAP_OPEN, pathname, "/foo/bar"); ++ expect_value(WRAP_OPEN, flags, O_WRONLY); ++ wrap_will_return(WRAP_OPEN, TEST_FD); + expect_value(__wrap_write, fd, TEST_FD); + expect_value(__wrap_write, count, sizeof(buf)); + will_return(__wrap_write, n_written); +@@ -489,7 +489,7 @@ int main(void) + { + int ret = 0; + +- init_test_verbosity(4); ++ init_test_verbosity(5); + ret += test_sysfs(); + return ret; + } +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 665d438e..cdb2780d 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -40,17 +40,17 @@ const char default_wwid_1[] = "TEST-WWID-1"; + */ + + +-int REAL_FUNC(open)(const char *path, int flags, int mode); ++int REAL_OPEN(const char *path, int flags, int mode); + + static const char _mocked_filename[] = "mocked_path"; + +-int WRAP_FUNC(open)(const char *path, int flags, int mode) ++int WRAP_OPEN(const char *path, int flags, int mode) + { + condlog(4, "%s: %s", __func__, path); + + if (!strcmp(path, _mocked_filename)) + return 111; +- return REAL_FUNC(open)(path, flags, mode); ++ return REAL_OPEN(path, flags, mode); + } + + int __wrap_libmp_get_version(int which, unsigned int version[3]) +diff --git a/tests/wrap64.h b/tests/wrap64.h +index b0a4d831..7e434206 100644 +--- a/tests/wrap64.h ++++ b/tests/wrap64.h +@@ -29,6 +29,20 @@ + #define WRAP_FUNC(x) CONCAT2(__wrap_, WRAP_NAME(x)) + #define REAL_FUNC(x) CONCAT2(__real_, WRAP_NAME(x)) + ++/* ++ * With clang, glibc 2.39, and _FILE_OFFSET_BITS==64, ++ * open() resolves to __open64_2(). ++ */ ++#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 39) && \ ++ defined(__clang__) && __clang__ == 1 && \ ++ defined(__fortify_use_clang) && __fortify_use_clang == 1 ++#define WRAP_OPEN_NAME __open64_2 ++#else ++#define WRAP_OPEN_NAME WRAP_NAME(open) ++#endif ++#define WRAP_OPEN CONCAT2(__wrap_, WRAP_OPEN_NAME) ++#define REAL_OPEN CONCAT2(__real_, WRAP_OPEN_NAME) ++ + /* + * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. + * https://savannah.gnu.org/forum/forum.php?forum_id=9205 diff --git a/0020-GitHub-actions-fixes-for-spelling-CI.patch b/0020-GitHub-actions-fixes-for-spelling-CI.patch new file mode 100644 index 0000000..21b74ff --- /dev/null +++ b/0020-GitHub-actions-fixes-for-spelling-CI.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 8 Mar 2024 10:04:39 +0100 +Subject: [PATCH] GitHub actions: fixes for spelling CI + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/patterns.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt +index 57767ea1..858faee6 100644 +--- a/.github/actions/spelling/patterns.txt ++++ b/.github/actions/spelling/patterns.txt +@@ -22,6 +22,7 @@ + \bdmmp_pgs\b + \bdmmp_mpath_kdev_name_get\b + \bfast_io_fail_tmo\b ++\bLimitRTPRIO\b + \bmax_fds\b + \bmissing_uev_wait_timeout\b + \bMPATH_MAX_PARAM_LEN\b +@@ -86,6 +87,7 @@ + \bprin_resvdescr\b + \bprout_param_descriptor\b + \brq_servact\b ++\bSCHED_RT_PRIO\b + \bssize_t\b + \btrnptid_list\b + \buxsock_timeout\b diff --git a/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch b/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch new file mode 100644 index 0000000..59cdd0e --- /dev/null +++ b/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 27 Feb 2024 09:57:47 +0100 +Subject: [PATCH] GitHub workflows: run workflows if workflow file has changed + +We want to run workflows if the workflow file itself has changed. + +Fixes: 2cbe81a ("GitHub Workflows: run expensive workflows only on relevant changes") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 1 + + .github/workflows/foreign.yaml | 2 ++ + .github/workflows/multiarch-stable.yaml | 2 ++ + .github/workflows/multiarch.yaml | 2 ++ + .github/workflows/native.yaml | 2 ++ + .github/workflows/rolling.yaml | 2 ++ + .github/workflows/spelling.yml | 2 ++ + 7 files changed, 13 insertions(+) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 53382420..393322e5 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -5,6 +5,7 @@ on: + - queue + - abi + paths: ++ - '.github/workflows/abi.yaml' + - '**.h' + - '**.c' + pull_request: +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 92f6d17a..a62ae009 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/foreign.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/foreign.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml +index 45b74c51..e51d383c 100644 +--- a/.github/workflows/multiarch-stable.yaml ++++ b/.github/workflows/multiarch-stable.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/multiarch-stable.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/multiarch-stable.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml +index b4dec9c7..7b762e5c 100644 +--- a/.github/workflows/multiarch.yaml ++++ b/.github/workflows/multiarch.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/multiarch.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/multiarch.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 09133c1e..0ef9df94 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/native.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/native.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml +index 1f1507ee..3536b944 100644 +--- a/.github/workflows/rolling.yaml ++++ b/.github/workflows/rolling.yaml +@@ -6,6 +6,7 @@ on: + - queue + - tip + paths: ++ - '.github/workflows/rolling.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +@@ -15,6 +16,7 @@ on: + - master + - queue + paths: ++ - '.github/workflows/rolling.yaml' + - '**.h' + - '**.c' + - '**Makefile*' +diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml +index 0416fa9e..7943ebb8 100644 +--- a/.github/workflows/spelling.yml ++++ b/.github/workflows/spelling.yml +@@ -63,7 +63,9 @@ on: + tags-ignore: + - "**" + paths: ++ - '.github/workflows/spelling.yml' + - 'README*' ++ - 'NEWS.md' + - '**.3' + - '**.5' + - '**.8' diff --git a/0022-multipath-tools-add-TGTDIR-option.patch b/0022-multipath-tools-add-TGTDIR-option.patch new file mode 100644 index 0000000..d26fb18 --- /dev/null +++ b/0022-multipath-tools-add-TGTDIR-option.patch @@ -0,0 +1,106 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 14:44:45 +0200 +Subject: [PATCH] multipath-tools: add TGTDIR option + +TGTDIR is a convenience option for developers for building multipath-tools such +that compiled-in paths of the plugins, config files, etc. match an +installation under some optional path. See README.md for instructions and +examples. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 2 ++ + Makefile.inc | 8 +++---- + README.md | 33 +++++++++++++++++++++++++++++ + 3 files changed, 39 insertions(+), 4 deletions(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 5906403d..fc9f22f8 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -167,6 +167,7 @@ retrigger + rhabarber + rootprefix + rootprefixdir ++rpmbuild + rport + rtpi + sas +@@ -200,6 +201,7 @@ tcp + TESTDEPS + testname + tgill ++TGTDIR + TIDS + tmo + tpg +diff --git a/Makefile.inc b/Makefile.inc +index 5668e638..81b86cd8 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -101,9 +101,9 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) + CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -D_FILE_OFFSET_BITS=64 \ +- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ +- -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ +- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ ++ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ ++ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ ++ -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ + -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS := -fPIE -DPIE +@@ -149,4 +149,4 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) + + %: %.in + @echo creating $@ +- $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ ++ $(Q)sed 's:@CONFIGFILE@:'$(TGTDIR)$(configfile)':g;s:@CONFIGDIR@:'$(TGTDIR)$(configdir)':g;s:@STATE_DIR@:'$(TGTDIR)$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ +diff --git a/README.md b/README.md +index d4f35f57..7207b14c 100644 +--- a/README.md ++++ b/README.md +@@ -151,6 +151,39 @@ sufficient control. See `Makefile.inc` for even more fine-grained control. + On such distributions, override `unitdir` and `libudevdir` to use systemd's + `rootprefix`: `make libudevdir=/lib/udev unitdir=/lib/systemd/system` + ++### prefix, DESTDIR and TGTDIR ++ ++`prefix` and related variables are included in compiled-in paths like ++`plugindir` and are used by `make install`. Using `prefix` is useful if ++multipath-tools is built locally on the same host where it's supposed to be ++installed. ++ ++By convention, the `DESTDIR` variable is prepended to all paths by `make ++install`, but not to any compiled-in paths. ++It is useful if the software is built on one system (build host) but intended ++to be run on another system (installation host). This is typically used in build ++systems like *rpmbuild* to set a root directory for all the installed ++files. ++ ++On the contrary, the `TGTDIR` variable is used for compiled-in paths only, and ++ignored by `make install`. It is useful for running multipath-tools in a separate ++subdirectory in the installation host, mostly for testing / development ++purposes. ++ ++For example, ++ ++ make prefix=/opt DESTDIR=/build TGTDIR=/test install ++ ++will install plugins into `/build/opt/lib64/multipath` on the build ++host. On the installation host, the plugins will be expected to be found under ++`/test/opt/lib64/multipath`. If the developer runs ++ ++ rsync -a $BUILD_HOST:$DESTDIR/ $INSTALL_HOST:$TGTDIR/ ++ ++and adds `$TGTDIR/lib64` to `LD_LIBRARY_PATH` on the installation host, the ++multipath binaries installed under `$TGTDIR` will find their plugins and ++configuration files in the expected compiled-in paths. ++ + ### Compiler Options + + Use `OPTFLAGS` to change optimization-related compiler options; diff --git a/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch b/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch new file mode 100644 index 0000000..b59f879 --- /dev/null +++ b/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 17:18:18 +0200 +Subject: [PATCH] libmultipath: move get_udev_for_mpp to sysfs.c + +No functional changes, just code movement. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 20 -------------------- + libmultipath/sysfs.c | 19 +++++++++++++++++++ + libmultipath/sysfs.h | 4 ++++ + 3 files changed, 23 insertions(+), 20 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 4ecf6ba4..89ac03d5 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -453,26 +453,6 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) + return r; + } + +-static struct udev_device * +-get_udev_for_mpp(const struct multipath *mpp) +-{ +- dev_t devnum; +- struct udev_device *udd; +- +- if (!mpp || !has_dm_info(mpp)) { +- condlog(1, "%s called with empty mpp", __func__); +- return NULL; +- } +- +- devnum = makedev(mpp->dmi.major, mpp->dmi.minor); +- udd = udev_device_new_from_devnum(udev, 'b', devnum); +- if (!udd) { +- condlog(1, "failed to get udev device for %s", mpp->alias); +- return NULL; +- } +- return udd; +-} +- + void trigger_partitions_udev_change(struct udev_device *dev, + const char *action, int len) + { +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 328951ed..afe9de91 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -339,3 +339,22 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) + + return found; + } ++ ++struct udev_device *get_udev_for_mpp(const struct multipath *mpp) ++{ ++ dev_t devnum; ++ struct udev_device *udd; ++ ++ if (!mpp || !has_dm_info(mpp)) { ++ condlog(1, "%s called with empty mpp", __func__); ++ return NULL; ++ } ++ ++ devnum = makedev(mpp->dmi.major, mpp->dmi.minor); ++ udd = udev_device_new_from_devnum(udev, 'b', devnum); ++ if (!udd) { ++ condlog(1, "failed to get udev device for %s", mpp->alias); ++ return NULL; ++ } ++ return udd; ++} +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 2db86bd6..3be3f665 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -39,4 +39,8 @@ do { \ + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); ++ ++struct multipath; ++struct udev_device *get_udev_for_mpp(const struct multipath *mpp); ++ + #endif diff --git a/0024-libmultipath-add-mp_find_path_by_devt.patch b/0024-libmultipath-add-mp_find_path_by_devt.patch new file mode 100644 index 0000000..8a85be2 --- /dev/null +++ b/0024-libmultipath-add-mp_find_path_by_devt.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 14:57:33 +0200 +Subject: [PATCH] libmultipath: add mp_find_path_by_devt() + +A helper function that searches a struct multipath by dev_t, and +works whether or not mpp->paths is currently available. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs.c | 19 +++++++++++++++++++ + libmultipath/structs.h | 3 +++ + 2 files changed, 22 insertions(+) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 74e31a13..e248fb51 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -526,6 +526,25 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t) + return NULL; + } + ++struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt) ++{ ++ struct path *pp; ++ struct pathgroup *pgp; ++ unsigned int i, j; ++ ++ pp = find_path_by_devt(mpp->paths, devt); ++ if (pp) ++ return pp; ++ ++ vector_foreach_slot (mpp->pg, pgp, i){ ++ vector_foreach_slot (pgp->paths, pp, j){ ++ if (!strcmp(pp->dev_t, devt)) ++ return pp; ++ } ++ } ++ return NULL; ++} ++ + static int do_pathcount(const struct multipath *mpp, const int *states, + unsigned int nr_states) + { +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 734905e2..a25eb9d5 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -568,6 +568,9 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt + struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev); + struct path * first_path (const struct multipath *mpp); + ++struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt); ++ ++ + int pathcount (const struct multipath *, int); + int count_active_paths(const struct multipath *); + int count_active_pending_paths(const struct multipath *); diff --git a/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch b/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch new file mode 100644 index 0000000..aaa0e9f --- /dev/null +++ b/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 11 Apr 2024 17:20:14 +0200 +Subject: [PATCH] Revert "libmultipath: fix max_sectors_kb on adding path" + +This reverts commit bbb77f318ee483292f50a7782aecaecc7e60f727. +Reviewed-by: Benjamin Marzinski + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 89ac03d5..13602f3f 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -575,12 +575,11 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + ssize_t len; + int i, j, ret, err = 0; + struct udev_device *udd; +- int max_sectors_kb = mpp->max_sectors_kb; ++ int max_sectors_kb; + +- /* by default, do not initialize max_sectors_kb on the device */ +- if (max_sectors_kb == MAX_SECTORS_KB_UNDEF && !is_reload) ++ if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) + return 0; +- /* on reload, re-apply the user tuning on all the path devices */ ++ max_sectors_kb = mpp->max_sectors_kb; + if (is_reload) { + if (!has_dm_info(mpp) && + dm_get_info(mpp->alias, &mpp->dmi) != 0) { diff --git a/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch b/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch new file mode 100644 index 0000000..c82cfe7 --- /dev/null +++ b/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Apr 2024 22:20:46 +0200 +Subject: [PATCH] libmultipath: Only set max_sectors_kb on map creation + +Changing max_sectors_kb on a live map is dangerous. When I/O occurs while the +max_sectors_kb value of a map is larger than that of any of its paths, I/O +errors like this may result: + + blk_insert_cloned_request: over max size limit. (127 > 126) + +This situation must be strictly avoided. The kernel makes sure that the +map's limits match those of the paths when the map is created. But setting +max_sectors_kb on path devices before reloading is dangerous, even if we +read the value from the map's max_sectors_kb beforehand. The reason for +this is that the sysfs value max_sectors_kb is the kernel's max_sectors +divided by 2, and user space has no way to figure out if the kernel-internal +value is odd or even. Thus by writing back the value just read to +max_sectors_kb, one might actually decrease the kernel value by one. + +The only safe way to set max_sectors_kb on a live map would be to suspend +it, flushing all outstanding IO, then the path max_sectors_kb, reload, +and resume. + +Since commit 8fd4868 ("libmultipath: don't set max_sectors_kb on reloads"), +we don't set the configured max_sectors_kb any more. But as shown above, +this is not safe. So really only set max_sectors_kb when creating a map. + +Users who have stacked block devices on top of multipath, as described in the +commit message of 8fd4868 must make sure that the max_sectors_kb setting is +correct when the multipath map is first created. Decreasing the map's +max_sectors_kb value (without touching the paths) should actually be possible +in this situation, because stacked block devices are usually bio-based, and +bio-based IO (in contrast to request-based) can be split if the lower-level +device has can't handle the size of the I/O. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 38 ++++---------------------------------- + 1 file changed, 4 insertions(+), 34 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 13602f3f..8cbb2a88 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -566,46 +566,18 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + mpp->needs_paths_uevent = 0; + } + +-static int +-sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) ++static int sysfs_set_max_sectors_kb(struct multipath *mpp) + { + struct pathgroup * pgp; + struct path *pp; + char buff[11]; + ssize_t len; + int i, j, ret, err = 0; +- struct udev_device *udd; +- int max_sectors_kb; + + if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) + return 0; +- max_sectors_kb = mpp->max_sectors_kb; +- if (is_reload) { +- if (!has_dm_info(mpp) && +- dm_get_info(mpp->alias, &mpp->dmi) != 0) { +- condlog(1, "failed to get dm info for %s", mpp->alias); +- return 1; +- } +- udd = get_udev_for_mpp(mpp); +- if (!udd) { +- condlog(1, "failed to get udev device to set max_sectors_kb for %s", mpp->alias); +- return 1; +- } +- ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, +- sizeof(buff)); +- udev_device_unref(udd); +- if (!sysfs_attr_value_ok(ret, sizeof(buff))) { +- condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); +- return 1; +- } +- if (sscanf(buff, "%u\n", &max_sectors_kb) != 1) { +- condlog(1, "can't parse current max_sectors_kb from %s", +- mpp->alias); +- return 1; +- } +- } +- snprintf(buff, 11, "%d", max_sectors_kb); +- len = strlen(buff); ++ ++ len = snprintf(buff, sizeof(buff), "%d", mpp->max_sectors_kb); + + vector_foreach_slot (mpp->pg, pgp, i) { + vector_foreach_slot(pgp->paths, pp, j) { +@@ -923,7 +895,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + return DOMAP_RETRY; + } + +- sysfs_set_max_sectors_kb(mpp, 0); ++ sysfs_set_max_sectors_kb(mpp); + if (is_daemon && mpp->ghost_delay > 0 && count_active_paths(mpp) && + pathcount(mpp, PATH_UP) == 0) + mpp->ghost_delay_tick = mpp->ghost_delay; +@@ -934,7 +906,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + + case ACT_RELOAD: + case ACT_RELOAD_RENAME: +- sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; + r = dm_addmap_reload(mpp, params, 0); +@@ -942,7 +913,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + + case ACT_RESIZE: + case ACT_RESIZE_RENAME: +- sysfs_set_max_sectors_kb(mpp, 1); + if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) + mpp->ghost_delay_tick = 0; + r = dm_addmap_reload(mpp, params, 1); diff --git a/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch b/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch new file mode 100644 index 0000000..a4389df --- /dev/null +++ b/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch @@ -0,0 +1,233 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Apr 2024 23:59:03 +0200 +Subject: [PATCH] libmultipath: set max_sectors_kb in adopt_paths() + +As explained in the previous commit, setting max_sectors_kb for +paths that are members of a live map is dangerous. But as long as +a path is not a member of a map, setting max_sectors_kb poses no risk. +Set the parameter in adopt_paths(), for paths that aren't members +of the map yet. In order to determine whether or not a path is currently +member of the map, adopt_paths() needs to passed the current member list. If +(and only if) it's called from coalesce_paths(), the passed struct multipath +doesn not represent the current state of the map; adopt_paths() must therefore +get a new argument current_mpp that represents the kernel state. + +We must still call sysfs_set_max_sectors_kb() from domap() in the ACT_CREATE +case, because when adopt_paths is called from coalesce_paths() for a map that +doesn't exist yet, mpp->max_sectors_kb is not set. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 2 +- + libmultipath/structs_vec.c | 62 ++++++++++++++++++++++++++++++++++---- + libmultipath/structs_vec.h | 6 ++-- + multipathd/main.c | 6 ++-- + tests/Makefile | 2 +- + tests/test-lib.c | 9 +++++- + 6 files changed, 73 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 8cbb2a88..b5c701fa 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -1105,7 +1105,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, + /* + * at this point, we know we really got a new mp + */ +- mpp = add_map_with_path(vecs, pp1, 0); ++ mpp = add_map_with_path(vecs, pp1, 0, cmpp); + if (!mpp) { + orphan_path(pp1, "failed to create multipath device"); + continue; +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 0fc608c2..c0c5cc90 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -242,7 +242,38 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + return must_reload; + } + +-int adopt_paths(vector pathvec, struct multipath *mpp) ++static bool set_path_max_sectors_kb(const struct path *pp, int max_sectors_kb) ++{ ++ char buf[11]; ++ ssize_t len; ++ int ret, current; ++ bool rc = false; ++ ++ if (max_sectors_kb == MAX_SECTORS_KB_UNDEF) ++ return rc; ++ ++ if (sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 ++ || sscanf(buf, "%d\n", ¤t) != 1) ++ current = MAX_SECTORS_KB_UNDEF; ++ if (current == max_sectors_kb) ++ return rc; ++ ++ len = snprintf(buf, sizeof(buf), "%d", max_sectors_kb); ++ ret = sysfs_attr_set_value(pp->udev, "queue/max_sectors_kb", buf, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "failed setting max_sectors_kb on %s", ++ pp->dev); ++ else { ++ condlog(3, "%s: set max_sectors_kb to %d for %s", __func__, ++ max_sectors_kb, pp->dev); ++ rc = true; ++ } ++ return rc; ++} ++ ++int adopt_paths(vector pathvec, struct multipath *mpp, ++ const struct multipath *current_mpp) + { + int i, ret; + struct path * pp; +@@ -285,9 +316,28 @@ int adopt_paths(vector pathvec, struct multipath *mpp) + continue; + } + +- if (!find_path_by_devt(mpp->paths, pp->dev_t) && +- store_path(mpp->paths, pp)) +- goto err; ++ if (!find_path_by_devt(mpp->paths, pp->dev_t)) { ++ ++ if (store_path(mpp->paths, pp)) ++ goto err; ++ /* ++ * Setting max_sectors_kb on live paths is dangerous. ++ * But we can do it here on a path that isn't yet part ++ * of the map. If this value is lower than the current ++ * max_sectors_kb and the map is reloaded, the map's ++ * max_sectors_kb will be safely adjusted by the kernel. ++ * ++ * We must make sure that the path is not part of the ++ * map yet. Normally we can check this in mpp->paths. ++ * But if adopt_paths is called from coalesce_paths, ++ * we need to check the separate struct multipath that ++ * has been obtained from map_discovery(). ++ */ ++ if (!current_mpp || ++ !mp_find_path_by_devt(current_mpp, pp->dev_t)) ++ mpp->need_reload = mpp->need_reload || ++ set_path_max_sectors_kb(pp, mpp->max_sectors_kb); ++ } + + pp->mpp = mpp; + condlog(3, "%s: ownership set to %s", +@@ -693,7 +743,7 @@ find_existing_alias (struct multipath * mpp, + } + + struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, +- int add_vec) ++ int add_vec, const struct multipath *current_mpp) + { + struct multipath * mpp; + struct config *conf = NULL; +@@ -721,7 +771,7 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, + goto out; + mpp->size = pp->size; + +- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ if (adopt_paths(vecs->pathvec, mpp, current_mpp) || pp->mpp != mpp || + find_slot(mpp->paths, pp) == -1) + goto out; + +diff --git a/libmultipath/structs_vec.h b/libmultipath/structs_vec.h +index 3253f1bb..dbc43058 100644 +--- a/libmultipath/structs_vec.h ++++ b/libmultipath/structs_vec.h +@@ -13,7 +13,8 @@ struct vectors { + + void set_no_path_retry(struct multipath *mpp); + +-int adopt_paths (vector pathvec, struct multipath * mpp); ++int adopt_paths (vector pathvec, struct multipath *mpp, ++ const struct multipath *current_mpp); + void orphan_path (struct path * pp, const char *reason); + void set_path_removed(struct path *pp); + +@@ -28,7 +29,8 @@ void remove_maps (struct vectors * vecs); + + void sync_map_state (struct multipath *); + struct multipath * add_map_with_path (struct vectors * vecs, +- struct path * pp, int add_vec); ++ struct path * pp, int add_vec, ++ const struct multipath *current_mpp); + void update_queue_mode_del_path(struct multipath *mpp); + void update_queue_mode_add_path(struct multipath *mpp); + int update_multipath_table (struct multipath *mpp, vector pathvec, int flags); +diff --git a/multipathd/main.c b/multipathd/main.c +index dd17d5c3..d8518a92 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -636,7 +636,7 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + + retry: + condlog(4, "%s: updating new map", mpp->alias); +- if (adopt_paths(vecs->pathvec, mpp)) { ++ if (adopt_paths(vecs->pathvec, mpp, NULL)) { + condlog(0, "%s: failed to adopt paths for new map update", + mpp->alias); + retries = -1; +@@ -1231,7 +1231,7 @@ rescan: + if (mpp) { + condlog(4,"%s: adopting all paths for path %s", + mpp->alias, pp->dev); +- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || ++ if (adopt_paths(vecs->pathvec, mpp, NULL) || pp->mpp != mpp || + find_slot(mpp->paths, pp) == -1) + goto fail; /* leave path added to pathvec */ + +@@ -1245,7 +1245,7 @@ rescan: + return 0; + } + condlog(4,"%s: creating new map", pp->dev); +- if ((mpp = add_map_with_path(vecs, pp, 1))) { ++ if ((mpp = add_map_with_path(vecs, pp, 1, NULL))) { + mpp->action = ACT_CREATE; + /* + * We don't depend on ACT_CREATE, as domap will +diff --git a/tests/Makefile b/tests/Makefile +index d1d52dde..4005204a 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -45,7 +45,7 @@ dmevents-test_OBJDEPS = $(multipathdir)/devmapper.o + dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu + hwtable-test_TESTDEPS := test-lib.o + hwtable-test_OBJDEPS := $(multipathdir)/discovery.o $(multipathdir)/blacklist.o \ +- $(multipathdir)/structs.o $(multipathdir)/propsel.o ++ $(multipathdir)/structs_vec.o $(multipathdir)/structs.o $(multipathdir)/propsel.o + hwtable-test_LIBDEPS := -ludev -lpthread -ldl + blacklist-test_TESTDEPS := test-log.o + blacklist-test_LIBDEPS := -ludev +diff --git a/tests/test-lib.c b/tests/test-lib.c +index cdb2780d..88f35e94 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -152,6 +152,13 @@ int __wrap_sysfs_get_size(struct path *pp, unsigned long long *sz) + return 0; + } + ++int __wrap_sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, ++ const char * value, size_t value_len) ++{ ++ condlog(5, "%s: %s", __func__, value); ++ return value_len; ++} ++ + void *__wrap_udev_device_get_parent_with_subsystem_devtype( + struct udev_device *ud, const char *subsys, char *type) + { +@@ -400,7 +407,7 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) + /* pathinfo() call in adopt_paths */ + mock_pathinfo(DI_CHECKER|DI_PRIO, &mop); + +- mp = add_map_with_path(vecs, pp, 1); ++ mp = add_map_with_path(vecs, pp, 1, NULL); + assert_ptr_not_equal(mp, NULL); + + /* TBD: mock setup_map() ... */ diff --git a/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch b/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch new file mode 100644 index 0000000..9b66bbb --- /dev/null +++ b/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch @@ -0,0 +1,89 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 17:19:43 +0200 +Subject: [PATCH] libmultipath: add wildcard %k for printing max_sectors_kb + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 360308d2..efd5a16a 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -32,6 +32,7 @@ + #include "util.h" + #include "foreign.h" + #include "strbuf.h" ++#include "sysfs.h" + + #define PRINT_PATH_LONG "%w %i %d %D %p %t %T %s %o" + #define PRINT_PATH_INDENT "%i %d %D %t %T %o" +@@ -431,6 +432,27 @@ snprint_multipath_vpd_data(struct strbuf *buff, + return append_strbuf_str(buff, "[undef]"); + } + ++static void cleanup_udev_device(struct udev_device **udd) ++{ ++ if (*udd) ++ udev_device_unref(*udd); ++} ++ ++static int ++snprint_multipath_max_sectors_kb(struct strbuf *buff, const struct multipath *mpp) ++{ ++ char buf[11]; ++ int max_sectors_kb; ++ struct udev_device *udd __attribute__((cleanup(cleanup_udev_device))) ++ = get_udev_for_mpp(mpp); ++ ++ if (!udd || ++ sysfs_attr_get_value(udd, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 || ++ sscanf(buf, "%d\n", &max_sectors_kb) != 1) ++ return print_strbuf(buff, "n/a"); ++ return print_strbuf(buff, "%d", max_sectors_kb); ++} ++ + /* + * path info printing functions + */ +@@ -790,6 +812,20 @@ snprint_alua_tpg(struct strbuf *buff, const struct path * pp) + return print_strbuf(buff, "0x%04x", pp->tpg_id); + } + ++static int ++snprint_path_max_sectors_kb(struct strbuf *buff, const struct path *pp) ++{ ++ char buf[11]; ++ int max_sectors_kb; ++ ++ if (!pp->udev || ++ sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", ++ buf, sizeof(buf)) <= 0 || ++ sscanf(buf, "%d\n", &max_sectors_kb) != 1) ++ return print_strbuf(buff, "n/a"); ++ return print_strbuf(buff, "%d", max_sectors_kb); ++} ++ + static const struct multipath_data mpd[] = { + {'n', "name", snprint_name}, + {'w', "uuid", snprint_multipath_uuid}, +@@ -815,6 +851,7 @@ static const struct multipath_data mpd[] = { + {'e', "rev", snprint_multipath_rev}, + {'G', "foreign", snprint_multipath_foreign}, + {'g', "vpd page data", snprint_multipath_vpd_data}, ++ {'k', "max_sectors_kb",snprint_multipath_max_sectors_kb}, + }; + + static const struct path_data pd[] = { +@@ -845,6 +882,7 @@ static const struct path_data pd[] = { + {'I', "init_st", snprint_initialized}, + {'L', "LUN hex", snprint_path_lunhex}, + {'A', "TPG", snprint_alua_tpg}, ++ {'k', "max_sectors_kb",snprint_path_max_sectors_kb}, + }; + + static const struct pathgroup_data pgd[] = { diff --git a/0029-multipath.conf-5-update-documentation-for-max_sector.patch b/0029-multipath.conf-5-update-documentation-for-max_sector.patch new file mode 100644 index 0000000..dcdf164 --- /dev/null +++ b/0029-multipath.conf-5-update-documentation-for-max_sector.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 17 Apr 2024 18:59:04 +0200 +Subject: [PATCH] multipath.conf(5): update documentation for max_sectors_kb + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5.in | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index c788c180..b29a75fe 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1311,11 +1311,36 @@ The default is: \fB0\fR + . + .TP + .B max_sectors_kb +-Sets the max_sectors_kb device parameter on all path devices and the multipath +-device to the specified value. ++Sets the \fImax_sectors_kb\fR device parameter on some path devices and the multipath ++device to the specified value. \fImax_sectors_kb\fR is the largest I/O size, in units ++of 1024 bytes, that the kernel allows for a single I/O request. For hardware devices ++like SCSI disks, this value is limited by the capabilities of the hardware. ++It is crucial that the value of a multipath map is never higher than the minimum value of ++of all its path devices. This is ensured by the kernel when a multipath map ++is loaded, but manipulating the values of a map or either of its paths while the ++map is live can cause race conditions and I/O errors. Therefore this value is only ++enforced by multipathd when a multipath map is first created, or when a path device ++is added to a map. In both cases, race conditions are avoided by the kernel. + .RS +-.TP +-The default is: in \fB/sys/block//queue/max_sectors_kb\fR ++.PP ++Setting \fImax_sectors_kb\fR does not guarantee that all path devices will have this ++value set. It is not an error if the value of a path device is higher than that of ++the containing multipath map. It is also not an error if the actual limit of a map is ++lower than the value in \fI@CONFIGFILE@\fR. This can happen if the hardware limits of one ++or more path devices are lower than the configured value. ++.PP ++Normally the kernel and its device drivers take care of the maximum ++I/O size, and administrators do not need to bother about \fImax_sectors_kb\fR. ++But some hardware devices may report incorrect I/O size limits, or other components ++in the environment (e.g. the fabric) may impose constraints that the kernel cannot ++detect. In such cases setting \fImax_sectors_kb\fR makes sense. It should be set when ++maps are first created, and not be changed thereafter. ++If the setting \fBmust\fR be changed for a live map, set the ++value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use ++\fBmultipathd del path \fR and \fBmultipathd add path \fR to ++delete and re-add the same path device. ++.LP ++The default is: \fBundefined\fR. + .RE + . + . diff --git a/0030-multipath-tools-simplify-comment-in-hwtable.patch b/0030-multipath-tools-simplify-comment-in-hwtable.patch new file mode 100644 index 0000000..59090a7 --- /dev/null +++ b/0030-multipath-tools-simplify-comment-in-hwtable.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sun, 28 Apr 2024 01:45:35 +0200 +Subject: [PATCH] multipath-tools: simplify comment in hwtable + +Instead of adding the new 5300 model, replace them with wildcards. + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 640bf347..7aac3f37 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -683,8 +683,8 @@ static struct hwentry default_hw[] = { + .pgfailback = -FAILBACK_IMMEDIATE, + }, + { +- // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 +- // FlashSystem V840/V9000/5000/5100/5200/7200/7300/9100/9200/9200R/9500 ++ // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) ++ // Flex System V7000 / FlashSystem V840/V9000 and 5x00/7x00/9x00 + .vendor = "IBM", + .product = "^2145", + .no_path_retry = NO_PATH_RETRY_QUEUE, diff --git a/0031-multipath-tools-unify-text-in-multipath.conf.5.patch b/0031-multipath-tools-unify-text-in-multipath.conf.5.patch new file mode 100644 index 0000000..b6d9af3 --- /dev/null +++ b/0031-multipath-tools-unify-text-in-multipath.conf.5.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sun, 28 Apr 2024 01:45:36 +0200 +Subject: [PATCH] multipath-tools: unify text in multipath.conf.5 + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5.in | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index b29a75fe..c1a19ebb 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -187,7 +187,7 @@ The default is: \fBno\fR + . + .TP + .B multipath_dir +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + . + . + .TP +@@ -277,7 +277,7 @@ The default is: \fBno\fR + . + .TP + .B pg_timeout +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + . + . + .TP +@@ -322,7 +322,7 @@ The default is: \fBID_WWN\fR, for NVMe devices + . + .TP + .B getuid_callout +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + . + . + .TP +@@ -995,7 +995,7 @@ The default is: \fB\fR + . + .TP + .B config_dir +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + .RS + .TP + The compiled-in value is: \fB@CONFIGDIR@\fR +@@ -1295,7 +1295,7 @@ The default is: \fBno\fR + . + .TP + .B disable_changed_wwids +-(Deprecated) This option is not supported anymore, and the value is ignored. ++(Deprecated) This option is not supported anymore, and will be ignored. + .RE + . + . +@@ -1340,7 +1340,7 @@ value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use + \fBmultipathd del path \fR and \fBmultipathd add path \fR to + delete and re-add the same path device. + .LP +-The default is: \fBundefined\fR. ++The default is: \fB\fR + .RE + . + . diff --git a/0032-multipath-tools-update-man-pages-dates.patch b/0032-multipath-tools-update-man-pages-dates.patch new file mode 100644 index 0000000..c011eac --- /dev/null +++ b/0032-multipath-tools-update-man-pages-dates.patch @@ -0,0 +1,86 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sun, 28 Apr 2024 01:45:37 +0200 +Subject: [PATCH] multipath-tools: update man pages dates + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persistent_reserve_in.3 | 2 +- + libmpathpersist/mpath_persistent_reserve_out.3 | 2 +- + multipath/multipath.8.in | 2 +- + multipath/multipath.conf.5.in | 2 +- + multipathd/multipathd.8.in | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/libmpathpersist/mpath_persistent_reserve_in.3 b/libmpathpersist/mpath_persistent_reserve_in.3 +index 6cc35349..4ac43fa3 100644 +--- a/libmpathpersist/mpath_persistent_reserve_in.3 ++++ b/libmpathpersist/mpath_persistent_reserve_in.3 +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MPATH_PERSISTENT_RESERVE_IN 3 2018-06-15 Linux ++.TH MPATH_PERSISTENT_RESERVE_IN 3 2024-02-09 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/libmpathpersist/mpath_persistent_reserve_out.3 b/libmpathpersist/mpath_persistent_reserve_out.3 +index 70e26028..3dbeae1f 100644 +--- a/libmpathpersist/mpath_persistent_reserve_out.3 ++++ b/libmpathpersist/mpath_persistent_reserve_out.3 +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MPATH_PERSISTENT_RESERVE_OUT 3 2018-06-15 Linux ++.TH MPATH_PERSISTENT_RESERVE_OUT 3 2024-02-09 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in +index 348eb220..b88e9a4c 100644 +--- a/multipath/multipath.8.in ++++ b/multipath/multipath.8.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH 8 2021-11-12 Linux ++.TH MULTIPATH 8 2023-09-08 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index c1a19ebb..46d3685a 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH.CONF 5 2023-06-15 Linux ++.TH MULTIPATH.CONF 5 2024-04-17 Linux + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in +index f1cab3ff..12b77156 100644 +--- a/multipathd/multipathd.8.in ++++ b/multipathd/multipathd.8.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATHD 8 2022-09-03 Linux ++.TH MULTIPATHD 8 2023-12-19 Linux + . + . + .\" ---------------------------------------------------------------------------- diff --git a/0033-libmultipath-export-partmap_in_use.patch b/0033-libmultipath-export-partmap_in_use.patch new file mode 100644 index 0000000..47a6772 --- /dev/null +++ b/0033-libmultipath-export-partmap_in_use.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:13 -0400 +Subject: [PATCH] libmultipath: export partmap_in_use + +A future commit will make use of this function + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 2 +- + libmultipath/devmapper.h | 1 + + libmultipath/libmultipath.version | 1 + + 3 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 4ce7e82f..a87abf7e 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1043,7 +1043,7 @@ has_partmap(const char *name __attribute__((unused)), + return 1; + } + +-static int ++int + partmap_in_use(const char *name, void *data) + { + int part_count, *ret_count = (int *)data; +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index a7d66604..93caa2aa 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -57,6 +57,7 @@ enum { + DM_FLUSH_BUSY, + }; + ++int partmap_in_use(const char *name, void *data); + int _dm_flush_map (const char *, int, int, int, int); + int dm_flush_map_nopaths(const char * mapname, int deferred_remove); + #define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 724786d5..e070f296 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -141,6 +141,7 @@ global: + need_io_err_check; + orphan_path; + parse_prkey_flags; ++ partmap_in_use; + pathcount; + path_discovery; + path_get_tpgs; diff --git a/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch b/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch new file mode 100644 index 0000000..7c36521 --- /dev/null +++ b/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch @@ -0,0 +1,346 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:14 -0400 +Subject: [PATCH] libmultipath: change flush_on_last_del to fix a multipathd + hang + +Commit 9bd3482e ("multipathd: make flush_map() delete maps like the +multipath command") fixed an issue where deleting a queueing multipath +device through multipathd could hang because the multipath device had +outstanding IO, even though the only openers of it at the time of +deletion were the kpartx partition devices. However it is still possible +to hang multipathd, because autoremoving the device when all paths have +been deleted doesn't disable queueing. To reproduce this hang: + +1. create a multipath device with a kpartx partition on top of it and +no_path_retry set to either "queue" or something long enough to run all +the commands in the reproducer before it disables queueing. +2. disable all the paths to the device with something like: + # echo offline > /sys/block//device/state +3. Write directly to the multipath device with something like: + # dd if=/dev/zero of=/dev/mapper/ bs=4K count=1 +4. delete all the paths to the device with something like: + # echo 1 > /sys/block//device/delete + +Multipathd will hang trying to delete the kpartx device because, as the +last opener, it must flush the multipath device before closing it. +Because it hangs holding the vecs_lock, multipathd will never disable +queueing on the device, so it will hang forever, even if no_path_retry +is set to a number. + +This hang can occur, even if deferred_remove is set. Since nothing has +the kpartx device opened, device-mapper does an immediate remove, which +will still hang. This means that even if deferred_remove is set, +multipathd still cannot delete a map while queueing is enabled. It must +either disable queueing or skip the autoremove. + +Mulitpath can currently be configured to avoid this hang by setting + +flush_on_last_del yes + +However there are good reasons why users wouldn't want to set that. They +may need to be able to survive having all paths getting temporarily +deleted. I should note that this is a pretty rare corner case, since +multipath automatically sets dev_loss_tmo so that it should not trigger +before queueing is disabled. + +This commit avoids the hang by changing the possible values for +flush_on_last_del to "never", "unused", and "always", and sets the +default to "unused". "always" works like "yes" did, "never" will not +disable queueing, and "unused" will only disable queueing if nothing has +the kpartx devices or the multipath device open. In order to be safe, if +the device has queue_if_no_paths set (and in case of "unused", the +device is in-use) the autoremove will be skipped. Also, instead of just +trusting the lack of "queue_if_no_paths" in the current mpp->features, +multipathd will tell the kernel to disable queueing, just to be sure it +actually is. + +I chose "unused" as the default because this should generally only cause +multipathd to work differently from the users perspective when nothing +has the multipath device open but it is queueing and there is +outstanding IO. Without this change, it would have hung instead of +failing the outstanding IO. However, I do understand that an argument +could be made that "never" makes more sense as default, even though it +will cause multipathd to skip autoremoves in cases where it wouldn't +before. The change to the behavior of deffered_remove will be +noticeable, but skipping an autoremove is much better than hanging. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/defaults.h | 2 +- + libmultipath/dict.c | 72 +++++++++++++++++++++++++++++++---- + libmultipath/dict.h | 1 + + libmultipath/hwtable.c | 6 +-- + libmultipath/propsel.c | 4 +- + libmultipath/structs.h | 7 ++-- + multipath/multipath.conf.5.in | 20 +++++++--- + multipathd/main.c | 39 +++++++++++++++---- + 8 files changed, 122 insertions(+), 29 deletions(-) + +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 64b633f2..ed08c251 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -43,7 +43,7 @@ + #define DEFAULT_PRIO PRIO_CONST + #define DEFAULT_PRIO_ARGS "" + #define DEFAULT_CHECKER TUR +-#define DEFAULT_FLUSH FLUSH_DISABLED ++#define DEFAULT_FLUSH FLUSH_UNUSED + #define DEFAULT_USER_FRIENDLY_NAMES USER_FRIENDLY_NAMES_OFF + #define DEFAULT_FORCE_SYNC 0 + #define UNSET_PARTITION_DELIM "/UNSET/" +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 5af036b7..546103f2 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -791,14 +791,70 @@ declare_def_snprint(checker_timeout, print_nonzero) + declare_def_handler(allow_usb_devices, set_yes_no) + declare_def_snprint(allow_usb_devices, print_yes_no) + +-declare_def_handler(flush_on_last_del, set_yes_no_undef) +-declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH) +-declare_ovr_handler(flush_on_last_del, set_yes_no_undef) +-declare_ovr_snprint(flush_on_last_del, print_yes_no_undef) +-declare_hw_handler(flush_on_last_del, set_yes_no_undef) +-declare_hw_snprint(flush_on_last_del, print_yes_no_undef) +-declare_mp_handler(flush_on_last_del, set_yes_no_undef) +-declare_mp_snprint(flush_on_last_del, print_yes_no_undef) ++ ++static const char * const flush_on_last_del_optvals[] = { ++ [FLUSH_NEVER] = "never", ++ [FLUSH_ALWAYS] = "always", ++ [FLUSH_UNUSED] = "unused", ++}; ++ ++static int ++set_flush_on_last_del(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ int i; ++ int *flush_val_ptr = (int *)ptr; ++ char *buff; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ for (i = FLUSH_NEVER; i <= FLUSH_UNUSED; i++) { ++ if (flush_on_last_del_optvals[i] != NULL && ++ !strcmp(buff, flush_on_last_del_optvals[i])) { ++ *flush_val_ptr = i; ++ break; ++ } ++ } ++ ++ if (i > FLUSH_UNUSED) { ++ bool deprecated = true; ++ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) ++ *flush_val_ptr = FLUSH_UNUSED; ++ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) ++ *flush_val_ptr = FLUSH_ALWAYS; ++ else { ++ deprecated = false; ++ condlog(1, "%s line %d, invalid value for flush_on_last_del: \"%s\"", ++ file, line_nr, buff); ++ } ++ if (deprecated) ++ condlog(2, "%s line %d, \"%s\" is a deprecated value for flush_on_last_del and is treated as \"%s\"", ++ file, line_nr, buff, ++ flush_on_last_del_optvals[*flush_val_ptr]); ++ } ++ ++ free(buff); ++ return 0; ++} ++ ++int ++print_flush_on_last_del(struct strbuf *buff, long v) ++{ ++ if (v == FLUSH_UNDEF) ++ return 0; ++ return append_strbuf_quoted(buff, flush_on_last_del_optvals[(int)v]); ++} ++ ++declare_def_handler(flush_on_last_del, set_flush_on_last_del) ++declare_def_snprint_defint(flush_on_last_del, print_flush_on_last_del, ++ DEFAULT_FLUSH) ++declare_ovr_handler(flush_on_last_del, set_flush_on_last_del) ++declare_ovr_snprint(flush_on_last_del, print_flush_on_last_del) ++declare_hw_handler(flush_on_last_del, set_flush_on_last_del) ++declare_hw_snprint(flush_on_last_del, print_flush_on_last_del) ++declare_mp_handler(flush_on_last_del, set_flush_on_last_del) ++declare_mp_snprint(flush_on_last_del, print_flush_on_last_del) + + declare_def_handler(user_friendly_names, set_yes_no_undef) + declare_def_snprint_defint(user_friendly_names, print_yes_no_undef, +diff --git a/libmultipath/dict.h b/libmultipath/dict.h +index 7e2dfbe0..e1794537 100644 +--- a/libmultipath/dict.h ++++ b/libmultipath/dict.h +@@ -18,4 +18,5 @@ int print_undef_off_zero(struct strbuf *buff, long v); + int print_dev_loss(struct strbuf *buff, unsigned long v); + int print_off_int_undef(struct strbuf *buff, long v); + int print_auto_resize(struct strbuf *buff, long v); ++int print_flush_on_last_del(struct strbuf *buff, long v); + #endif /* _DICT_H */ +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 7aac3f37..d1148de7 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -60,7 +60,7 @@ + .no_path_retry = NO_PATH_RETRY_UNDEF, + .minio = 1000, + .minio_rq = 1, +- .flush_on_last_del = FLUSH_DISABLED, ++ .flush_on_last_del = FLUSH_UNUSED, + .user_friendly_names = USER_FRIENDLY_NAMES_OFF, + .fast_io_fail = 5, + .dev_loss = 600, +@@ -829,7 +829,7 @@ static struct hwentry default_hw[] = { + .no_path_retry = NO_PATH_RETRY_QUEUE, + .pgpolicy = GROUP_BY_PRIO, + .pgfailback = -FAILBACK_IMMEDIATE, +- .flush_on_last_del = FLUSH_ENABLED, ++ .flush_on_last_del = FLUSH_ALWAYS, + .dev_loss = MAX_DEV_LOSS_TMO, + .prio_name = PRIO_ONTAP, + .user_friendly_names = USER_FRIENDLY_NAMES_OFF, +@@ -1160,7 +1160,7 @@ static struct hwentry default_hw[] = { + .no_path_retry = NO_PATH_RETRY_FAIL, + .minio = 1, + .minio_rq = 1, +- .flush_on_last_del = FLUSH_ENABLED, ++ .flush_on_last_del = FLUSH_ALWAYS, + .fast_io_fail = 15, + }, + /* +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 44241e2a..e2dcb316 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -963,6 +963,7 @@ out: + int select_flush_on_last_del(struct config *conf, struct multipath *mp) + { + const char *origin; ++ STRBUF_ON_STACK(buff); + + mp_set_mpe(flush_on_last_del); + mp_set_ovr(flush_on_last_del); +@@ -970,8 +971,9 @@ int select_flush_on_last_del(struct config *conf, struct multipath *mp) + mp_set_conf(flush_on_last_del); + mp_set_default(flush_on_last_del, DEFAULT_FLUSH); + out: ++ print_flush_on_last_del(&buff, mp->flush_on_last_del); + condlog(3, "%s: flush_on_last_del = %s %s", mp->alias, +- (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin); ++ get_strbuf_str(&buff), origin); + return 0; + } + +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index a25eb9d5..dbaf4d43 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -109,9 +109,10 @@ enum marginal_pathgroups_mode { + }; + + enum flush_states { +- FLUSH_UNDEF = YNU_UNDEF, +- FLUSH_DISABLED = YNU_NO, +- FLUSH_ENABLED = YNU_YES, ++ FLUSH_UNDEF, ++ FLUSH_NEVER, ++ FLUSH_ALWAYS, ++ FLUSH_UNUSED, + }; + + enum log_checker_err_states { +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 46d3685a..1d3d53bb 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -707,12 +707,22 @@ The default is: \fBno\fR + .TP + .B flush_on_last_del + If set to +-.I yes ++.I always + , multipathd will disable queueing when the last path to a device has been +-deleted. +-.RS +-.TP +-The default is: \fBno\fR ++deleted. If set to ++.I never ++, multipathd will not disable queueing when the last path to a device has ++been deleted. Since multipath cannot safely remove a device while queueing ++is enabled, setting this to \fInever\fR means that multipathd will not ++automatically remove an unused multipath device whose paths are all deleted if ++it is currently set to queue_if_no_path. If set to ++.I unused ++, multipathd will only disable queueing when the last path is removed if ++nothing currently has the multipath device or any of the kpartx partition ++devices on top of it open. ++.RS ++.TP ++The default is: \fBunused\fR + .RE + . + . +diff --git a/multipathd/main.c b/multipathd/main.c +index d8518a92..09286dd0 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -584,19 +584,42 @@ int update_multipath (struct vectors *vecs, char *mapname) + static bool + flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { + int r; ++ bool is_queueing = true; + ++ if (mpp->features) ++ is_queueing = strstr(mpp->features, "queue_if_no_path"); ++ ++ /* It's not safe to do a remove of a map that has "queue_if_no_path" ++ * set, since there could be outstanding IO which will cause ++ * multipathd to hang while attempting the remove */ ++ if (mpp->flush_on_last_del == FLUSH_NEVER && is_queueing) { ++ condlog(2, "%s: map is queueing, can't remove", mpp->alias); ++ return false; ++ } ++ if (mpp->flush_on_last_del == FLUSH_UNUSED && ++ partmap_in_use(mpp->alias, NULL) && is_queueing) { ++ condlog(2, "%s: map in use and queueing, can't remove", ++ mpp->alias); ++ return false; ++ } + /* +- * flush_map will fail if the device is open ++ * This will flush FLUSH_NEVER devices and FLUSH_UNUSED devices ++ * that are in use, but only if they are already marked as not ++ * queueing. That is just to make absolutely certain that they ++ * really are not queueing, like they claim. + */ +- if (mpp->flush_on_last_del == FLUSH_ENABLED) { +- condlog(2, "%s Last path deleted, disabling queueing", ++ condlog(is_queueing ? 2 : 3, "%s Last path deleted, disabling queueing", ++ mpp->alias); ++ mpp->retry_tick = 0; ++ mpp->no_path_retry = NO_PATH_RETRY_FAIL; ++ mpp->disable_queueing = 1; ++ mpp->stat_map_failures++; ++ if (dm_queue_if_no_path(mpp, 0) != 0) { ++ condlog(0, "%s: failed to disable queueing. Not removing", + mpp->alias); +- mpp->retry_tick = 0; +- mpp->no_path_retry = NO_PATH_RETRY_FAIL; +- mpp->disable_queueing = 1; +- mpp->stat_map_failures++; +- dm_queue_if_no_path(mpp, 0); ++ return false; + } ++ + r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove); + if (r != DM_FLUSH_OK) { + if (r == DM_FLUSH_DEFERRED) { diff --git a/0035-libmultipath-remove-redundant-config-option-from-Inf.patch b/0035-libmultipath-remove-redundant-config-option-from-Inf.patch new file mode 100644 index 0000000..8de5639 --- /dev/null +++ b/0035-libmultipath-remove-redundant-config-option-from-Inf.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:15 -0400 +Subject: [PATCH] libmultipath: remove redundant config option from InfiniBox + config + +The InfiniBox config already sets no_path_retry to "fail", so it won't +ever queue IO. That means setting flush_on_last_del to "always" is +redundant, since queueing is always disabled. Remove the +flush_on_last_del parameter, to make it easier for users to override the +default behavior if desired. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index d1148de7..9e008df6 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -1160,7 +1160,6 @@ static struct hwentry default_hw[] = { + .no_path_retry = NO_PATH_RETRY_FAIL, + .minio = 1, + .minio_rq = 1, +- .flush_on_last_del = FLUSH_ALWAYS, + .fast_io_fail = 15, + }, + /* diff --git a/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch b/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch new file mode 100644 index 0000000..f61f658 --- /dev/null +++ b/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:16 -0400 +Subject: [PATCH] libmultipath: pad dev_loss_tmo to avoid race with + no_path_retry + +Currently multipath makes sure that dev_loss_tmo is at least as long as +the configured no path queueing time. The goal is to make sure that path +devices aren't removed while the multipath device is still queueing in +hopes that they will become usable again. + +This is racy. Multipathd may take longer to check the paths than +configured. If strict_timing isn't set, it will definitely take longer. +To account for this, pad the minimum dev_loss_tmo value by five seconds +(one default checker interval) plus one second per minute of no path +queueing time. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 6fd4dabb..e2052422 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -901,6 +901,11 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) + uint64_t no_path_retry_tmo = + (uint64_t)mpp->no_path_retry * conf->checkint; + ++ /* pad no_path_retry_tmo by one standard check interval ++ * plus one second per minute to account for timing ++ * issues with the rechecks */ ++ no_path_retry_tmo += no_path_retry_tmo / 60 + DEFAULT_CHECKINT; ++ + if (no_path_retry_tmo > MAX_DEV_LOSS_TMO) + min_dev_loss = MAX_DEV_LOSS_TMO; + else diff --git a/0037-libmultipath-fix-deferred_remove-function-arguments.patch b/0037-libmultipath-fix-deferred_remove-function-arguments.patch new file mode 100644 index 0000000..507a056 --- /dev/null +++ b/0037-libmultipath-fix-deferred_remove-function-arguments.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Apr 2024 19:35:17 -0400 +Subject: [PATCH] libmultipath: fix deferred_remove function arguments + +Aside from one version of dm_flush_map_nopaths(), all the callers of +_dm_flush_map() and dm_simplecmd() set deferred_remove to 0. But these +functions, as well as some helper functions they called, all treated the +deferred_remove argument as an enum deferred_remove_states, and called +do_deferred() to see if the remove should be deferred. To simplify the +code, make these functions treat deferred_remove as a boolean value +signifying whether a remove is deferred, and make dm_flush_map_nopaths() +do the work of checking if the remove should be deferred. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 19 +++++++++---------- + libmultipath/libmultipath.version | 2 +- + 2 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index a87abf7e..2e7b2c64 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -386,8 +386,6 @@ libmp_dm_task_create(int task) + return dm_task_create(task); + } + +-#define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS) +- + static int + dm_simplecmd (int task, const char *name, int no_flush, int need_sync, + uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { +@@ -411,7 +409,7 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, + dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ + #endif + #ifdef LIBDM_API_DEFERRED +- if (do_deferred(deferred_remove)) ++ if (deferred_remove) + dm_task_deferred_remove(dmt); + #endif + if (udev_wait_flag && +@@ -1082,7 +1080,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + + /* If you aren't doing a deferred remove, make sure that no + * devices are in use */ +- if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL)) ++ if (!deferred_remove && partmap_in_use(mapname, NULL)) + return DM_FLUSH_BUSY; + + if (need_suspend && +@@ -1100,7 +1098,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) + return r; + +- if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) { ++ if (!deferred_remove && dm_get_opencount(mapname)) { + condlog(2, "%s: map in use", mapname); + return DM_FLUSH_BUSY; + } +@@ -1112,8 +1110,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + r = dm_device_remove(mapname, need_sync, deferred_remove); + + if (r) { +- if (do_deferred(deferred_remove) +- && dm_map_present(mapname)) { ++ if (deferred_remove && dm_map_present(mapname)) { + condlog(4, "multipath map %s remove deferred", + mapname); + return DM_FLUSH_DEFERRED; +@@ -1147,7 +1144,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + int + dm_flush_map_nopaths(const char * mapname, int deferred_remove) + { +- return _dm_flush_map(mapname, 1, deferred_remove, 0, 0); ++ return _dm_flush_map(mapname, 1, ++ (deferred_remove == DEFERRED_REMOVE_ON || ++ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), ++ 0, 0); + } + + #else +@@ -1539,8 +1539,7 @@ remove_partmap(const char *name, void *data) + + if (dm_get_opencount(name)) { + dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); +- if (!do_deferred(rd->deferred_remove) && +- dm_get_opencount(name)) { ++ if (rd->deferred_remove && dm_get_opencount(name)) { + condlog(2, "%s: map in use", name); + return DM_FLUSH_BUSY; + } +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index e070f296..eb511749 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { + put_multipath_config; + }; + +-LIBMULTIPATH_23.0.0 { ++LIBMULTIPATH_24.0.0 { + global: + /* symbols referenced by multipath and multipathd */ + add_foreign; diff --git a/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch b/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch new file mode 100644 index 0000000..ef922ec --- /dev/null +++ b/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch @@ -0,0 +1,212 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 May 2024 18:38:24 +0200 +Subject: [PATCH] libmultipath: use bitwise flags for map flushing API + +Rather than passing 3 separate bool variables to _dm_flush_map(), +define bitwise flags to modify the function's behavior, and pass +these flags to called functions accordingly. + +This improves the readability of the code, function calls are +more expressive. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 68 +++++++++++++++++----------------------- + libmultipath/devmapper.h | 18 ++++++++--- + 2 files changed, 41 insertions(+), 45 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 2e7b2c64..a6a9c2b7 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -53,9 +53,8 @@ static int dm_cancel_remove_partmaps(const char * mapname); + #define __DR_UNUSED__ __attribute__((unused)) + #endif + +-static int dm_remove_partmaps (const char * mapname, int need_sync, +- int deferred_remove); +-static int do_foreach_partmaps(const char * mapname, ++static int dm_remove_partmaps (const char *mapname, int flags); ++static int do_foreach_partmaps(const char *mapname, + int (*partmap_func)(const char *, void *), + void *data); + static int _dm_queue_if_no_path(const char *mapname, int enable); +@@ -439,9 +438,9 @@ int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) + } + + static int +-dm_device_remove (const char *name, int needsync, int deferred_remove) { +- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0, +- deferred_remove); ++dm_device_remove (const char *name, int flags) { ++ return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, ++ flags & DMFL_DEFERRED); + } + + static int +@@ -1061,8 +1060,7 @@ partmap_in_use(const char *name, void *data) + return 0; + } + +-int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, +- int need_suspend, int retries) ++int _dm_flush_map (const char *mapname, int flags, int retries) + { + int r; + int queue_if_no_path = 0; +@@ -1080,10 +1078,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + + /* If you aren't doing a deferred remove, make sure that no + * devices are in use */ +- if (!deferred_remove && partmap_in_use(mapname, NULL)) ++ if (!(flags & DMFL_DEFERRED) && partmap_in_use(mapname, NULL)) + return DM_FLUSH_BUSY; + +- if (need_suspend && ++ if ((flags & DMFL_SUSPEND) && + dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK && + strstr(params, "queue_if_no_path")) { + if (!_dm_queue_if_no_path(mapname, 0)) +@@ -1095,22 +1093,22 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + free(params); + params = NULL; + +- if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) ++ if ((r = dm_remove_partmaps(mapname, flags))) + return r; + +- if (!deferred_remove && dm_get_opencount(mapname)) { ++ if (!(flags & DMFL_DEFERRED) && dm_get_opencount(mapname)) { + condlog(2, "%s: map in use", mapname); + return DM_FLUSH_BUSY; + } + + do { +- if (need_suspend && queue_if_no_path != -1) ++ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) + dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0); + +- r = dm_device_remove(mapname, need_sync, deferred_remove); ++ r = dm_device_remove(mapname, flags); + + if (r) { +- if (deferred_remove && dm_map_present(mapname)) { ++ if ((flags & DMFL_DEFERRED) && dm_map_present(mapname)) { + condlog(4, "multipath map %s remove deferred", + mapname); + return DM_FLUSH_DEFERRED; +@@ -1124,7 +1122,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + } else { + condlog(2, "failed to remove multipath map %s", + mapname); +- if (need_suspend && queue_if_no_path != -1) { ++ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) { + dm_simplecmd_noflush(DM_DEVICE_RESUME, + mapname, udev_flags); + } +@@ -1139,27 +1137,18 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + return DM_FLUSH_FAIL; + } + +-#ifdef LIBDM_API_DEFERRED +- + int +-dm_flush_map_nopaths(const char * mapname, int deferred_remove) ++dm_flush_map_nopaths(const char *mapname, int deferred_remove __DR_UNUSED__) + { +- return _dm_flush_map(mapname, 1, +- (deferred_remove == DEFERRED_REMOVE_ON || +- deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), +- 0, 0); +-} +- +-#else +- +-int +-dm_flush_map_nopaths(const char * mapname, +- int deferred_remove __attribute__((unused))) +-{ +- return _dm_flush_map(mapname, 1, 0, 0, 0); +-} ++ int flags = DMFL_NEED_SYNC; + ++#ifdef LIBDM_API_DEFERRED ++ flags |= ((deferred_remove == DEFERRED_REMOVE_ON || ++ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) ? ++ DMFL_DEFERRED : 0); + #endif ++ return _dm_flush_map(mapname, flags, 0); ++} + + int dm_flush_maps (int retries) + { +@@ -1528,8 +1517,7 @@ out: + } + + struct remove_data { +- int need_sync; +- int deferred_remove; ++ int flags; + }; + + static int +@@ -1538,21 +1526,21 @@ remove_partmap(const char *name, void *data) + struct remove_data *rd = (struct remove_data *)data; + + if (dm_get_opencount(name)) { +- dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); +- if (rd->deferred_remove && dm_get_opencount(name)) { ++ dm_remove_partmaps(name, rd->flags); ++ if ((rd->flags & DMFL_DEFERRED) && dm_get_opencount(name)) { + condlog(2, "%s: map in use", name); + return DM_FLUSH_BUSY; + } + } + condlog(4, "partition map %s removed", name); +- dm_device_remove(name, rd->need_sync, rd->deferred_remove); ++ dm_device_remove(name, rd->flags); + return DM_FLUSH_OK; + } + + static int +-dm_remove_partmaps (const char * mapname, int need_sync, int deferred_remove) ++dm_remove_partmaps (const char * mapname, int flags) + { +- struct remove_data rd = { need_sync, deferred_remove }; ++ struct remove_data rd = { flags }; + return do_foreach_partmaps(mapname, remove_partmap, &rd); + } + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index 93caa2aa..bb4a55a6 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -58,12 +58,20 @@ enum { + }; + + int partmap_in_use(const char *name, void *data); +-int _dm_flush_map (const char *, int, int, int, int); +-int dm_flush_map_nopaths(const char * mapname, int deferred_remove); +-#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) +-#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0, 0, 0, 0) ++ ++enum { ++ DMFL_NONE = 0, ++ DMFL_NEED_SYNC = 1 << 0, ++ DMFL_DEFERRED = 1 << 1, ++ DMFL_SUSPEND = 1 << 2, ++}; ++ ++int _dm_flush_map (const char *mapname, int flags, int retries); ++#define dm_flush_map(mapname) _dm_flush_map(mapname, DMFL_NEED_SYNC, 0) ++#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, DMFL_NONE, 0) + #define dm_suspend_and_flush_map(mapname, retries) \ +- _dm_flush_map(mapname, 1, 0, 1, retries) ++ _dm_flush_map(mapname, DMFL_NEED_SYNC|DMFL_SUSPEND, retries) ++int dm_flush_map_nopaths(const char * mapname, int deferred_remove); + int dm_cancel_deferred_remove(struct multipath *mpp); + int dm_flush_maps (int retries); + int dm_fail_path(const char * mapname, char * path); diff --git a/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch b/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch new file mode 100644 index 0000000..1aee878 --- /dev/null +++ b/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch @@ -0,0 +1,117 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 May 2024 18:45:17 +0200 +Subject: [PATCH] libmultipath: use bitwise flags for dm_simplecmd API + +Also use bitwise flags for dm_simplecmd() and its relatives. Again, +this makes the code more expressive and more readable, while +simplifying the function calls. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 26 +++++++++++++------------- + libmultipath/devmapper.h | 5 +++-- + 2 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index a6a9c2b7..08bb3c51 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -386,10 +386,9 @@ libmp_dm_task_create(int task) + } + + static int +-dm_simplecmd (int task, const char *name, int no_flush, int need_sync, +- uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { ++dm_simplecmd (int task, const char *name, int flags, uint16_t udev_flags) { + int r = 0; +- int udev_wait_flag = ((need_sync || udev_flags) && ++ int udev_wait_flag = (((flags & DMFL_NEED_SYNC) || udev_flags) && + (task == DM_DEVICE_RESUME || + task == DM_DEVICE_REMOVE)); + uint32_t cookie = 0; +@@ -404,11 +403,11 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, + dm_task_no_open_count(dmt); + dm_task_skip_lockfs(dmt); /* for DM_DEVICE_RESUME */ + #ifdef LIBDM_API_FLUSH +- if (no_flush) ++ if (flags & DMFL_NO_FLUSH) + dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ + #endif + #ifdef LIBDM_API_DEFERRED +- if (deferred_remove) ++ if (flags & DMFL_DEFERRED) + dm_task_deferred_remove(dmt); + #endif + if (udev_wait_flag && +@@ -429,18 +428,17 @@ out: + + int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags) + { +- return dm_simplecmd(task, name, 0, 1, udev_flags, 0); ++ return dm_simplecmd(task, name, DMFL_NEED_SYNC, udev_flags); + } + + int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) + { +- return dm_simplecmd(task, name, 1, 1, udev_flags, 0); ++ return dm_simplecmd(task, name, DMFL_NO_FLUSH|DMFL_NEED_SYNC, udev_flags); + } + + static int + dm_device_remove (const char *name, int flags) { +- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, +- flags & DMFL_DEFERRED); ++ return dm_simplecmd(DM_DEVICE_REMOVE, name, flags, 0); + } + + static int +@@ -594,8 +592,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) + params, ADDMAP_RO, 0); + } + if (r) +- r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, +- 1, udev_flags, 0); ++ r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, ++ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), ++ udev_flags); + if (r) + return r; + +@@ -603,8 +602,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) + * drop the new table, so doing a second resume will try using + * the original table */ + if (dm_is_suspended(mpp->alias)) +- dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, 1, +- udev_flags, 0); ++ dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, ++ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), ++ udev_flags); + return 0; + } + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index bb4a55a6..a242381e 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -38,8 +38,8 @@ void skip_libmp_dm_init(void); + void libmp_dm_exit(void); + void libmp_udev_set_sync_support(int on); + struct dm_task *libmp_dm_task_create(int task); +-int dm_simplecmd_flush (int, const char *, uint16_t); +-int dm_simplecmd_noflush (int, const char *, uint16_t); ++int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); ++int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); + int dm_addmap_create (struct multipath *mpp, char *params); + int dm_addmap_reload (struct multipath *mpp, char *params, int flush); + int dm_map_present (const char *); +@@ -64,6 +64,7 @@ enum { + DMFL_NEED_SYNC = 1 << 0, + DMFL_DEFERRED = 1 << 1, + DMFL_SUSPEND = 1 << 2, ++ DMFL_NO_FLUSH = 1 << 3, + }; + + int _dm_flush_map (const char *mapname, int flags, int retries); diff --git a/0040-libmultipath-add-argument-names-to-some-prototypes.patch b/0040-libmultipath-add-argument-names-to-some-prototypes.patch new file mode 100644 index 0000000..3244d55 --- /dev/null +++ b/0040-libmultipath-add-argument-names-to-some-prototypes.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 2 May 2024 18:46:42 +0200 +Subject: [PATCH] libmultipath: add argument names to some prototypes + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.h | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h +index a242381e..19b79c5b 100644 +--- a/libmultipath/devmapper.h ++++ b/libmultipath/devmapper.h +@@ -42,12 +42,12 @@ int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); + int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); + int dm_addmap_create (struct multipath *mpp, char *params); + int dm_addmap_reload (struct multipath *mpp, char *params, int flush); +-int dm_map_present (const char *); ++int dm_map_present (const char *name); + int dm_map_present_by_uuid(const char *uuid); +-int dm_get_map(const char *, unsigned long long *, char **); +-int dm_get_status(const char *, char **); +-int dm_type(const char *, char *); +-int dm_is_mpath(const char *); ++int dm_get_map(const char *name, unsigned long long *size, char **outparams); ++int dm_get_status(const char *name, char **outstatus); ++int dm_type(const char *name, char *type); ++int dm_is_mpath(const char *name); + + enum { + DM_FLUSH_OK = 0, diff --git a/0041-libmultipath-bump-version-to-0.9.9.patch b/0041-libmultipath-bump-version-to-0.9.9.patch new file mode 100644 index 0000000..890b047 --- /dev/null +++ b/0041-libmultipath-bump-version-to-0.9.9.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 22:09:10 +0200 +Subject: [PATCH] libmultipath: bump version to 0.9.9 + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/version.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/version.h b/libmultipath/version.h +index e102975f..271d8e74 100644 +--- a/libmultipath/version.h ++++ b/libmultipath/version.h +@@ -20,9 +20,9 @@ + #ifndef _VERSION_H + #define _VERSION_H + +-#define VERSION_CODE 0x000908 ++#define VERSION_CODE 0x000909 + /* MMDDYY, in hex */ +-#define DATE_CODE 0x020F18 ++#define DATE_CODE 0x050318 + + #define PROG "multipath-tools" + diff --git a/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch b/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch new file mode 100644 index 0000000..47c3949 --- /dev/null +++ b/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 22:28:34 +0200 +Subject: [PATCH] GitHub Workflows: native.yaml: run for Fedora 40 + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 0ef9df94..a062845e 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -33,7 +33,7 @@ jobs: + - debian-buster + - debian-bullseye + - debian-bookworm +- - fedora-39 ++ - fedora-40 + - opensuse-leap + container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + steps: diff --git a/0043-update-NEWS.md.patch b/0043-update-NEWS.md.patch new file mode 100644 index 0000000..4edc69d --- /dev/null +++ b/0043-update-NEWS.md.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 23:11:48 +0200 +Subject: [PATCH] update NEWS.md + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 3 ++ + .github/actions/spelling/patterns.txt | 3 +- + NEWS.md | 62 +++++++++++++++++++++++++++ + 3 files changed, 67 insertions(+), 1 deletion(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index fc9f22f8..bdfce83a 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -17,6 +17,7 @@ blkid + bmarzins + cciss + CFLAGS ++cgroups + christophe + clangd + clariion +@@ -67,6 +68,7 @@ fulldescr + gcc + getprkey + getprstatus ++getrlimit + getuid + github + GPT +@@ -170,6 +172,7 @@ rootprefixdir + rpmbuild + rport + rtpi ++rtprio + sas + sbp + scsi +diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt +index 858faee6..aa361654 100644 +--- a/.github/actions/spelling/patterns.txt ++++ b/.github/actions/spelling/patterns.txt +@@ -22,7 +22,7 @@ + \bdmmp_pgs\b + \bdmmp_mpath_kdev_name_get\b + \bfast_io_fail_tmo\b +-\bLimitRTPRIO\b ++\bLimitRTPRIO=?\b + \bmax_fds\b + \bmissing_uev_wait_timeout\b + \bMPATH_MAX_PARAM_LEN\b +@@ -87,6 +87,7 @@ + \bprin_resvdescr\b + \bprout_param_descriptor\b + \brq_servact\b ++\bRLIMIT_RTPRIO\b + \bSCHED_RT_PRIO\b + \bssize_t\b + \btrnptid_list\b +diff --git a/NEWS.md b/NEWS.md +index 0b094b98..4c54afa0 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -1,5 +1,67 @@ + # multipath-tools Release Notes + ++## multipath-tools 0.9.9, 2024/05 ++ ++### User-Visible Changes ++ ++* *Changed realtime scheduling:* multipathd used to run at the highest possible ++ realtime priority, 99. This has always been excessive, and on some ++ distributions (e.g. RHEL 8), it hasn't worked at all. It is now possible to ++ set multipathd's real time scheduling by setting the hard limit for ++ `RLIMIT_RTPRIO` (see getrlimit(2)), which corresponds to the `rtprio` ++ setting in limits.conf and to `LimitRTPRIO=` in the systemd unit file. The ++ default in the systemd unit file has been set to 10. If the limit is set to ++ 0, multipathd doesn't attempt to enable real-time scheduling. ++ Otherwise, it will try to set the scheduling priority to the given value. ++ Fixes [#82](https://github.com/opensvc/multipath-tools/issues/82). ++* *Changed normal scheduling:* In order to make sure that multipathd has ++ sufficient priority even if real time scheduling is switched off, the ++ `CPUWeight=` setting in the unit file is set to 1000. This is necessary ++ because regular nice(2) values have no effect in systems with cgroups enabled. ++* *Changed handling of `max_sectors_kb` configuration:* multipathd applies ++ the `max_sectors_kb` setting only during map creation, or when a new path is ++ added to an existing map. The kernel makes sure that the multipath device ++ never has a larger `max_sectors_kb` value than any of its configured path ++ devices. The reason for this change is that applying `max_sectors_kb` on ++ live maps can cause IO errors and data loss in rare situations. ++ It can now happen that some path devices have a higher `max_sectors_kb` ++ value than the map; this is not an error. It is not possible any more to ++ decrease `max_sectors_kb` in `multipath.conf` and run `multipathd ++ reconfigure` to "apply" this setting to the map and its paths. If decreasing ++ the IO size is necessary, either destroy and recreate the map, or remove one ++ path with `multipathd del path $PATH`, run `multipathd reconfigure`, and ++ re-add the path with `multipathd add path $PATH`. ++* *New wildcard %k:* The wildcard `%k` for `max_sectors_kb` has been added to ++ the `multipathd show paths format` and `multipathd show maps format` ++ commands. ++* *Changed semantics of flush_on_last_del:* The `flush_on_last_del` option ++ now takes the values `always` , `unused`, or `never`. `yes` and `no` ++ are still accepted as aliases for `always` and `unused`, respectively. ++ `always` means that when all paths for a multipath map have been removed, ++ *outstanding IO will be failed* and the map will be deleted. `unused` means ++ that this will only happen when the map is not mounted or otherwise opened. ++ `never` means the map will only be removed if the `queue_if_no_path` ++ feature is off. ++ This fixes a problem where multipathd could hang when the last path of ++ a queueing map was deleted. ++ ++### Other major changes ++ ++* Adapted the dm-mpath udev rules such that they will work with the modified ++ device mapper udev rules (`DM_UDEV_RULES_VSN==3`, lvm2 > 2.03.22). They are ++ still compatible with older versions of the device-mapper udev rules. ++ ++### Bug fixes ++ ++* Fixed misspelled DM_UDEV_DISABLE_OTHER_RULES_FLAG in 11-dm-mpath.rules ++* Always use `glibc_basename()` to avoid some issues with MUSL libc. ++ Fixes [#84](https://github.com/opensvc/multipath-tools/pull/84). ++ ++### Other ++ ++* Build: added `TGTDIR` option to simplify building for a different target ++ host (see README.md). ++ + ## multipath-tools 0.9.8, 2024/02 + + ### User-Visible Changes diff --git a/0044-multipath.conf.5.in-fix-man-page-date.patch b/0044-multipath.conf.5.in-fix-man-page-date.patch new file mode 100644 index 0000000..c9f2d5d --- /dev/null +++ b/0044-multipath.conf.5.in-fix-man-page-date.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 3 May 2024 23:22:50 +0200 +Subject: [PATCH] multipath.conf.5.in: fix man page date + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 1d3d53bb..dacb9b0e 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -6,7 +6,7 @@ + .\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH.CONF 5 2024-04-17 Linux ++.TH MULTIPATH.CONF 5 2024-04-25 Linux + . + . + .\" ---------------------------------------------------------------------------- diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0045-RH-fixup-udev-rules-for-redhat.patch similarity index 86% rename from 0001-RH-fixup-udev-rules-for-redhat.patch rename to 0045-RH-fixup-udev-rules-for-redhat.patch index 02efadd..d78919e 100644 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ b/0045-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 6b454303..0b0e3ad2 100644 +index 81b86cd8..33dbb99c 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif @@ -26,9 +26,9 @@ index 6b454303..0b0e3ad2 100644 +exec_prefix := $(prefix)/usr # Prefix for non-essential libraries (libdmmp) usr_prefix := $(if $(prefix),$(prefix),/usr) - # Prefix for configfuration files (multipath.conf) + # Prefix for configuration files (multipath.conf) diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 1969dee0..d2b28233 100644 +index 8dd3369c..7c3c7524 100644 --- a/kpartx/kpartx.rules +++ b/kpartx/kpartx.rules @@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" @@ -40,20 +40,20 @@ index 1969dee0..d2b28233 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 0efb9b26..504d6892 100644 +index 67fb5e62..2ea9e528 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -26,7 +26,7 @@ install: - $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ +@@ -27,7 +27,7 @@ install: $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules + $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 -@@ -48,7 +48,7 @@ uninstall: - $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules +@@ -50,7 +50,7 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf - $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0046-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 96% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0046-RH-Remove-the-property-blacklist-exception-builtin.patch index bc259d4..b039539 100644 --- a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0046-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -42,10 +42,10 @@ index 75100b20..0b212078 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 683bdb72..87b3b2a5 100644 +index dacb9b0e..645e8f88 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1431,9 +1431,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1468,9 +1468,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index 683bdb72..87b3b2a5 100644 . .RS .PP -@@ -1444,10 +1449,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1481,10 +1486,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0047-RH-don-t-start-without-a-config-file.patch similarity index 92% rename from 0003-RH-don-t-start-without-a-config-file.patch rename to 0047-RH-don-t-start-without-a-config-file.patch index fa304dc..ad7962a 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0047-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index b7dbc6f5..3a374b3d 100644 +index 83fa7369..002027a7 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -958,6 +958,19 @@ int _init_config (const char *file, struct config *conf) +@@ -959,6 +959,19 @@ int _init_config (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -58,12 +58,12 @@ index 384193ab..158cebf0 100644 enum devtypes { DEV_NONE, diff --git a/multipath/main.c b/multipath/main.c -index 9e1c5052..46944589 100644 +index ce702e7f..c21e3e0b 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -829,11 +829,14 @@ main (int argc, char *argv[]) +@@ -842,11 +842,14 @@ main (int argc, char *argv[]) + char *dev = NULL; struct config *conf; - int retries = -1; bool enable_foreign = false; + bool have_config; + struct stat buf; @@ -76,7 +76,7 @@ index 9e1c5052..46944589 100644 if (init_config(DEFAULT_CONFIGFILE)) exit(RTVL_FAIL); if (atexit(uninit_config)) -@@ -1081,6 +1084,9 @@ main (int argc, char *argv[]) +@@ -1097,6 +1100,9 @@ main (int argc, char *argv[]) while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) condlog(3, "restart multipath configuration process"); @@ -87,7 +87,7 @@ index 9e1c5052..46944589 100644 put_multipath_config(conf); if (dev) diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in -index 6f123760..70b69a06 100644 +index 780bf852..2c518378 100644 --- a/multipath/multipath.rules.in +++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" @@ -99,7 +99,7 @@ index 6f123760..70b69a06 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index e98c27fd..fd2061e5 100644 +index 12b77156..499557a0 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. @@ -112,7 +112,7 @@ index e98c27fd..fd2061e5 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 6d03ff71..0965d6f9 100644 +index a63ddd9a..01ceff7d 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ @@ -124,7 +124,7 @@ index 6d03ff71..0965d6f9 100644 Conflicts=shutdown.target Conflicts=initrd-cleanup.service diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket -index c777e5e3..3c20a2ff 100644 +index 6a62f5fd..263b6b0c 100644 --- a/multipathd/multipathd.socket +++ b/multipathd/multipathd.socket @@ -1,6 +1,7 @@ diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0048-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0048-RH-Fix-nvme-function-missing-argument.patch diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0049-RH-use-rpm-optflags-if-present.patch similarity index 87% rename from 0005-RH-use-rpm-optflags-if-present.patch rename to 0049-RH-use-rpm-optflags-if-present.patch index 6352c23..0f354e7 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0049-RH-use-rpm-optflags-if-present.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 0b0e3ad2..3d80d224 100644 +index 33dbb99c..94e0ec85 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -95,11 +95,23 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo @@ -41,10 +41,10 @@ index 0b0e3ad2..3d80d224 100644 -CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes +CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -@@ -108,7 +120,7 @@ CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + -D_FILE_OFFSET_BITS=64 \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ +@@ -109,7 +121,7 @@ CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0006-RH-add-mpathconf.patch b/0050-RH-add-mpathconf.patch similarity index 98% rename from 0006-RH-add-mpathconf.patch rename to 0050-RH-add-mpathconf.patch index fd47a6c..fd65e34 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0050-RH-add-mpathconf.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 3a374b3d..4544f484 100644 +index 002027a7..3d5943d3 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -960,6 +960,8 @@ int _init_config (const char *file, struct config *conf) +@@ -961,6 +961,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -35,7 +35,7 @@ index 3a374b3d..4544f484 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index 504d6892..9f14036c 100644 +index 2ea9e528..3dc241cc 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so @@ -45,8 +45,8 @@ index 504d6892..9f14036c 100644 + $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -31,6 +32,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) +@@ -32,6 +33,7 @@ install: $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 @@ -54,12 +54,13 @@ index 504d6892..9f14036c 100644 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) -@@ -45,11 +47,13 @@ endif +@@ -46,12 +48,14 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 96% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index a3c4e9d..9884258 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 46944589..47f89a0a 100644 +index c21e3e0b..3f3ac9fb 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -92,7 +92,7 @@ index 46944589..47f89a0a 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -848,7 +894,7 @@ main (int argc, char *argv[]) +@@ -861,7 +907,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); if (atexit(cleanup_bindings)) condlog(1, "failed to register cleanup handler for bindings: %m"); @@ -101,7 +101,7 @@ index 46944589..47f89a0a 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -919,6 +965,10 @@ main (int argc, char *argv[]) +@@ -932,6 +978,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -113,7 +113,7 @@ index 46944589..47f89a0a 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in -index 348eb220..82a7e68e 100644 +index b88e9a4c..edd742aa 100644 --- a/multipath/multipath.8.in +++ b/multipath/multipath.8.in @@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig. @@ -138,7 +138,7 @@ index 348eb220..82a7e68e 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 0965d6f9..c964eb1b 100644 +index 01ceff7d..e0c2011b 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -17,6 +17,7 @@ ConditionVirtualization=!container diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0052-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 91% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0052-RH-reset-default-find_mutipaths-value-to-off.patch index cf7317e..04ad52c 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0052-RH-reset-default-find_mutipaths-value-to-off.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 64b633f2..5bda9f93 100644 +index ed08c251..4b033ff9 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -23,7 +23,7 @@ @@ -27,10 +27,10 @@ index 64b633f2..5bda9f93 100644 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 87b3b2a5..8e246571 100644 +index 645e8f88..a7543939 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1213,7 +1213,7 @@ as non-multipath and passed on to upper layers. +@@ -1225,7 +1225,7 @@ as non-multipath and passed on to upper layers. \fBNote:\fR this may cause delays during device detection if there are single-path devices which aren\'t blacklisted. .TP diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 84% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index aa49d69..c090da0 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 6fd4dabb..19692b1e 100644 +index e2052422..3bcd94ce 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1216,13 +1216,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 6fd4dabb..19692b1e 100644 good_len = 8; break; default: -@@ -1240,10 +1236,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1245,10 +1241,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ @@ -45,10 +45,10 @@ index 6fd4dabb..19692b1e 100644 case 0x1: /* T-10 Vendor ID: Prio 2 */ diff --git a/tests/vpd.c b/tests/vpd.c -index 1b2d62d6..7309b5c5 100644 +index e3212e61..cdb111bb 100644 --- a/tests/vpd.c +++ b/tests/vpd.c -@@ -231,11 +231,13 @@ static const char * const str_prefix[] = { +@@ -232,11 +232,13 @@ static const char * const str_prefix[] = { [STR_IQN] = "iqn.", }; @@ -62,7 +62,7 @@ index 1b2d62d6..7309b5c5 100644 /** * create_scsi_string_desc() - create a SCSI name string descriptor. -@@ -766,6 +768,7 @@ make_test_vpd_naa(2, 18); +@@ -767,6 +769,7 @@ make_test_vpd_naa(2, 18); make_test_vpd_naa(2, 17); make_test_vpd_naa(2, 16); @@ -70,7 +70,7 @@ index 1b2d62d6..7309b5c5 100644 /* SCSI Name string: EUI64, WWID size: 17 */ make_test_vpd_str(0, 20, 18) make_test_vpd_str(0, 20, 17) -@@ -801,6 +804,7 @@ make_test_vpd_str(18, 20, 18) +@@ -802,6 +805,7 @@ make_test_vpd_str(18, 20, 18) make_test_vpd_str(18, 20, 17) make_test_vpd_str(18, 20, 16) make_test_vpd_str(18, 20, 15) @@ -78,7 +78,7 @@ index 1b2d62d6..7309b5c5 100644 static int test_vpd(void) { -@@ -909,6 +913,7 @@ static int test_vpd(void) +@@ -910,6 +914,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_naa_2_18), cmocka_unit_test(test_vpd_naa_2_17), cmocka_unit_test(test_vpd_naa_2_16), @@ -86,7 +86,7 @@ index 1b2d62d6..7309b5c5 100644 cmocka_unit_test(test_vpd_str_0_20_18), cmocka_unit_test(test_vpd_str_0_20_17), cmocka_unit_test(test_vpd_str_0_20_16), -@@ -933,6 +938,7 @@ static int test_vpd(void) +@@ -934,6 +939,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_str_18_20_17), cmocka_unit_test(test_vpd_str_18_20_16), cmocka_unit_test(test_vpd_str_18_20_15), diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0055-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch index 0059895..7624c5b 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0055-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 3d80d224..15e3bd3a 100644 +index 94e0ec85..49514b06 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0056-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0012-RH-compile-with-libreadline-support.patch rename to 0056-RH-compile-with-libreadline-support.patch index b0c8749..eb0ab13 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0056-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 15e3bd3a..64384a72 100644 +index 49514b06..a3ed9f28 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0013-RH-Add-mpathcleanup.patch b/0057-RH-Add-mpathcleanup.patch similarity index 96% rename from 0013-RH-Add-mpathcleanup.patch rename to 0057-RH-Add-mpathcleanup.patch index c15fb6d..bd2dcd6 100644 --- a/0013-RH-Add-mpathcleanup.patch +++ b/0057-RH-Add-mpathcleanup.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski create mode 100755 multipath/mpathcleanup diff --git a/multipath/Makefile b/multipath/Makefile -index 9f14036c..99ad81b0 100644 +index 3dc241cc..47e82234 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -25,6 +25,7 @@ install: @@ -24,15 +24,15 @@ index 9f14036c..99ad81b0 100644 + $(Q)$(INSTALL_PROGRAM) -m 755 mpathcleanup $(DESTDIR)$(bindir)/ $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules -@@ -48,6 +49,7 @@ endif + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) +@@ -49,6 +50,7 @@ endif uninstall: $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathcleanup $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf - $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf diff --git a/multipath/mpathcleanup b/multipath/mpathcleanup new file mode 100755 index 00000000..6fd921e4 diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 78bef5a..22e6ad7 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,30 +1,72 @@ Name: device-mapper-multipath -Version: 0.9.7 -Release: 7%{?dist} +Version: 0.9.8 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.7.tar.gz -o multipath-tools-0.9.7.tgz -Source0: multipath-tools-0.9.7.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.8.tar.gz -o multipath-tools-0.9.8.tgz +Source0: multipath-tools-0.9.8.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0012: 0012-RH-compile-with-libreadline-support.patch -Patch0013: 0013-RH-Add-mpathcleanup.patch -Patch0014: 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch -Patch0015: 0015-multipathd-fix-auto-resize-configuration.patch +Patch0001: 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch +Patch0002: 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch +Patch0003: 0003-multipathd-make-multipathd-scheduling-configurable.patch +Patch0004: 0004-libmpathutil-really-always-use-glibc-basename.patch +Patch0005: 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch +Patch0006: 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch +Patch0007: 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch +Patch0008: 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch +Patch0009: 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch +Patch0010: 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch +Patch0011: 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch +Patch0012: 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch +Patch0013: 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch +Patch0014: 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch +Patch0015: 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch +Patch0016: 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch +Patch0017: 0017-kpartx.rules-ignore-DM_SUSPENDED.patch +Patch0018: 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch +Patch0019: 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch +Patch0020: 0020-GitHub-actions-fixes-for-spelling-CI.patch +Patch0021: 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch +Patch0022: 0022-multipath-tools-add-TGTDIR-option.patch +Patch0023: 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch +Patch0024: 0024-libmultipath-add-mp_find_path_by_devt.patch +Patch0025: 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch +Patch0026: 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch +Patch0027: 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch +Patch0028: 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch +Patch0029: 0029-multipath.conf-5-update-documentation-for-max_sector.patch +Patch0030: 0030-multipath-tools-simplify-comment-in-hwtable.patch +Patch0031: 0031-multipath-tools-unify-text-in-multipath.conf.5.patch +Patch0032: 0032-multipath-tools-update-man-pages-dates.patch +Patch0033: 0033-libmultipath-export-partmap_in_use.patch +Patch0034: 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch +Patch0035: 0035-libmultipath-remove-redundant-config-option-from-Inf.patch +Patch0036: 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch +Patch0037: 0037-libmultipath-fix-deferred_remove-function-arguments.patch +Patch0038: 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch +Patch0039: 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch +Patch0040: 0040-libmultipath-add-argument-names-to-some-prototypes.patch +Patch0041: 0041-libmultipath-bump-version-to-0.9.9.patch +Patch0042: 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch +Patch0043: 0043-update-NEWS.md.patch +Patch0044: 0044-multipath.conf.5.in-fix-man-page-date.patch +Patch0045: 0045-RH-fixup-udev-rules-for-redhat.patch +Patch0046: 0046-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0047: 0047-RH-don-t-start-without-a-config-file.patch +Patch0048: 0048-RH-Fix-nvme-function-missing-argument.patch +Patch0049: 0049-RH-use-rpm-optflags-if-present.patch +Patch0050: 0050-RH-add-mpathconf.patch +Patch0051: 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0052: 0052-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0053: 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0054: 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0055: 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0056: 0056-RH-compile-with-libreadline-support.patch +Patch0057: 0057-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -111,7 +153,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.7 -p1 +%autosetup -n multipath-tools-0.9.8 -p1 cp %{SOURCE1} . %build @@ -172,6 +214,7 @@ fi %{_mandir}/man8/mpathpersist.8* %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules +%config /usr/lib/udev/rules.d/99-z-dm-mpath-late.rules %dir %{_modulesloaddir} %{_modulesloaddir}/scsi_dh.conf %{_tmpfilesdir}/multipath.conf @@ -232,6 +275,14 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon May 20 2024 Benjamin Marzinski - 0.9.8-1 +- Update source to upstream version 0.9.8 plus latest staging branch + * Previous patches 0014 & 0015 are included in the source tarball + * patches 0001-0044 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0001-0013 are now patches 0045-0057 +- Install /lib/udev/rules.d/99-z-dm-mpath-late.rules + * Wed Jan 24 2024 Fedora Release Engineering - 0.9.7-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild diff --git a/sources b/sources index 89f8f37..b0337e2 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.7.tgz) = 0f4c97179a3de5a0c77893fec229eb183293fed8e5e01a9945b261845ccf5d13f8ef2c2ff0c17c9345217d236275caed4765422ec95aed80821f11658bf96e26 +SHA512 (multipath-tools-0.9.8.tgz) = 4d73bcf6bce769a829c306c609b206ddba65a708620f458106e406dd18d12f9a9d97f400662daa8e6a75c9fdf7decb6dcbda92cb807b6c53522c7b4b2795b627 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 59945a7f7ef24b659a0e3895f78f84a15384454a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Jun 2024 14:29:22 -0400 Subject: [PATCH 17/33] device-mapper-multipath-0.9.9-1 Update source to upstream version 0.9.9 * Previous patches 0001-0044 are included in the source tarball Rename redhat patches * Previous patches 0045-0057 are now patches 0001-0013 --- .gitignore | 1 + ...s-fix-misspelled-DM_UDEV_DISABLE_OTH.patch | 27 -- ... 0001-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...ondlog-level-for-setscheduler-error-.patch | 27 -- ...RH-don-t-start-without-a-config-file.patch | 2 +- ...e-multipathd-scheduling-configurable.patch | 87 ----- ...H-Fix-nvme-function-missing-argument.patch | 0 ...til-really-always-use-glibc-basename.patch | 144 -------- ... 0005-RH-use-rpm-optflags-if-present.patch | 0 ...multipathd-set-priority-to-RLIMIT_RT.patch | 134 ------- ...hconf.patch => 0006-RH-add-mpathconf.patch | 0 ...PUWeight-to-1000-and-LimitRTPRIO-to-.patch | 33 -- ...s-explain-logic-for-device-becoming-.patch | 30 -- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...s-don-t-import-DM_NOSCAN-from-udev-d.patch | 37 -- ...-default-find_mutipaths-value-to-off.patch | 0 ...s-don-t-import-ID_FS_VERSION-from-ud.patch | 27 -- ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...s-adapt-MPATH_DEVICE_READY-0-logic-t.patch | 67 ---- ...-parse_vpd_pg83-match-scsi_id-output.patch | 0 ...s-adapt-coldplug-event-handling-ro-1.patch | 43 --- ...si-device-handlers-to-modules-load.d.patch | 0 ...s-don-t-import-properties-with-new-1.patch | 36 -- ...-RH-compile-with-libreadline-support.patch | 0 ...s-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch | 75 ---- ...up.patch => 0013-RH-Add-mpathcleanup.patch | 0 ...ules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch | 55 --- ...path.rules-simplify-PATH_FAILED-case.patch | 38 -- ...ules-make-label-names-more-intuitive.patch | 109 ------ 0017-kpartx.rules-ignore-DM_SUSPENDED.patch | 29 -- ...tests-fix-CI-failures-on-arm-v7-with.patch | 270 -------------- ...tests-fix-CI-failures-with-clang-on-.patch | 246 ------------- ...GitHub-actions-fixes-for-spelling-CI.patch | 31 -- ...-run-workflows-if-workflow-file-has-.patch | 146 -------- 0022-multipath-tools-add-TGTDIR-option.patch | 106 ------ ...ath-move-get_udev_for_mpp-to-sysfs.c.patch | 87 ----- ...ibmultipath-add-mp_find_path_by_devt.patch | 60 --- ...ath-fix-max_sectors_kb-on-adding-pat.patch | 33 -- ...y-set-max_sectors_kb-on-map-creation.patch | 122 ------ ...th-set-max_sectors_kb-in-adopt_paths.patch | 233 ------------ ...-wildcard-k-for-printing-max_sectors.patch | 89 ----- ...-update-documentation-for-max_sector.patch | 57 --- ...th-tools-simplify-comment-in-hwtable.patch | 34 -- ...tools-unify-text-in-multipath.conf.5.patch | 75 ---- ...ltipath-tools-update-man-pages-dates.patch | 86 ----- 0033-libmultipath-export-partmap_in_use.patch | 53 --- ...nge-flush_on_last_del-to-fix-a-multi.patch | 346 ------------------ ...ove-redundant-config-option-from-Inf.patch | 31 -- ...-dev_loss_tmo-to-avoid-race-with-no_.patch | 40 -- ...x-deferred_remove-function-arguments.patch | 107 ------ ...e-bitwise-flags-for-map-flushing-API.patch | 212 ----------- ...e-bitwise-flags-for-dm_simplecmd-API.patch | 117 ------ ...dd-argument-names-to-some-prototypes.patch | 34 -- 0041-libmultipath-bump-version-to-0.9.9.patch | 27 -- ...kflows-native.yaml-run-for-Fedora-40.patch | 24 -- 0043-update-NEWS.md.patch | 134 ------- ...ultipath.conf.5.in-fix-man-page-date.patch | 24 -- device-mapper-multipath.spec | 84 ++--- sources | 2 +- 60 files changed, 26 insertions(+), 3885 deletions(-) delete mode 100644 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch rename 0045-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0046-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) delete mode 100644 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch rename 0047-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (99%) delete mode 100644 0003-multipathd-make-multipathd-scheduling-configurable.patch rename 0048-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0004-libmpathutil-really-always-use-glibc-basename.patch rename 0049-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (100%) delete mode 100644 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch rename 0050-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (100%) delete mode 100644 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch delete mode 100644 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch rename 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) delete mode 100644 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch rename 0052-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch rename 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) delete mode 100644 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch rename 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (100%) delete mode 100644 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch rename 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (100%) delete mode 100644 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch rename 0056-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (100%) delete mode 100644 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch rename 0057-RH-Add-mpathcleanup.patch => 0013-RH-Add-mpathcleanup.patch (100%) delete mode 100644 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch delete mode 100644 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch delete mode 100644 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch delete mode 100644 0017-kpartx.rules-ignore-DM_SUSPENDED.patch delete mode 100644 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch delete mode 100644 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch delete mode 100644 0020-GitHub-actions-fixes-for-spelling-CI.patch delete mode 100644 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch delete mode 100644 0022-multipath-tools-add-TGTDIR-option.patch delete mode 100644 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch delete mode 100644 0024-libmultipath-add-mp_find_path_by_devt.patch delete mode 100644 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch delete mode 100644 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch delete mode 100644 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch delete mode 100644 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch delete mode 100644 0029-multipath.conf-5-update-documentation-for-max_sector.patch delete mode 100644 0030-multipath-tools-simplify-comment-in-hwtable.patch delete mode 100644 0031-multipath-tools-unify-text-in-multipath.conf.5.patch delete mode 100644 0032-multipath-tools-update-man-pages-dates.patch delete mode 100644 0033-libmultipath-export-partmap_in_use.patch delete mode 100644 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch delete mode 100644 0035-libmultipath-remove-redundant-config-option-from-Inf.patch delete mode 100644 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch delete mode 100644 0037-libmultipath-fix-deferred_remove-function-arguments.patch delete mode 100644 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch delete mode 100644 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch delete mode 100644 0040-libmultipath-add-argument-names-to-some-prototypes.patch delete mode 100644 0041-libmultipath-bump-version-to-0.9.9.patch delete mode 100644 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch delete mode 100644 0043-update-NEWS.md.patch delete mode 100644 0044-multipath.conf.5.in-fix-man-page-date.patch diff --git a/.gitignore b/.gitignore index 80e9936..3bea72e 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.6.tgz /multipath-tools-0.9.7.tgz /multipath-tools-0.9.8.tgz +/multipath-tools-0.9.9.tgz diff --git a/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch b/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch deleted file mode 100644 index 4b9d7fc..0000000 --- a/0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 18:16:32 +0100 -Subject: [PATCH] 11-dm-mpath.rules: fix misspelled - DM_UDEV_DISABLE_OTHER_RULES_FLAG - -Fixes: b3582da ("11-dm-mpath.rules: use import logic like 13-dm-disk.rules") -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index d364f9bc..d9585abf 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -116,7 +116,7 @@ LABEL="scan_import" - ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - - # Don't import the properties from db if we will run blkid later. --ENV{DM_NOSCAN}!="1", ENV{DM_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" -+ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - - IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" diff --git a/0045-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0045-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch diff --git a/0046-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0046-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch b/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch deleted file mode 100644 index 8a6ff99..0000000 --- a/0002-multipathd-use-condlog-level-for-setscheduler-error-.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 1 Mar 2024 19:37:29 -0500 -Subject: [PATCH] multipathd: use condlog level for setscheduler error message - -condlog uses its own log levels, so LOG_WARNING makes no sense. It -actually translates to a message sent at the LOG_DEBUG level. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 6193e691..85ac540f 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3178,7 +3178,7 @@ setscheduler (void) - res = sched_setscheduler (0, SCHED_RR, &sched_param); - - if (res == -1) -- condlog(LOG_WARNING, "Could not set SCHED_RR at priority 99"); -+ condlog(2, "Could not set SCHED_RR at priority 99"); - return; - } - diff --git a/0047-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 99% rename from 0047-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index ad7962a..267ffa7 100644 --- a/0047-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -99,7 +99,7 @@ index 780bf852..2c518378 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index 12b77156..499557a0 100644 +index 7bc8806e..315884eb 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. diff --git a/0003-multipathd-make-multipathd-scheduling-configurable.patch b/0003-multipathd-make-multipathd-scheduling-configurable.patch deleted file mode 100644 index 8529152..0000000 --- a/0003-multipathd-make-multipathd-scheduling-configurable.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 1 Mar 2024 19:37:30 -0500 -Subject: [PATCH] multipathd: make multipathd scheduling configurable - -Currently multipathd always tries to run as a realtime process with a -priority of 99. This is excessive. As a first step towards fixing this, -make it possible at compile time to lower the priority or keep -multipathd from making itself a realtime process. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile.inc | 6 ++++++ - README.md | 3 +++ - multipathd/Makefile | 3 +++ - multipathd/main.c | 5 +++-- - 4 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 5668e638..6d206281 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -18,6 +18,12 @@ READLINE := - # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac - SCSI_DH_MODULES_PRELOAD := - -+# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd -+# change its scheduling policy to SCHED_RR and its priority to the specified -+# value. set to 0 to stop multipathd from changing the scheduling policy and -+# priority it was started with. -+SCHED_RT_PRIO := 99 -+ - EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) - - # PKG_CONFIG must be read from the environment to enable compilation -diff --git a/README.md b/README.md -index d4f35f57..bb41bf0e 100644 ---- a/README.md -+++ b/README.md -@@ -98,6 +98,9 @@ The following variables can be passed to the `make` command line: - By default, command line editing is disabled. - Note that using libreadline may - [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). -+ * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority -+ multipathd will attempt to run with. for value 0, disable multipathd -+ changing itself to a realtime process. - * `ENABLE_LIBDMMP=0`: disable building libdmmp - * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event - polling API. For use with pre-5.0 kernels that don't support dmevent polling -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 997b40cf..7300f07a 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -57,6 +57,9 @@ $(CLI): $(CLI_OBJS) - cli_handlers.o: cli_handlers.c - $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - -+main.o: main.c -+ $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< -+ - install: - $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -diff --git a/multipathd/main.c b/multipathd/main.c -index 85ac540f..9486a8a3 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3172,7 +3172,7 @@ setscheduler (void) - { - int res; - static struct sched_param sched_param = { -- .sched_priority = 99 -+ .sched_priority = SCHED_RT_PRIO - }; - - res = sched_setscheduler (0, SCHED_RR, &sched_param); -@@ -3471,7 +3471,8 @@ child (__attribute__((unused)) void *param) - if (!vecs) - goto failed; - -- setscheduler(); -+ if (SCHED_RT_PRIO) -+ setscheduler(); - set_oom_adj(); - #ifdef FPIN_EVENT_HANDLER - if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) diff --git a/0048-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0048-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch diff --git a/0004-libmpathutil-really-always-use-glibc-basename.patch b/0004-libmpathutil-really-always-use-glibc-basename.patch deleted file mode 100644 index 78f8859..0000000 --- a/0004-libmpathutil-really-always-use-glibc-basename.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 3 Apr 2024 18:55:54 +0200 -Subject: [PATCH] libmpathutil: really always use glibc basename() - -Despite 03a5456 ("libmultipath: always use glibc basename()"), we -still call the system library's basename() from libmultipath. -musl libc until 1.24 provided a prototype for basename() in string.h, -which was not correct and was resolved to the destructive POSIX -basename(). musl libc 1.25 removed this prototype. - -While the remaining code path doesn't strictly depend on the non-destructive -behavior of glibc's basename(), it's cleaner and safer to use the same -implementation everywhere. - -Fixes: 03a5456 ("libmultipath: always use glibc basename()") -Fixes: https://github.com/opensvc/multipath-tools/pull/84 - -Signed-off-by: Martin Wilck -Reviewed-by: Khem Raj -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathutil/libmpathutil.version | 4 ++++ - libmpathutil/util.c | 5 +---- - libmpathutil/util.h | 5 +++++ - tests/util.c | 31 +++++++++++++++++++++++++++++++ - 4 files changed, 41 insertions(+), 4 deletions(-) - -diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version -index 80d64a3e..fee74a32 100644 ---- a/libmpathutil/libmpathutil.version -+++ b/libmpathutil/libmpathutil.version -@@ -129,3 +129,7 @@ LIBMPATHUTIL_2.0 { - vector_move_up; - vector_sort; - }; -+ -+LIBMPATHUTIL_2.1 { -+ libmp_basename; -+}; -diff --git a/libmpathutil/util.c b/libmpathutil/util.c -index 9d147fca..23d303f9 100644 ---- a/libmpathutil/util.c -+++ b/libmpathutil/util.c -@@ -32,18 +32,15 @@ strchop(char *str) - return i; - } - --#ifndef __GLIBC__ - /* - * glibc's non-destructive version of basename() - * License: LGPL-2.1-or-later - */ --static const char *__basename(const char *filename) -+const char *libmp_basename(const char *filename) - { - char *p = strrchr(filename, '/'); - return p ? p + 1 : filename; - } --#define basename(x) __basename(x) --#endif - - int - basenamecpy (const char *src, char *dst, size_t size) -diff --git a/libmpathutil/util.h b/libmpathutil/util.h -index de9fcfdd..4997fed6 100644 ---- a/libmpathutil/util.h -+++ b/libmpathutil/util.h -@@ -12,6 +12,11 @@ - #include - - size_t strchop(char *); -+ -+const char *libmp_basename(const char *filename); -+#ifndef __GLIBC__ -+#define basename(x) libmp_basename(x) -+#endif - int basenamecpy (const char *src, char *dst, size_t size); - int filepresent (const char *run); - char *get_next_string(char **temp, const char *split_char); -diff --git a/tests/util.c b/tests/util.c -index d6083dce..4850ddcb 100644 ---- a/tests/util.c -+++ b/tests/util.c -@@ -16,6 +16,7 @@ - * - */ - -+#define _GNU_SOURCE - #include - #include - #include -@@ -23,6 +24,7 @@ - #include - #include - #include -+#include - #include "util.h" - - #include "globals.c" -@@ -163,6 +165,34 @@ static int test_basenamecpy(void) - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+static void test_basename_01(void **state) -+{ -+ const char *path = "/foo/bar"; -+ const char *base; -+ -+ base = basename(path); -+ assert_string_equal(base, "bar"); -+ assert_string_equal(path, "/foo/bar"); -+} -+ -+static void test_basename_02(void **state) -+{ -+ const char *path = "/foo/bar/"; -+ const char *base; -+ -+ base = basename(path); -+ assert_string_equal(base, ""); -+ assert_string_equal(path, "/foo/bar/"); -+} -+ -+static int test_basename(void) { -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_basename_01), -+ cmocka_unit_test(test_basename_02), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ - /* - * On big endian systems, if bitfield_t is 32bit, we need - * to swap the two 32 bit parts of a 64bit value to make -@@ -946,6 +976,7 @@ int main(void) - - init_test_verbosity(-1); - ret += test_basenamecpy(); -+ ret += test_basename(); - ret += test_bitmasks(); - ret += test_strlcpy(); - ret += test_strlcat(); diff --git a/0049-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 100% rename from 0049-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch diff --git a/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch b/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch deleted file mode 100644 index fd12767..0000000 --- a/0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Apr 2024 18:56:12 -0400 -Subject: [PATCH] multipathd: make multipathd set priority to RLIMIT_RTPRIO - -With this change, if the SCHED_RT_PRIO compiler flag has been removed. -Instead multipathd will call getrlimit(RLIMIT_RTPRIO, ...) and look at -the hard limit. It it's 0, multipath will do nothing. Otherwise it will -change its scheduling policy to SCHED_RR and its priority to the hard -limit. - -This allows users to change the priority of that multipathd runs with by -adding - -LimitRTPRIO= - -to the [Service] section of the multipathd.service unit file. Setting -LimitRTPRIO=0 will make multipathd run as a normal process, while -setting LimitRTPRIO=infinity will make it use the maximum SCHED_RR prio, -which is 99. - -To keep the existing behavior, multipathd.service now sets -LimitRTPRIO=infinity - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile.inc | 6 ------ - README.md | 3 --- - multipathd/Makefile | 3 --- - multipathd/main.c | 22 +++++++++++++++------- - multipathd/multipathd.service.in | 1 + - 5 files changed, 16 insertions(+), 19 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 6d206281..5668e638 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -18,12 +18,6 @@ READLINE := - # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac - SCSI_DH_MODULES_PRELOAD := - --# Multipathd scheduling priority. Set value from 1 to 99 to make multipathd --# change its scheduling policy to SCHED_RR and its priority to the specified --# value. set to 0 to stop multipathd from changing the scheduling policy and --# priority it was started with. --SCHED_RT_PRIO := 99 -- - EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) - - # PKG_CONFIG must be read from the environment to enable compilation -diff --git a/README.md b/README.md -index bb41bf0e..d4f35f57 100644 ---- a/README.md -+++ b/README.md -@@ -98,9 +98,6 @@ The following variables can be passed to the `make` command line: - By default, command line editing is disabled. - Note that using libreadline may - [make binary indistributable due to license incompatibility](https://github.com/opensvc/multipath-tools/issues/36). -- * `SCHED_RT_PRIO={0-99}`: for values {1-99} set the realtime priority -- multipathd will attempt to run with. for value 0, disable multipathd -- changing itself to a realtime process. - * `ENABLE_LIBDMMP=0`: disable building libdmmp - * `ENABLE_DMEVENTS_POLL=0`: disable support for the device-mapper event - polling API. For use with pre-5.0 kernels that don't support dmevent polling -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 7300f07a..997b40cf 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -57,9 +57,6 @@ $(CLI): $(CLI_OBJS) - cli_handlers.o: cli_handlers.c - $(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter -c -o $@ $< - --main.o: main.c -- $(Q)$(CC) $(CPPFLAGS) -DSCHED_RT_PRIO=$(SCHED_RT_PRIO) $(CFLAGS) -c -o $@ $< -- - install: - $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -diff --git a/multipathd/main.c b/multipathd/main.c -index 9486a8a3..dd17d5c3 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -3171,14 +3171,23 @@ static void - setscheduler (void) - { - int res; -- static struct sched_param sched_param = { -- .sched_priority = SCHED_RT_PRIO -- }; -+ static struct sched_param sched_param; -+ struct rlimit rlim; -+ -+ if (getrlimit(RLIMIT_RTPRIO, &rlim) < 0 || rlim.rlim_max == 0) -+ return; -+ -+ sched_param.sched_priority = rlim.rlim_max > INT_MAX ? INT_MAX : -+ rlim.rlim_max; -+ res = sched_get_priority_max(SCHED_RR); -+ if (res > 0 && res < sched_param.sched_priority) -+ sched_param.sched_priority = res; - -- res = sched_setscheduler (0, SCHED_RR, &sched_param); -+ res = sched_setscheduler(0, SCHED_RR, &sched_param); - - if (res == -1) -- condlog(2, "Could not set SCHED_RR at priority 99"); -+ condlog(2, "Could not set SCHED_RR at priority %d", -+ sched_param.sched_priority); - return; - } - -@@ -3471,8 +3480,7 @@ child (__attribute__((unused)) void *param) - if (!vecs) - goto failed; - -- if (SCHED_RT_PRIO) -- setscheduler(); -+ setscheduler(); - set_oom_adj(); - #ifdef FPIN_EVENT_HANDLER - if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) -diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 6d03ff71..18bb367e 100644 ---- a/multipathd/multipathd.service.in -+++ b/multipathd/multipathd.service.in -@@ -19,6 +19,7 @@ NotifyAccess=main - ExecStart=/sbin/multipathd -d -s - ExecReload=/sbin/multipathd reconfigure - TasksMax=infinity -+LimitRTPRIO=infinity - - [Install] - WantedBy=sysinit.target diff --git a/0050-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 100% rename from 0050-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch diff --git a/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch b/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch deleted file mode 100644 index 0cbe997..0000000 --- a/0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 15 Apr 2024 19:43:06 -0400 -Subject: [PATCH] multipathd: Set CPUWeight to 1000 and LimitRTPRIO to 10 - -If multipathd doesn't become a real time process, it was scheduled as a -normal process, without any priority increase. Bump up the CPUWeight so -that even as a normal process, it will still run with increased -priority. - -If multipathd did become a real time process, it set itself to the -highest priority, which is excessive. A priority of 10 is plenty. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/multipathd.service.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 18bb367e..a63ddd9a 100644 ---- a/multipathd/multipathd.service.in -+++ b/multipathd/multipathd.service.in -@@ -19,7 +19,8 @@ NotifyAccess=main - ExecStart=/sbin/multipathd -d -s - ExecReload=/sbin/multipathd reconfigure - TasksMax=infinity --LimitRTPRIO=infinity -+LimitRTPRIO=10 -+CPUWeight=1000 - - [Install] - WantedBy=sysinit.target diff --git a/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch b/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch deleted file mode 100644 index 6241459..0000000 --- a/0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 19:53:14 +0100 -Subject: [PATCH] 11-dm-mpath.rules: explain logic for device becoming ready - while suspended - -Add a comment to explain why we must set MPATH_DEVICE_READY=0 when -we see a device becoming ready (number of active paths 0 -> 1) while -the device is suspended. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index d9585abf..b8d19d01 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -98,6 +98,8 @@ ENV{MPATH_DEVICE_READY}=="0", \ - # If the device comes back online, set DM_ACTIVATION so that - # upper layers do a rescan. If the device is currently suspended, - # we have to postpone the activation until the next event. -+# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the -+# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. - ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" - ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" - ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" diff --git a/0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch b/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch deleted file mode 100644 index 3900b39..0000000 --- a/0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 19:57:59 +0100 -Subject: [PATCH] 11-dm-mpath.rules: don't import DM_NOSCAN from udev db - -DM_NOSCAN is our "output" flag for 13-dm-disk.rules, and it should -be treated the same way as DM_UDEV_DISABLE_OTHER_RULES_FLAG, which -isn't imported from the udev database. The state that we need to -remember is MPATH_DEVICE_READY, which we've already imported above, -and we will set the "output" flags accordingly in the "force_activation" -code path further down. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index b8d19d01..eb12b0c6 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -18,9 +18,11 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 - - # If this uevent didn't come from dm, don't try to update the - # device state -+# Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the -+# device below at force_activation, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ -- IMPORT{db}="DM_NOSCAN", IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ -- GOTO="scan_import" -+ IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ -+ GOTO="force_activation" - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - diff --git a/0052-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0052-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch b/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch deleted file mode 100644 index 933a43a..0000000 --- a/0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 21:02:49 +0100 -Subject: [PATCH] 11-dm-mpath.rules: don't import ID_FS_VERSION from udev db - -Use the same set of properties to import as 13-dm-disk.rules. -ID_FS_VERSION isn't used in any udev rule I am aware of. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index eb12b0c6..4386b6ca 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -126,7 +126,6 @@ IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" - IMPORT{db}="ID_FS_UUID_ENC" - IMPORT{db}="ID_FS_LABEL_ENC" --IMPORT{db}="ID_FS_VERSION" - IMPORT{db}="ID_PART_ENTRY_NAME" - IMPORT{db}="ID_PART_ENTRY_UUID" - IMPORT{db}="ID_PART_ENTRY_SCHEME" diff --git a/0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch b/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch deleted file mode 100644 index 97b3901..0000000 --- a/0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 20:53:50 +0100 -Subject: [PATCH] 11-dm-mpath.rules: adapt MPATH_DEVICE_READY=0 logic to - 10-dm.rules update - -With the late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG isn't -restored from the udev database any more, so we don't need to restore -the flag to its original state before it is saved to the db. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 22 ++++++++++++---------- - 1 file changed, 12 insertions(+), 10 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 4386b6ca..2f909c3a 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -19,7 +19,7 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1 - # If this uevent didn't come from dm, don't try to update the - # device state - # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the --# device below at force_activation, which is correct. -+# device below at mpath_is_ready, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ - IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ - GOTO="force_activation" -@@ -84,25 +84,27 @@ ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ - - LABEL="force_activation" - -+ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - # Do not initiate scanning if no path is available, - # otherwise there would be a hang or IO error on access. - # We'd like to avoid this, especially within udev processing. --ENV{MPATH_DEVICE_READY}=="0", ENV{DM_NOSCAN}="1" -- --# Skip all foreign rules if no path is available. -+# This is communicated to later rules in DM_NOSCAN. -+# Likewise, skip all foreign rules if no path is available. - # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this --# to upper layers. The original value will be restored in a late --# udev rule. --ENV{MPATH_DEVICE_READY}=="0", \ -- ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}", \ -- ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" -+# to upper layers. With dm rules < v3, save the original value here; -+# it will be restored in a late udev rule. -+ENV{DM_UDEV_RULES_VSN}=="1|2", \ -+ ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" -+ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" -+GOTO="dont_activate" -+ -+LABEL="mpath_is_ready" - - # If the device comes back online, set DM_ACTIVATION so that - # upper layers do a rescan. If the device is currently suspended, - # we have to postpone the activation until the next event. - # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the - # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. --ENV{MPATH_DEVICE_READY}=="0", GOTO="dont_activate" - ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" - ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" - diff --git a/0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 100% rename from 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch diff --git a/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch b/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch deleted file mode 100644 index 938a07f..0000000 --- a/0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 20:55:40 +0100 -Subject: [PATCH] 11-dm-mpath.rules: adapt coldplug event handling ro - 10-dm.rules update - -With late late patches for 10-dm.rules, DM_UDEV_DISABLE_OTHER_RULES_FLAG is -never restored from the udev db. Thus we don't need to clear it here -any more for coldplug events. Also, we must use .DM_SUSPENDED instead of -DM_SUSPENDED as input flag with the v3 rule set (other occurences of -DM_SUSPENDED will be replaced in a follow-up patch). - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 2f909c3a..5f547cab 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -9,12 +9,17 @@ ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ - ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" - --# Coldplug event. DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored -+# Coldplug event. Import previously set properties. -+ACTION!="add", GOTO="mpath_coldplug_end" -+ENV{DM_ACTIVATION}!="1", GOTO="mpath_coldplug_end" -+ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" -+# With DM rules < v3, DM_UDEV_DISABLE_OTHER_RULES_FLAG has been restored - # from DB in 10-dm.rules. If the device is not suspended, clear the flag. - # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically - # equivalent to DM_SUSPENDED==1 || DISK_RO==1 --ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ -+ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" -+LABEL="mpath_coldplug_end" - - # If this uevent didn't come from dm, don't try to update the - # device state diff --git a/0055-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 100% rename from 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch diff --git a/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch b/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch deleted file mode 100644 index f4e69cf..0000000 --- a/0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 20:58:47 +0100 -Subject: [PATCH] 11-dm-mpath.rules: don't import properties with new - 13-dm-disk.rules - -With the late changes to 13-dm-disk.rules, we don't need to import any -blkid-generated properties from the udev database, because they will -be imported later. - -Except for ID_FS_TYPE, this actually holds since lvm2 commit 94f77a4 ("udev: -import previous results of blkid when in suspended state"), included in lvm2 -2.03.19, but we have no simple way to detect the version of the lvm2 rules. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 5f547cab..95126bf2 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -126,6 +126,10 @@ LABEL="scan_import" - # have never been properly set. Don't import them. - ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - -+# DM rules v3 will import missing properties on 13-dm-disk.rules. -+# No need to do it here. -+ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" -+ - # Don't import the properties from db if we will run blkid later. - ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - diff --git a/0056-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 100% rename from 0056-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch diff --git a/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch b/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch deleted file mode 100644 index e922427..0000000 --- a/0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 22:33:59 +0100 -Subject: [PATCH] 11-dm-mpath.rules: replace DM_SUSPENDED by .DM_SUSPENDED - -With the late changes to the device mapper rules, DM_SUSPENDED -is not exported any more. Use .DM_SUSPENDED instead. - -Note that although 11-dm-mpath.rules is not a part of lvm2, it -can be considered as part of the device-mapper layer (everything -before 13-dm-disk.rules can), and is thus allowed to use -.DM_SUSPENDED. In practice .DM_SUSPENDED is equivalent to -DM_UDEV_DISABLE_OTHER_RULES_FLAG for multipath devices, but -using .DM_SUSPENDED here makes the intention more obvious. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 95126bf2..efc6416f 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -4,8 +4,11 @@ ENV{DM_UUID}!="mpath-?*", GOTO="mpath_end" - - IMPORT{db}="MPATH_DEVICE_READY" - -+# device-mapper rules v2 compatibility -+ENV{.DM_SUSPENDED}!="?*", ENV{.DM_SUSPENDED}="$env{DM_SUSPENDED}" -+ - # Coldplug event while device is suspended (e.g. during a reload) --ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="1", \ -+ACTION=="add", ENV{DM_ACTIVATION}=="1", ENV{.DM_SUSPENDED}=="1", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.warning \"Coldplug event for suspended device\"", \ - ENV{DM_COLDPLUG_SUSPENDED}="1", GOTO="scan_import" - -@@ -17,7 +20,7 @@ ENV{DM_UDEV_RULES_VSN}!="1|2", ENV{.DM_SUSPENDED}!="1", GOTO="scan_import" - # from DB in 10-dm.rules. If the device is not suspended, clear the flag. - # This is safe for multipath where DM_UDEV_DISABLE_OTHER_RULES_FLAG is basically - # equivalent to DM_SUSPENDED==1 || DISK_RO==1 --ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ -+ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" - LABEL="mpath_coldplug_end" - -@@ -68,7 +71,7 @@ LABEL="mpath_action" - # Activation might have been partially skipped. Activate the device now, - # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. - IMPORT{db}="DM_COLDPLUG_SUSPENDED" --ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{DM_SUSPENDED}!="1", \ -+ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ - GOTO="force_activation" -@@ -111,7 +114,7 @@ LABEL="mpath_is_ready" - # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the - # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. - ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" --ENV{DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" -+ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" - - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" - LABEL="dont_activate" -@@ -145,7 +148,7 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" - LABEL="import_end" - - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now --ENV{DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" -+ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" - - # Multipath maps should take precedence over their members. - ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" diff --git a/0057-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch similarity index 100% rename from 0057-RH-Add-mpathcleanup.patch rename to 0013-RH-Add-mpathcleanup.patch diff --git a/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch b/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch deleted file mode 100644 index a5eecaf..0000000 --- a/0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 23:23:53 +0100 -Subject: [PATCH] 11-dm-mpath.rules: replace DM_NOSCAN by .DM_NOSCAN - -We don't need to restore DM_NOSCAN from the db anymore, so we can rename -it to .DM_NOSCAN, making it a temporary property. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index efc6416f..3ae3c054 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -96,14 +96,14 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - # Do not initiate scanning if no path is available, - # otherwise there would be a hang or IO error on access. - # We'd like to avoid this, especially within udev processing. --# This is communicated to later rules in DM_NOSCAN. -+# This is communicated to later rules in .DM_NOSCAN. - # Likewise, skip all foreign rules if no path is available. - # Use DM_UDEV_DISABLE_OTHER_RULES_FLAG to communicate this - # to upper layers. With dm rules < v3, save the original value here; - # it will be restored in a late udev rule. - ENV{DM_UDEV_RULES_VSN}=="1|2", \ - ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" --ENV{DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" -+ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" - GOTO="dont_activate" - - LABEL="mpath_is_ready" -@@ -134,7 +134,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" - - # Don't import the properties from db if we will run blkid later. --ENV{DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" -+ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - - IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" -@@ -150,6 +150,9 @@ LABEL="import_end" - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now - ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" - -+# device-mapper rules v2 compatibility for 13-dm-disk.rules -+ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{DM_NOSCAN}="$env{.DM_NOSCAN}" -+ - # Multipath maps should take precedence over their members. - ENV{DM_UDEV_LOW_PRIORITY_FLAG}!="1", OPTIONS+="link_priority=50" - diff --git a/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch b/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch deleted file mode 100644 index ce393ae..0000000 --- a/0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Mar 2024 21:17:51 +0100 -Subject: [PATCH] 11-dm-mpath.rules: simplify PATH_FAILED case - -This combination of a GOTO and a simple rule can be combined -into a single rule. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 12 ++++-------- - 1 file changed, 4 insertions(+), 8 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 3ae3c054..4777fbec 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -56,14 +56,10 @@ PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" - ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" - LABEL="paths_ok" - --# Don't mark a device ready on a PATH_FAILED event. even if --# DM_NR_VALID_PATHS is greater than 0. Just keep the existing --# value --ENV{DM_ACTION}=="PATH_FAILED", GOTO="mpath_action" -- --# This event is either a PATH_REINSTATED or a table reload where --# there are active paths. Mark the device ready --ENV{MPATH_DEVICE_READY}="1" -+# For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. -+# If it's not PATH_FAILED, this event is either a PATH_REINSTATED or a -+# table reload where there are active paths. Mark the device ready. -+ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" - - LABEL="mpath_action" - diff --git a/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch b/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch deleted file mode 100644 index e81f04f..0000000 --- a/0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 21:54:26 +0100 -Subject: [PATCH] 11-dm-mpath.rules: make label names more intuitive - -The labels "dont_activate" and "scan_import" denote the same code line. -Remove "dont_activate". Improve two misleading label names. - -Substitutions: - dont_activate -> scan_import - force_activation -> check_mpath_ready - mpath_action -> check_mpath_unchanged - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 4777fbec..0562eddf 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -30,7 +30,7 @@ LABEL="mpath_coldplug_end" - # device below at mpath_is_ready, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ - IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ -- GOTO="force_activation" -+ GOTO="check_mpath_ready" - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - -@@ -38,13 +38,13 @@ ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - # table with no active devices. If this happens, mark the - # device not ready - ENV{DM_SUBSYSTEM_UDEV_FLAG2}=="1", ENV{MPATH_DEVICE_READY}="0", \ -- GOTO="mpath_action" -+ GOTO="check_mpath_unchanged" - - # If the last path has failed mark the device not ready - # Note that DM_NR_VALID_PATHS is only set for PATH_FAILED|PATH_REINSTATED - # events. - # This may not be reliable, as events aren't necessarily received in order. --ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" -+ENV{DM_NR_VALID_PATHS}=="0", ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" - - # Don't run multipath -U during "coldplug" after switching root, - # because paths are just being added to the udev db. -@@ -53,7 +53,8 @@ ACTION=="add", ENV{.MPATH_DEVICE_READY_OLD}=="1", GOTO="paths_ok" - # Check the map state directly with multipath -U. - # This doesn't attempt I/O on the device. - PROGRAM=="@BINDIR@/multipath -U -v1 %k", GOTO="paths_ok" --ENV{MPATH_DEVICE_READY}="0", GOTO="mpath_action" -+ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" -+ - LABEL="paths_ok" - - # For PATH_FAILED events, keep the existing value of MPATH_DEVICE_READY. -@@ -61,7 +62,7 @@ LABEL="paths_ok" - # table reload where there are active paths. Mark the device ready. - ENV{DM_ACTION}!="PATH_FAILED", ENV{MPATH_DEVICE_READY}="1" - --LABEL="mpath_action" -+LABEL="check_mpath_unchanged" - - # A previous coldplug event occurred while the device was suspended. - # Activation might have been partially skipped. Activate the device now, -@@ -70,7 +71,7 @@ IMPORT{db}="DM_COLDPLUG_SUSPENDED" - ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="/bin/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ -- GOTO="force_activation" -+ GOTO="check_mpath_ready" - - # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. - # Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its -@@ -86,7 +87,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ - ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ - ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" - --LABEL="force_activation" -+LABEL="check_mpath_ready" - - ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - # Do not initiate scanning if no path is available, -@@ -100,7 +101,7 @@ ENV{MPATH_DEVICE_READY}!="0", GOTO="mpath_is_ready" - ENV{DM_UDEV_RULES_VSN}=="1|2", \ - ENV{.MPATH_SAVE_DISABLE_OTHER_RULES_FLAG}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}" - ENV{.DM_NOSCAN}="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" --GOTO="dont_activate" -+GOTO="scan_import" - - LABEL="mpath_is_ready" - -@@ -109,11 +110,10 @@ LABEL="mpath_is_ready" - # we have to postpone the activation until the next event. - # In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the - # MPATH_UNCHANGED logic will cause later rules to skipped in the next event. --ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="dont_activate" --ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="dont_activate" -+ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" -+ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" - - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" --LABEL="dont_activate" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or diff --git a/0017-kpartx.rules-ignore-DM_SUSPENDED.patch b/0017-kpartx.rules-ignore-DM_SUSPENDED.patch deleted file mode 100644 index 3b0ac76..0000000 --- a/0017-kpartx.rules-ignore-DM_SUSPENDED.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 1 Mar 2024 21:17:26 +0100 -Subject: [PATCH] kpartx.rules: ignore DM_SUSPENDED - -DM_SUSPENDED=1 implies DM_UDEV_DISABLE_OTHER_RULES_FLAG=1, no -need to check it again. The DM_NOSCAN check needs to remain in -order to keep compatibility with dm rules v2. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.rules | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 1969dee0..8dd3369c 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -27,7 +27,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" - ENV{MPATH_UNCHANGED}=="1", GOTO="mpath_kpartx_end" - - # Don't run kpartx now if we know it will fail or hang. --ENV{DM_SUSPENDED}=="1", GOTO="mpath_kpartx_end" -+# This is required for device mapper rules v2 compatibility. - ENV{DM_NOSCAN}=="1", GOTO="mpath_kpartx_end" - - # Run kpartx diff --git a/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch b/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch deleted file mode 100644 index 2840cec..0000000 --- a/0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 4 Apr 2024 23:23:28 +0200 -Subject: [PATCH] multipath-tools tests: fix CI failures on arm/v7 with glibc - 2.37 - -glibc 2.37 has added several new wrappers around the ioctl and -io_getevents system calls on 32 bit systems, to deal with 64bit -time_t. These aren't resolved with cmocka's wrapping technique. - -Fix this with C preprocessor trickery, similar to -7b217f8 ("multipath-tools: Makefile.inc: set _FILE_OFFSET_BITS=64"). - -Note: the directio test with DIO_TEST_DEV for fails under qemu-linux-user -with foreign-arch binfmt, because aio-related system calls are unsupported -by qemu-linux-user. See https://gitlab.com/qemu-project/qemu/-/issues/210. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/directio.c | 28 ++++++++++++++-------------- - tests/vpd.c | 35 ++++++++++++++++++----------------- - tests/wrap64.h | 25 ++++++++++++++++++++++++- - 3 files changed, 56 insertions(+), 32 deletions(-) - -diff --git a/tests/directio.c b/tests/directio.c -index cbedcc9c..d5f84f10 100644 ---- a/tests/directio.c -+++ b/tests/directio.c -@@ -41,13 +41,13 @@ struct timespec full_timeout = { .tv_sec = -1 }; - #define ioctl_request_t int - #endif - --int __real_ioctl(int fd, ioctl_request_t request, void *argp); -+int REAL_IOCTL(int fd, ioctl_request_t request, void *argp); - --int __wrap_ioctl(int fd, ioctl_request_t request, void *argp) -+int WRAP_IOCTL(int fd, ioctl_request_t request, void *argp) - { - #ifdef DIO_TEST_DEV - mock_type(int); -- return __real_ioctl(fd, request, argp); -+ return REAL_IOCTL(fd, request, argp); - #else - int *blocksize = (int *)argp; - -@@ -148,10 +148,10 @@ int __wrap_io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt) - #endif - } - --int __real_io_getevents(io_context_t ctx, long min_nr, long nr, -+int REAL_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, - struct io_event *events, struct timespec *timeout); - --int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, -+int WRAP_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr, - struct io_event *events, struct timespec *timeout) - { - int nr_evs; -@@ -169,8 +169,8 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, - #ifdef DIO_TEST_DEV - mock_ptr_type(struct timespec *); - mock_ptr_type(struct io_event *); -- assert_int_equal(nr_evs, __real_io_getevents(ctx, min_nr, nr_evs, -- events, timeout)); -+ assert_int_equal(nr_evs, REAL_IO_GETEVENTS(ctx, min_nr, nr_evs, -+ events, timeout)); - #else - sleep_tmo = mock_ptr_type(struct timespec *); - if (sleep_tmo) { -@@ -193,7 +193,7 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr, - - static void return_io_getevents_none(void) - { -- will_return(__wrap_io_getevents, 0); -+ wrap_will_return(WRAP_IO_GETEVENTS, 0); - } - - static void return_io_getevents_nr(struct timespec *ts, int nr, -@@ -207,15 +207,15 @@ static void return_io_getevents_nr(struct timespec *ts, int nr, - mock_events[i + ev_off].res = reqs[i]->blksize; - } - while (nr > 0) { -- will_return(__wrap_io_getevents, (nr > 128)? 128 : nr); -- will_return(__wrap_io_getevents, ts); -- will_return(__wrap_io_getevents, &mock_events[off + ev_off]); -+ wrap_will_return(WRAP_IO_GETEVENTS, (nr > 128)? 128 : nr); -+ wrap_will_return(WRAP_IO_GETEVENTS, ts); -+ wrap_will_return(WRAP_IO_GETEVENTS, &mock_events[off + ev_off]); - ts = NULL; - off += 128; - nr -= 128; - } - if (nr == 0) -- will_return(__wrap_io_getevents, 0); -+ wrap_will_return(WRAP_IO_GETEVENTS, 0); - ev_off += i; - } - -@@ -251,7 +251,7 @@ static void do_libcheck_init(struct checker *c, int blocksize, - struct directio_context * ct; - - c->fd = test_fd; -- will_return(__wrap_ioctl, blocksize); -+ wrap_will_return(WRAP_IOCTL, blocksize); - assert_int_equal(libcheck_init(c), 0); - ct = (struct directio_context *)c->context; - assert_non_null(ct); -@@ -762,7 +762,7 @@ int main(void) - { - int ret = 0; - -- init_test_verbosity(2); -+ init_test_verbosity(5); - ret += test_directio(); - return ret; - } -diff --git a/tests/vpd.c b/tests/vpd.c -index 1b2d62d6..e3212e61 100644 ---- a/tests/vpd.c -+++ b/tests/vpd.c -@@ -20,6 +20,7 @@ - #include "vector.h" - #include "structs.h" - #include "discovery.h" -+#include "wrap64.h" - #include "globals.c" - - #define VPD_BUFSIZ 4096 -@@ -58,7 +59,7 @@ static const char vendor_id[] = "Linux"; - static const char test_id[] = - "A123456789AbcDefB123456789AbcDefC123456789AbcDefD123456789AbcDef"; - --int __wrap_ioctl(int fd, unsigned long request, void *param) -+int WRAP_IOCTL(int fd, unsigned long request, void *param) - { - int len; - struct sg_io_hdr *io_hdr; -@@ -428,8 +429,8 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state) \ - /* Replace spaces, like code under test */ \ - exp_subst = subst_spaces(exp_wwid); \ - free(exp_wwid); \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen, \ - exp_len, ret, '1', 0, false, \ -@@ -458,8 +459,8 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \ - exp_len--; \ - if (exp_len >= wlen) \ - exp_len = wlen - 1; \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen, \ - exp_len, ret, byte0[type], 0, \ -@@ -495,8 +496,8 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state) \ - \ - n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, \ - 3, naa, 0); \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen, \ - exp_len, ret, '3', '0' + naa, true, \ -@@ -518,8 +519,8 @@ static void test_vpd_naa_##NAA##_badlen_##BAD(void **state) \ - n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 3, NAA, 0); \ - \ - vt->vpdbuf[7] = BAD; \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ - assert_int_equal(-ret, -ERR); \ - } -@@ -545,11 +546,11 @@ static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state) \ - /* overwrite the page size to DEFAULT_SGIO_LEN + 1 */ \ - put_unaligned_be16(255, vt->vpdbuf + 2); \ - /* this causes get_vpd_sgio to do a second ioctl */ \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - } \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml, \ - exp_len, ret, '2', 0, true, \ -@@ -571,8 +572,8 @@ static void test_vpd_eui_badlen_##LEN##_##BAD(void **state) \ - n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 2, 0, LEN); \ - \ - vt->vpdbuf[7] = BAD; \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40); \ - assert_int_equal(ret, ERR); \ - if (ERR >= 0) \ -@@ -600,8 +601,8 @@ static void test_vpd80_ ## size ## _ ## len ## _ ## wlen(void **state) \ - exp_len = wlen - 1; \ - n = create_vpd80(vt->vpdbuf, sizeof(vt->vpdbuf), input, \ - size, len); \ -- will_return(__wrap_ioctl, n); \ -- will_return(__wrap_ioctl, vt->vpdbuf); \ -+ wrap_will_return(WRAP_IOCTL, n); \ -+ wrap_will_return(WRAP_IOCTL, vt->vpdbuf); \ - ret = get_vpd_sgio(10, 0x80, 0, vt->wwid, wlen); \ - assert_correct_wwid("test_vpd80_" #size "_" #len "_" #wlen, \ - exp_len, ret, 0, 0, false, \ -diff --git a/tests/wrap64.h b/tests/wrap64.h -index 8c91d279..b0a4d831 100644 ---- a/tests/wrap64.h -+++ b/tests/wrap64.h -@@ -1,5 +1,7 @@ - #ifndef _WRAP64_H - #define _WRAP64_H 1 -+#include -+#include - #include "util.h" - - /* -@@ -31,7 +33,9 @@ - * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. - * https://savannah.gnu.org/forum/forum.php?forum_id=9205 - */ --#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) -+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 -+#define WRAP_FCNTL_NAME __fcntl_time64 -+#elif defined(__GLIBC__) && __GLIBC_PREREQ(2, 28) - #define WRAP_FCNTL_NAME WRAP_NAME(fcntl) - #else - #define WRAP_FCNTL_NAME fcntl -@@ -39,6 +43,25 @@ - #define WRAP_FCNTL CONCAT2(__wrap_, WRAP_FCNTL_NAME) - #define REAL_FCNTL CONCAT2(__real_, WRAP_FCNTL_NAME) - -+/* -+ * glibc 2.37 uses __ioctl_time64 for ioctl -+ */ -+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7 -+#define WRAP_IOCTL_NAME __ioctl_time64 -+#else -+#define WRAP_IOCTL_NAME ioctl -+#endif -+#define WRAP_IOCTL CONCAT2(__wrap_, WRAP_IOCTL_NAME) -+#define REAL_IOCTL CONCAT2(__real_, WRAP_IOCTL_NAME) -+ -+#if defined(__NR_io_pgetevents) && __BITS_PER_LONG == 32 && defined(_TIME_BITS) && _TIME_BITS == 64 -+#define WRAP_IO_GETEVENTS_NAME io_getevents_time64 -+#else -+#define WRAP_IO_GETEVENTS_NAME io_getevents -+#endif -+#define WRAP_IO_GETEVENTS CONCAT2(__wrap_, WRAP_IO_GETEVENTS_NAME) -+#define REAL_IO_GETEVENTS CONCAT2(__real_, WRAP_IO_GETEVENTS_NAME) -+ - /* - * will_return() is itself a macro that uses CPP "stringizing". We need a - * macro indirection to make sure the *value* of WRAP_FUNC() is stringized diff --git a/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch b/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch deleted file mode 100644 index d1dedac..0000000 --- a/0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 5 Apr 2024 22:21:43 +0200 -Subject: [PATCH] multipath-tools tests: fix CI failures with clang on Fedora - Rawhide - -Fedora's glibc 2.39 includes the following patch: - -https://patches.linaro.org/project/libc-alpha/patch/20240208184622.332678-10-adhemerval.zanella@linaro.org/ - -It causes open("file", O_RDONLY) to resolve to __open64_2(), -whereas it resolves to open64() with gcc, causing CI failures because of -wrong wrapper substitutions. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - tests/dmevents.c | 6 ++--- - tests/sysfs.c | 58 ++++++++++++++++++++++++------------------------ - tests/test-lib.c | 6 ++--- - tests/wrap64.h | 14 ++++++++++++ - 4 files changed, 49 insertions(+), 35 deletions(-) - -diff --git a/tests/dmevents.c b/tests/dmevents.c -index 540bf0d3..395b16d7 100644 ---- a/tests/dmevents.c -+++ b/tests/dmevents.c -@@ -207,7 +207,7 @@ static int teardown(void **state) - return 0; - } - --int WRAP_FUNC(open)(const char *pathname, int flags) -+int WRAP_OPEN(const char *pathname, int flags) - { - assert_ptr_equal(pathname, "/dev/mapper/control"); - assert_int_equal(flags, O_RDWR); -@@ -389,7 +389,7 @@ static void test_init_waiter_bad1(void **state) - struct test_data *datap = (struct test_data *)(*state); - if (datap == NULL) - skip(); -- wrap_will_return(WRAP_FUNC(open), -1); -+ wrap_will_return(WRAP_OPEN, -1); - assert_int_equal(init_dmevent_waiter(&datap->vecs), -1); - assert_ptr_equal(waiter, NULL); - } -@@ -400,7 +400,7 @@ static void test_init_waiter_good0(void **state) - struct test_data *datap = (struct test_data *)(*state); - if (datap == NULL) - skip(); -- wrap_will_return(WRAP_FUNC(open), 2); -+ wrap_will_return(WRAP_OPEN, 2); - assert_int_equal(init_dmevent_waiter(&datap->vecs), 0); - assert_ptr_not_equal(waiter, NULL); - } -diff --git a/tests/sysfs.c b/tests/sysfs.c -index fc256d87..c623d1bb 100644 ---- a/tests/sysfs.c -+++ b/tests/sysfs.c -@@ -29,7 +29,7 @@ char *__wrap_udev_device_get_syspath(struct udev_device *ud) - return val; - } - --int WRAP_FUNC(open)(const char *pathname, int flags) -+int WRAP_OPEN(const char *pathname, int flags) - { - int ret; - -@@ -167,10 +167,10 @@ static void test_sagv_open_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); - errno = ENOENT; -- wrap_will_return(WRAP_FUNC(open), -1); -+ wrap_will_return(WRAP_OPEN, -1); - expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' cannot be opened"); - assert_int_equal(sysfs_attr_get_value((void *)state, "bar", - buf, sizeof(buf)), -ENOENT); -@@ -182,9 +182,9 @@ static void test_sagv_read_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, sizeof(buf)); - errno = EISDIR; -@@ -197,9 +197,9 @@ static void test_sagv_read_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/baz'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/baz"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, sizeof(buf)); - errno = EPERM; -@@ -223,9 +223,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) - memset(buf, '.', sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, bufsz); - will_return(__wrap_read, sizeof(input) - 1); -@@ -250,9 +250,9 @@ static void _test_sagv_read(void **state, unsigned int bufsz) - memset(buf, '.', sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/baz'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/baz"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/baz"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, bufsz); - will_return(__wrap_read, sizeof(input) - 1); -@@ -301,9 +301,9 @@ static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) - memset(buf, '.', sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_RDONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_RDONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_read, fd, TEST_FD); - expect_value(__wrap_read, count, bufsz); - will_return(__wrap_read, sizeof(input) - 1); -@@ -386,10 +386,10 @@ static void test_sasv_open_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_WRONLY); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_WRONLY); - errno = EPERM; -- wrap_will_return(WRAP_FUNC(open), -1); -+ wrap_will_return(WRAP_OPEN, -1); - expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' cannot be opened"); - assert_int_equal(sysfs_attr_set_value((void *)state, "bar", - buf, sizeof(buf)), -EPERM); -@@ -401,9 +401,9 @@ static void test_sasv_write_fail(void **state) - - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_WRONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_WRONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_write, fd, TEST_FD); - expect_value(__wrap_write, count, sizeof(buf)); - errno = EISDIR; -@@ -422,9 +422,9 @@ static void _test_sasv_write(void **state, unsigned int n_written) - assert_in_range(n_written, 0, sizeof(buf)); - will_return(__wrap_udev_device_get_syspath, "/foo"); - expect_condlog(4, "open '/foo/bar'"); -- expect_string(WRAP_FUNC(open), pathname, "/foo/bar"); -- expect_value(WRAP_FUNC(open), flags, O_WRONLY); -- wrap_will_return(WRAP_FUNC(open), TEST_FD); -+ expect_string(WRAP_OPEN, pathname, "/foo/bar"); -+ expect_value(WRAP_OPEN, flags, O_WRONLY); -+ wrap_will_return(WRAP_OPEN, TEST_FD); - expect_value(__wrap_write, fd, TEST_FD); - expect_value(__wrap_write, count, sizeof(buf)); - will_return(__wrap_write, n_written); -@@ -489,7 +489,7 @@ int main(void) - { - int ret = 0; - -- init_test_verbosity(4); -+ init_test_verbosity(5); - ret += test_sysfs(); - return ret; - } -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 665d438e..cdb2780d 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -40,17 +40,17 @@ const char default_wwid_1[] = "TEST-WWID-1"; - */ - - --int REAL_FUNC(open)(const char *path, int flags, int mode); -+int REAL_OPEN(const char *path, int flags, int mode); - - static const char _mocked_filename[] = "mocked_path"; - --int WRAP_FUNC(open)(const char *path, int flags, int mode) -+int WRAP_OPEN(const char *path, int flags, int mode) - { - condlog(4, "%s: %s", __func__, path); - - if (!strcmp(path, _mocked_filename)) - return 111; -- return REAL_FUNC(open)(path, flags, mode); -+ return REAL_OPEN(path, flags, mode); - } - - int __wrap_libmp_get_version(int which, unsigned int version[3]) -diff --git a/tests/wrap64.h b/tests/wrap64.h -index b0a4d831..7e434206 100644 ---- a/tests/wrap64.h -+++ b/tests/wrap64.h -@@ -29,6 +29,20 @@ - #define WRAP_FUNC(x) CONCAT2(__wrap_, WRAP_NAME(x)) - #define REAL_FUNC(x) CONCAT2(__real_, WRAP_NAME(x)) - -+/* -+ * With clang, glibc 2.39, and _FILE_OFFSET_BITS==64, -+ * open() resolves to __open64_2(). -+ */ -+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 39) && \ -+ defined(__clang__) && __clang__ == 1 && \ -+ defined(__fortify_use_clang) && __fortify_use_clang == 1 -+#define WRAP_OPEN_NAME __open64_2 -+#else -+#define WRAP_OPEN_NAME WRAP_NAME(open) -+#endif -+#define WRAP_OPEN CONCAT2(__wrap_, WRAP_OPEN_NAME) -+#define REAL_OPEN CONCAT2(__real_, WRAP_OPEN_NAME) -+ - /* - * fcntl() needs special treatment; fcntl64() has been introduced in 2.28. - * https://savannah.gnu.org/forum/forum.php?forum_id=9205 diff --git a/0020-GitHub-actions-fixes-for-spelling-CI.patch b/0020-GitHub-actions-fixes-for-spelling-CI.patch deleted file mode 100644 index 21b74ff..0000000 --- a/0020-GitHub-actions-fixes-for-spelling-CI.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 8 Mar 2024 10:04:39 +0100 -Subject: [PATCH] GitHub actions: fixes for spelling CI - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/patterns.txt | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt -index 57767ea1..858faee6 100644 ---- a/.github/actions/spelling/patterns.txt -+++ b/.github/actions/spelling/patterns.txt -@@ -22,6 +22,7 @@ - \bdmmp_pgs\b - \bdmmp_mpath_kdev_name_get\b - \bfast_io_fail_tmo\b -+\bLimitRTPRIO\b - \bmax_fds\b - \bmissing_uev_wait_timeout\b - \bMPATH_MAX_PARAM_LEN\b -@@ -86,6 +87,7 @@ - \bprin_resvdescr\b - \bprout_param_descriptor\b - \brq_servact\b -+\bSCHED_RT_PRIO\b - \bssize_t\b - \btrnptid_list\b - \buxsock_timeout\b diff --git a/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch b/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch deleted file mode 100644 index 59cdd0e..0000000 --- a/0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 27 Feb 2024 09:57:47 +0100 -Subject: [PATCH] GitHub workflows: run workflows if workflow file has changed - -We want to run workflows if the workflow file itself has changed. - -Fixes: 2cbe81a ("GitHub Workflows: run expensive workflows only on relevant changes") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 1 + - .github/workflows/foreign.yaml | 2 ++ - .github/workflows/multiarch-stable.yaml | 2 ++ - .github/workflows/multiarch.yaml | 2 ++ - .github/workflows/native.yaml | 2 ++ - .github/workflows/rolling.yaml | 2 ++ - .github/workflows/spelling.yml | 2 ++ - 7 files changed, 13 insertions(+) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 53382420..393322e5 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -5,6 +5,7 @@ on: - - queue - - abi - paths: -+ - '.github/workflows/abi.yaml' - - '**.h' - - '**.c' - pull_request: -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 92f6d17a..a62ae009 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/foreign.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/foreign.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml -index 45b74c51..e51d383c 100644 ---- a/.github/workflows/multiarch-stable.yaml -+++ b/.github/workflows/multiarch-stable.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/multiarch-stable.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/multiarch-stable.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml -index b4dec9c7..7b762e5c 100644 ---- a/.github/workflows/multiarch.yaml -+++ b/.github/workflows/multiarch.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/multiarch.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/multiarch.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 09133c1e..0ef9df94 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/native.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/native.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml -index 1f1507ee..3536b944 100644 ---- a/.github/workflows/rolling.yaml -+++ b/.github/workflows/rolling.yaml -@@ -6,6 +6,7 @@ on: - - queue - - tip - paths: -+ - '.github/workflows/rolling.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -@@ -15,6 +16,7 @@ on: - - master - - queue - paths: -+ - '.github/workflows/rolling.yaml' - - '**.h' - - '**.c' - - '**Makefile*' -diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml -index 0416fa9e..7943ebb8 100644 ---- a/.github/workflows/spelling.yml -+++ b/.github/workflows/spelling.yml -@@ -63,7 +63,9 @@ on: - tags-ignore: - - "**" - paths: -+ - '.github/workflows/spelling.yml' - - 'README*' -+ - 'NEWS.md' - - '**.3' - - '**.5' - - '**.8' diff --git a/0022-multipath-tools-add-TGTDIR-option.patch b/0022-multipath-tools-add-TGTDIR-option.patch deleted file mode 100644 index d26fb18..0000000 --- a/0022-multipath-tools-add-TGTDIR-option.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 14:44:45 +0200 -Subject: [PATCH] multipath-tools: add TGTDIR option - -TGTDIR is a convenience option for developers for building multipath-tools such -that compiled-in paths of the plugins, config files, etc. match an -installation under some optional path. See README.md for instructions and -examples. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 2 ++ - Makefile.inc | 8 +++---- - README.md | 33 +++++++++++++++++++++++++++++ - 3 files changed, 39 insertions(+), 4 deletions(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 5906403d..fc9f22f8 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -167,6 +167,7 @@ retrigger - rhabarber - rootprefix - rootprefixdir -+rpmbuild - rport - rtpi - sas -@@ -200,6 +201,7 @@ tcp - TESTDEPS - testname - tgill -+TGTDIR - TIDS - tmo - tpg -diff --git a/Makefile.inc b/Makefile.inc -index 5668e638..81b86cd8 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -101,9 +101,9 @@ WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implici - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) - CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ - -D_FILE_OFFSET_BITS=64 \ -- -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" \ -- -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(configdir)\" \ -- -DDEFAULT_CONFIGFILE=\"$(configfile)\" -DSTATE_DIR=\"$(statedir)\" \ -+ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ -+ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ -+ -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ - -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP - CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe - BIN_CFLAGS := -fPIE -DPIE -@@ -149,4 +149,4 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version) - - %: %.in - @echo creating $@ -- $(Q)sed 's:@CONFIGFILE@:'$(configfile)':g;s:@CONFIGDIR@:'$(configdir)':g;s:@STATE_DIR@:'$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ -+ $(Q)sed 's:@CONFIGFILE@:'$(TGTDIR)$(configfile)':g;s:@CONFIGDIR@:'$(TGTDIR)$(configdir)':g;s:@STATE_DIR@:'$(TGTDIR)$(statedir)':g;s:@RUNTIME_DIR@:'$(runtimedir)':g;s/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g;s:@BINDIR@:'$(bindir)':g' $< >$@ -diff --git a/README.md b/README.md -index d4f35f57..7207b14c 100644 ---- a/README.md -+++ b/README.md -@@ -151,6 +151,39 @@ sufficient control. See `Makefile.inc` for even more fine-grained control. - On such distributions, override `unitdir` and `libudevdir` to use systemd's - `rootprefix`: `make libudevdir=/lib/udev unitdir=/lib/systemd/system` - -+### prefix, DESTDIR and TGTDIR -+ -+`prefix` and related variables are included in compiled-in paths like -+`plugindir` and are used by `make install`. Using `prefix` is useful if -+multipath-tools is built locally on the same host where it's supposed to be -+installed. -+ -+By convention, the `DESTDIR` variable is prepended to all paths by `make -+install`, but not to any compiled-in paths. -+It is useful if the software is built on one system (build host) but intended -+to be run on another system (installation host). This is typically used in build -+systems like *rpmbuild* to set a root directory for all the installed -+files. -+ -+On the contrary, the `TGTDIR` variable is used for compiled-in paths only, and -+ignored by `make install`. It is useful for running multipath-tools in a separate -+subdirectory in the installation host, mostly for testing / development -+purposes. -+ -+For example, -+ -+ make prefix=/opt DESTDIR=/build TGTDIR=/test install -+ -+will install plugins into `/build/opt/lib64/multipath` on the build -+host. On the installation host, the plugins will be expected to be found under -+`/test/opt/lib64/multipath`. If the developer runs -+ -+ rsync -a $BUILD_HOST:$DESTDIR/ $INSTALL_HOST:$TGTDIR/ -+ -+and adds `$TGTDIR/lib64` to `LD_LIBRARY_PATH` on the installation host, the -+multipath binaries installed under `$TGTDIR` will find their plugins and -+configuration files in the expected compiled-in paths. -+ - ### Compiler Options - - Use `OPTFLAGS` to change optimization-related compiler options; diff --git a/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch b/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch deleted file mode 100644 index b59f879..0000000 --- a/0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 17:18:18 +0200 -Subject: [PATCH] libmultipath: move get_udev_for_mpp to sysfs.c - -No functional changes, just code movement. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 20 -------------------- - libmultipath/sysfs.c | 19 +++++++++++++++++++ - libmultipath/sysfs.h | 4 ++++ - 3 files changed, 23 insertions(+), 20 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 4ecf6ba4..89ac03d5 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -453,26 +453,6 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) - return r; - } - --static struct udev_device * --get_udev_for_mpp(const struct multipath *mpp) --{ -- dev_t devnum; -- struct udev_device *udd; -- -- if (!mpp || !has_dm_info(mpp)) { -- condlog(1, "%s called with empty mpp", __func__); -- return NULL; -- } -- -- devnum = makedev(mpp->dmi.major, mpp->dmi.minor); -- udd = udev_device_new_from_devnum(udev, 'b', devnum); -- if (!udd) { -- condlog(1, "failed to get udev device for %s", mpp->alias); -- return NULL; -- } -- return udd; --} -- - void trigger_partitions_udev_change(struct udev_device *dev, - const char *action, int len) - { -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 328951ed..afe9de91 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -339,3 +339,22 @@ bool sysfs_is_multipathed(struct path *pp, bool set_wwid) - - return found; - } -+ -+struct udev_device *get_udev_for_mpp(const struct multipath *mpp) -+{ -+ dev_t devnum; -+ struct udev_device *udd; -+ -+ if (!mpp || !has_dm_info(mpp)) { -+ condlog(1, "%s called with empty mpp", __func__); -+ return NULL; -+ } -+ -+ devnum = makedev(mpp->dmi.major, mpp->dmi.minor); -+ udd = udev_device_new_from_devnum(udev, 'b', devnum); -+ if (!udd) { -+ condlog(1, "failed to get udev device for %s", mpp->alias); -+ return NULL; -+ } -+ return udd; -+} -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index 2db86bd6..3be3f665 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -39,4 +39,8 @@ do { \ - int sysfs_get_size (struct path *pp, unsigned long long * size); - int sysfs_check_holders(char * check_devt, char * new_devt); - bool sysfs_is_multipathed(struct path *pp, bool set_wwid); -+ -+struct multipath; -+struct udev_device *get_udev_for_mpp(const struct multipath *mpp); -+ - #endif diff --git a/0024-libmultipath-add-mp_find_path_by_devt.patch b/0024-libmultipath-add-mp_find_path_by_devt.patch deleted file mode 100644 index 8a85be2..0000000 --- a/0024-libmultipath-add-mp_find_path_by_devt.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 14:57:33 +0200 -Subject: [PATCH] libmultipath: add mp_find_path_by_devt() - -A helper function that searches a struct multipath by dev_t, and -works whether or not mpp->paths is currently available. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.c | 19 +++++++++++++++++++ - libmultipath/structs.h | 3 +++ - 2 files changed, 22 insertions(+) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 74e31a13..e248fb51 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -526,6 +526,25 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t) - return NULL; - } - -+struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt) -+{ -+ struct path *pp; -+ struct pathgroup *pgp; -+ unsigned int i, j; -+ -+ pp = find_path_by_devt(mpp->paths, devt); -+ if (pp) -+ return pp; -+ -+ vector_foreach_slot (mpp->pg, pgp, i){ -+ vector_foreach_slot (pgp->paths, pp, j){ -+ if (!strcmp(pp->dev_t, devt)) -+ return pp; -+ } -+ } -+ return NULL; -+} -+ - static int do_pathcount(const struct multipath *mpp, const int *states, - unsigned int nr_states) - { -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 734905e2..a25eb9d5 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -568,6 +568,9 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt - struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev); - struct path * first_path (const struct multipath *mpp); - -+struct path *mp_find_path_by_devt(const struct multipath *mpp, const char *devt); -+ -+ - int pathcount (const struct multipath *, int); - int count_active_paths(const struct multipath *); - int count_active_pending_paths(const struct multipath *); diff --git a/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch b/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch deleted file mode 100644 index aaa0e9f..0000000 --- a/0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 11 Apr 2024 17:20:14 +0200 -Subject: [PATCH] Revert "libmultipath: fix max_sectors_kb on adding path" - -This reverts commit bbb77f318ee483292f50a7782aecaecc7e60f727. -Reviewed-by: Benjamin Marzinski - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 89ac03d5..13602f3f 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -575,12 +575,11 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) - ssize_t len; - int i, j, ret, err = 0; - struct udev_device *udd; -- int max_sectors_kb = mpp->max_sectors_kb; -+ int max_sectors_kb; - -- /* by default, do not initialize max_sectors_kb on the device */ -- if (max_sectors_kb == MAX_SECTORS_KB_UNDEF && !is_reload) -+ if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) - return 0; -- /* on reload, re-apply the user tuning on all the path devices */ -+ max_sectors_kb = mpp->max_sectors_kb; - if (is_reload) { - if (!has_dm_info(mpp) && - dm_get_info(mpp->alias, &mpp->dmi) != 0) { diff --git a/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch b/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch deleted file mode 100644 index c82cfe7..0000000 --- a/0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Apr 2024 22:20:46 +0200 -Subject: [PATCH] libmultipath: Only set max_sectors_kb on map creation - -Changing max_sectors_kb on a live map is dangerous. When I/O occurs while the -max_sectors_kb value of a map is larger than that of any of its paths, I/O -errors like this may result: - - blk_insert_cloned_request: over max size limit. (127 > 126) - -This situation must be strictly avoided. The kernel makes sure that the -map's limits match those of the paths when the map is created. But setting -max_sectors_kb on path devices before reloading is dangerous, even if we -read the value from the map's max_sectors_kb beforehand. The reason for -this is that the sysfs value max_sectors_kb is the kernel's max_sectors -divided by 2, and user space has no way to figure out if the kernel-internal -value is odd or even. Thus by writing back the value just read to -max_sectors_kb, one might actually decrease the kernel value by one. - -The only safe way to set max_sectors_kb on a live map would be to suspend -it, flushing all outstanding IO, then the path max_sectors_kb, reload, -and resume. - -Since commit 8fd4868 ("libmultipath: don't set max_sectors_kb on reloads"), -we don't set the configured max_sectors_kb any more. But as shown above, -this is not safe. So really only set max_sectors_kb when creating a map. - -Users who have stacked block devices on top of multipath, as described in the -commit message of 8fd4868 must make sure that the max_sectors_kb setting is -correct when the multipath map is first created. Decreasing the map's -max_sectors_kb value (without touching the paths) should actually be possible -in this situation, because stacked block devices are usually bio-based, and -bio-based IO (in contrast to request-based) can be split if the lower-level -device has can't handle the size of the I/O. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 38 ++++---------------------------------- - 1 file changed, 4 insertions(+), 34 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 13602f3f..8cbb2a88 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -566,46 +566,18 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) - mpp->needs_paths_uevent = 0; - } - --static int --sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) -+static int sysfs_set_max_sectors_kb(struct multipath *mpp) - { - struct pathgroup * pgp; - struct path *pp; - char buff[11]; - ssize_t len; - int i, j, ret, err = 0; -- struct udev_device *udd; -- int max_sectors_kb; - - if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF) - return 0; -- max_sectors_kb = mpp->max_sectors_kb; -- if (is_reload) { -- if (!has_dm_info(mpp) && -- dm_get_info(mpp->alias, &mpp->dmi) != 0) { -- condlog(1, "failed to get dm info for %s", mpp->alias); -- return 1; -- } -- udd = get_udev_for_mpp(mpp); -- if (!udd) { -- condlog(1, "failed to get udev device to set max_sectors_kb for %s", mpp->alias); -- return 1; -- } -- ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, -- sizeof(buff)); -- udev_device_unref(udd); -- if (!sysfs_attr_value_ok(ret, sizeof(buff))) { -- condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); -- return 1; -- } -- if (sscanf(buff, "%u\n", &max_sectors_kb) != 1) { -- condlog(1, "can't parse current max_sectors_kb from %s", -- mpp->alias); -- return 1; -- } -- } -- snprintf(buff, 11, "%d", max_sectors_kb); -- len = strlen(buff); -+ -+ len = snprintf(buff, sizeof(buff), "%d", mpp->max_sectors_kb); - - vector_foreach_slot (mpp->pg, pgp, i) { - vector_foreach_slot(pgp->paths, pp, j) { -@@ -923,7 +895,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - return DOMAP_RETRY; - } - -- sysfs_set_max_sectors_kb(mpp, 0); -+ sysfs_set_max_sectors_kb(mpp); - if (is_daemon && mpp->ghost_delay > 0 && count_active_paths(mpp) && - pathcount(mpp, PATH_UP) == 0) - mpp->ghost_delay_tick = mpp->ghost_delay; -@@ -934,7 +906,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - - case ACT_RELOAD: - case ACT_RELOAD_RENAME: -- sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; - r = dm_addmap_reload(mpp, params, 0); -@@ -942,7 +913,6 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - - case ACT_RESIZE: - case ACT_RESIZE_RENAME: -- sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; - r = dm_addmap_reload(mpp, params, 1); diff --git a/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch b/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch deleted file mode 100644 index a4389df..0000000 --- a/0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 16 Apr 2024 23:59:03 +0200 -Subject: [PATCH] libmultipath: set max_sectors_kb in adopt_paths() - -As explained in the previous commit, setting max_sectors_kb for -paths that are members of a live map is dangerous. But as long as -a path is not a member of a map, setting max_sectors_kb poses no risk. -Set the parameter in adopt_paths(), for paths that aren't members -of the map yet. In order to determine whether or not a path is currently -member of the map, adopt_paths() needs to passed the current member list. If -(and only if) it's called from coalesce_paths(), the passed struct multipath -doesn not represent the current state of the map; adopt_paths() must therefore -get a new argument current_mpp that represents the kernel state. - -We must still call sysfs_set_max_sectors_kb() from domap() in the ACT_CREATE -case, because when adopt_paths is called from coalesce_paths() for a map that -doesn't exist yet, mpp->max_sectors_kb is not set. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 2 +- - libmultipath/structs_vec.c | 62 ++++++++++++++++++++++++++++++++++---- - libmultipath/structs_vec.h | 6 ++-- - multipathd/main.c | 6 ++-- - tests/Makefile | 2 +- - tests/test-lib.c | 9 +++++- - 6 files changed, 73 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 8cbb2a88..b5c701fa 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1105,7 +1105,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - /* - * at this point, we know we really got a new mp - */ -- mpp = add_map_with_path(vecs, pp1, 0); -+ mpp = add_map_with_path(vecs, pp1, 0, cmpp); - if (!mpp) { - orphan_path(pp1, "failed to create multipath device"); - continue; -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 0fc608c2..c0c5cc90 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -242,7 +242,38 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - return must_reload; - } - --int adopt_paths(vector pathvec, struct multipath *mpp) -+static bool set_path_max_sectors_kb(const struct path *pp, int max_sectors_kb) -+{ -+ char buf[11]; -+ ssize_t len; -+ int ret, current; -+ bool rc = false; -+ -+ if (max_sectors_kb == MAX_SECTORS_KB_UNDEF) -+ return rc; -+ -+ if (sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 -+ || sscanf(buf, "%d\n", ¤t) != 1) -+ current = MAX_SECTORS_KB_UNDEF; -+ if (current == max_sectors_kb) -+ return rc; -+ -+ len = snprintf(buf, sizeof(buf), "%d", max_sectors_kb); -+ ret = sysfs_attr_set_value(pp->udev, "queue/max_sectors_kb", buf, len); -+ if (ret != len) -+ log_sysfs_attr_set_value(3, ret, -+ "failed setting max_sectors_kb on %s", -+ pp->dev); -+ else { -+ condlog(3, "%s: set max_sectors_kb to %d for %s", __func__, -+ max_sectors_kb, pp->dev); -+ rc = true; -+ } -+ return rc; -+} -+ -+int adopt_paths(vector pathvec, struct multipath *mpp, -+ const struct multipath *current_mpp) - { - int i, ret; - struct path * pp; -@@ -285,9 +316,28 @@ int adopt_paths(vector pathvec, struct multipath *mpp) - continue; - } - -- if (!find_path_by_devt(mpp->paths, pp->dev_t) && -- store_path(mpp->paths, pp)) -- goto err; -+ if (!find_path_by_devt(mpp->paths, pp->dev_t)) { -+ -+ if (store_path(mpp->paths, pp)) -+ goto err; -+ /* -+ * Setting max_sectors_kb on live paths is dangerous. -+ * But we can do it here on a path that isn't yet part -+ * of the map. If this value is lower than the current -+ * max_sectors_kb and the map is reloaded, the map's -+ * max_sectors_kb will be safely adjusted by the kernel. -+ * -+ * We must make sure that the path is not part of the -+ * map yet. Normally we can check this in mpp->paths. -+ * But if adopt_paths is called from coalesce_paths, -+ * we need to check the separate struct multipath that -+ * has been obtained from map_discovery(). -+ */ -+ if (!current_mpp || -+ !mp_find_path_by_devt(current_mpp, pp->dev_t)) -+ mpp->need_reload = mpp->need_reload || -+ set_path_max_sectors_kb(pp, mpp->max_sectors_kb); -+ } - - pp->mpp = mpp; - condlog(3, "%s: ownership set to %s", -@@ -693,7 +743,7 @@ find_existing_alias (struct multipath * mpp, - } - - struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, -- int add_vec) -+ int add_vec, const struct multipath *current_mpp) - { - struct multipath * mpp; - struct config *conf = NULL; -@@ -721,7 +771,7 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, - goto out; - mpp->size = pp->size; - -- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || -+ if (adopt_paths(vecs->pathvec, mpp, current_mpp) || pp->mpp != mpp || - find_slot(mpp->paths, pp) == -1) - goto out; - -diff --git a/libmultipath/structs_vec.h b/libmultipath/structs_vec.h -index 3253f1bb..dbc43058 100644 ---- a/libmultipath/structs_vec.h -+++ b/libmultipath/structs_vec.h -@@ -13,7 +13,8 @@ struct vectors { - - void set_no_path_retry(struct multipath *mpp); - --int adopt_paths (vector pathvec, struct multipath * mpp); -+int adopt_paths (vector pathvec, struct multipath *mpp, -+ const struct multipath *current_mpp); - void orphan_path (struct path * pp, const char *reason); - void set_path_removed(struct path *pp); - -@@ -28,7 +29,8 @@ void remove_maps (struct vectors * vecs); - - void sync_map_state (struct multipath *); - struct multipath * add_map_with_path (struct vectors * vecs, -- struct path * pp, int add_vec); -+ struct path * pp, int add_vec, -+ const struct multipath *current_mpp); - void update_queue_mode_del_path(struct multipath *mpp); - void update_queue_mode_add_path(struct multipath *mpp); - int update_multipath_table (struct multipath *mpp, vector pathvec, int flags); -diff --git a/multipathd/main.c b/multipathd/main.c -index dd17d5c3..d8518a92 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -636,7 +636,7 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - - retry: - condlog(4, "%s: updating new map", mpp->alias); -- if (adopt_paths(vecs->pathvec, mpp)) { -+ if (adopt_paths(vecs->pathvec, mpp, NULL)) { - condlog(0, "%s: failed to adopt paths for new map update", - mpp->alias); - retries = -1; -@@ -1231,7 +1231,7 @@ rescan: - if (mpp) { - condlog(4,"%s: adopting all paths for path %s", - mpp->alias, pp->dev); -- if (adopt_paths(vecs->pathvec, mpp) || pp->mpp != mpp || -+ if (adopt_paths(vecs->pathvec, mpp, NULL) || pp->mpp != mpp || - find_slot(mpp->paths, pp) == -1) - goto fail; /* leave path added to pathvec */ - -@@ -1245,7 +1245,7 @@ rescan: - return 0; - } - condlog(4,"%s: creating new map", pp->dev); -- if ((mpp = add_map_with_path(vecs, pp, 1))) { -+ if ((mpp = add_map_with_path(vecs, pp, 1, NULL))) { - mpp->action = ACT_CREATE; - /* - * We don't depend on ACT_CREATE, as domap will -diff --git a/tests/Makefile b/tests/Makefile -index d1d52dde..4005204a 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -45,7 +45,7 @@ dmevents-test_OBJDEPS = $(multipathdir)/devmapper.o - dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu - hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := $(multipathdir)/discovery.o $(multipathdir)/blacklist.o \ -- $(multipathdir)/structs.o $(multipathdir)/propsel.o -+ $(multipathdir)/structs_vec.o $(multipathdir)/structs.o $(multipathdir)/propsel.o - hwtable-test_LIBDEPS := -ludev -lpthread -ldl - blacklist-test_TESTDEPS := test-log.o - blacklist-test_LIBDEPS := -ludev -diff --git a/tests/test-lib.c b/tests/test-lib.c -index cdb2780d..88f35e94 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -152,6 +152,13 @@ int __wrap_sysfs_get_size(struct path *pp, unsigned long long *sz) - return 0; - } - -+int __wrap_sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, -+ const char * value, size_t value_len) -+{ -+ condlog(5, "%s: %s", __func__, value); -+ return value_len; -+} -+ - void *__wrap_udev_device_get_parent_with_subsystem_devtype( - struct udev_device *ud, const char *subsys, char *type) - { -@@ -400,7 +407,7 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp) - /* pathinfo() call in adopt_paths */ - mock_pathinfo(DI_CHECKER|DI_PRIO, &mop); - -- mp = add_map_with_path(vecs, pp, 1); -+ mp = add_map_with_path(vecs, pp, 1, NULL); - assert_ptr_not_equal(mp, NULL); - - /* TBD: mock setup_map() ... */ diff --git a/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch b/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch deleted file mode 100644 index 9b66bbb..0000000 --- a/0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 17:19:43 +0200 -Subject: [PATCH] libmultipath: add wildcard %k for printing max_sectors_kb - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 360308d2..efd5a16a 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -32,6 +32,7 @@ - #include "util.h" - #include "foreign.h" - #include "strbuf.h" -+#include "sysfs.h" - - #define PRINT_PATH_LONG "%w %i %d %D %p %t %T %s %o" - #define PRINT_PATH_INDENT "%i %d %D %t %T %o" -@@ -431,6 +432,27 @@ snprint_multipath_vpd_data(struct strbuf *buff, - return append_strbuf_str(buff, "[undef]"); - } - -+static void cleanup_udev_device(struct udev_device **udd) -+{ -+ if (*udd) -+ udev_device_unref(*udd); -+} -+ -+static int -+snprint_multipath_max_sectors_kb(struct strbuf *buff, const struct multipath *mpp) -+{ -+ char buf[11]; -+ int max_sectors_kb; -+ struct udev_device *udd __attribute__((cleanup(cleanup_udev_device))) -+ = get_udev_for_mpp(mpp); -+ -+ if (!udd || -+ sysfs_attr_get_value(udd, "queue/max_sectors_kb", buf, sizeof(buf)) <= 0 || -+ sscanf(buf, "%d\n", &max_sectors_kb) != 1) -+ return print_strbuf(buff, "n/a"); -+ return print_strbuf(buff, "%d", max_sectors_kb); -+} -+ - /* - * path info printing functions - */ -@@ -790,6 +812,20 @@ snprint_alua_tpg(struct strbuf *buff, const struct path * pp) - return print_strbuf(buff, "0x%04x", pp->tpg_id); - } - -+static int -+snprint_path_max_sectors_kb(struct strbuf *buff, const struct path *pp) -+{ -+ char buf[11]; -+ int max_sectors_kb; -+ -+ if (!pp->udev || -+ sysfs_attr_get_value(pp->udev, "queue/max_sectors_kb", -+ buf, sizeof(buf)) <= 0 || -+ sscanf(buf, "%d\n", &max_sectors_kb) != 1) -+ return print_strbuf(buff, "n/a"); -+ return print_strbuf(buff, "%d", max_sectors_kb); -+} -+ - static const struct multipath_data mpd[] = { - {'n', "name", snprint_name}, - {'w', "uuid", snprint_multipath_uuid}, -@@ -815,6 +851,7 @@ static const struct multipath_data mpd[] = { - {'e', "rev", snprint_multipath_rev}, - {'G', "foreign", snprint_multipath_foreign}, - {'g', "vpd page data", snprint_multipath_vpd_data}, -+ {'k', "max_sectors_kb",snprint_multipath_max_sectors_kb}, - }; - - static const struct path_data pd[] = { -@@ -845,6 +882,7 @@ static const struct path_data pd[] = { - {'I', "init_st", snprint_initialized}, - {'L', "LUN hex", snprint_path_lunhex}, - {'A', "TPG", snprint_alua_tpg}, -+ {'k', "max_sectors_kb",snprint_path_max_sectors_kb}, - }; - - static const struct pathgroup_data pgd[] = { diff --git a/0029-multipath.conf-5-update-documentation-for-max_sector.patch b/0029-multipath.conf-5-update-documentation-for-max_sector.patch deleted file mode 100644 index dcdf164..0000000 --- a/0029-multipath.conf-5-update-documentation-for-max_sector.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 17 Apr 2024 18:59:04 +0200 -Subject: [PATCH] multipath.conf(5): update documentation for max_sectors_kb - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5.in | 33 +++++++++++++++++++++++++++++---- - 1 file changed, 29 insertions(+), 4 deletions(-) - -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index c788c180..b29a75fe 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -1311,11 +1311,36 @@ The default is: \fB0\fR - . - .TP - .B max_sectors_kb --Sets the max_sectors_kb device parameter on all path devices and the multipath --device to the specified value. -+Sets the \fImax_sectors_kb\fR device parameter on some path devices and the multipath -+device to the specified value. \fImax_sectors_kb\fR is the largest I/O size, in units -+of 1024 bytes, that the kernel allows for a single I/O request. For hardware devices -+like SCSI disks, this value is limited by the capabilities of the hardware. -+It is crucial that the value of a multipath map is never higher than the minimum value of -+of all its path devices. This is ensured by the kernel when a multipath map -+is loaded, but manipulating the values of a map or either of its paths while the -+map is live can cause race conditions and I/O errors. Therefore this value is only -+enforced by multipathd when a multipath map is first created, or when a path device -+is added to a map. In both cases, race conditions are avoided by the kernel. - .RS --.TP --The default is: in \fB/sys/block//queue/max_sectors_kb\fR -+.PP -+Setting \fImax_sectors_kb\fR does not guarantee that all path devices will have this -+value set. It is not an error if the value of a path device is higher than that of -+the containing multipath map. It is also not an error if the actual limit of a map is -+lower than the value in \fI@CONFIGFILE@\fR. This can happen if the hardware limits of one -+or more path devices are lower than the configured value. -+.PP -+Normally the kernel and its device drivers take care of the maximum -+I/O size, and administrators do not need to bother about \fImax_sectors_kb\fR. -+But some hardware devices may report incorrect I/O size limits, or other components -+in the environment (e.g. the fabric) may impose constraints that the kernel cannot -+detect. In such cases setting \fImax_sectors_kb\fR makes sense. It should be set when -+maps are first created, and not be changed thereafter. -+If the setting \fBmust\fR be changed for a live map, set the -+value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use -+\fBmultipathd del path \fR and \fBmultipathd add path \fR to -+delete and re-add the same path device. -+.LP -+The default is: \fBundefined\fR. - .RE - . - . diff --git a/0030-multipath-tools-simplify-comment-in-hwtable.patch b/0030-multipath-tools-simplify-comment-in-hwtable.patch deleted file mode 100644 index 59090a7..0000000 --- a/0030-multipath-tools-simplify-comment-in-hwtable.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 28 Apr 2024 01:45:35 +0200 -Subject: [PATCH] multipath-tools: simplify comment in hwtable - -Instead of adding the new 5300 model, replace them with wildcards. - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 640bf347..7aac3f37 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -683,8 +683,8 @@ static struct hwentry default_hw[] = { - .pgfailback = -FAILBACK_IMMEDIATE, - }, - { -- // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 -- // FlashSystem V840/V9000/5000/5100/5200/7200/7300/9100/9200/9200R/9500 -+ // Storwize V5000/V7000 lines / SAN Volume Controller (SVC) -+ // Flex System V7000 / FlashSystem V840/V9000 and 5x00/7x00/9x00 - .vendor = "IBM", - .product = "^2145", - .no_path_retry = NO_PATH_RETRY_QUEUE, diff --git a/0031-multipath-tools-unify-text-in-multipath.conf.5.patch b/0031-multipath-tools-unify-text-in-multipath.conf.5.patch deleted file mode 100644 index b6d9af3..0000000 --- a/0031-multipath-tools-unify-text-in-multipath.conf.5.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 28 Apr 2024 01:45:36 +0200 -Subject: [PATCH] multipath-tools: unify text in multipath.conf.5 - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5.in | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index b29a75fe..c1a19ebb 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -187,7 +187,7 @@ The default is: \fBno\fR - . - .TP - .B multipath_dir --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - . - . - .TP -@@ -277,7 +277,7 @@ The default is: \fBno\fR - . - .TP - .B pg_timeout --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - . - . - .TP -@@ -322,7 +322,7 @@ The default is: \fBID_WWN\fR, for NVMe devices - . - .TP - .B getuid_callout --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - . - . - .TP -@@ -995,7 +995,7 @@ The default is: \fB\fR - . - .TP - .B config_dir --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - .RS - .TP - The compiled-in value is: \fB@CONFIGDIR@\fR -@@ -1295,7 +1295,7 @@ The default is: \fBno\fR - . - .TP - .B disable_changed_wwids --(Deprecated) This option is not supported anymore, and the value is ignored. -+(Deprecated) This option is not supported anymore, and will be ignored. - .RE - . - . -@@ -1340,7 +1340,7 @@ value in \fI@CONFIGFILE@\fR, run \fBmultipathd reconfigure\fR, and use - \fBmultipathd del path \fR and \fBmultipathd add path \fR to - delete and re-add the same path device. - .LP --The default is: \fBundefined\fR. -+The default is: \fB\fR - .RE - . - . diff --git a/0032-multipath-tools-update-man-pages-dates.patch b/0032-multipath-tools-update-man-pages-dates.patch deleted file mode 100644 index c011eac..0000000 --- a/0032-multipath-tools-update-man-pages-dates.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Sun, 28 Apr 2024 01:45:37 +0200 -Subject: [PATCH] multipath-tools: update man pages dates - -Cc: Martin Wilck -Cc: Benjamin Marzinski -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Signed-off-by: Xose Vazquez Perez -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persistent_reserve_in.3 | 2 +- - libmpathpersist/mpath_persistent_reserve_out.3 | 2 +- - multipath/multipath.8.in | 2 +- - multipath/multipath.conf.5.in | 2 +- - multipathd/multipathd.8.in | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/libmpathpersist/mpath_persistent_reserve_in.3 b/libmpathpersist/mpath_persistent_reserve_in.3 -index 6cc35349..4ac43fa3 100644 ---- a/libmpathpersist/mpath_persistent_reserve_in.3 -+++ b/libmpathpersist/mpath_persistent_reserve_in.3 -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MPATH_PERSISTENT_RESERVE_IN 3 2018-06-15 Linux -+.TH MPATH_PERSISTENT_RESERVE_IN 3 2024-02-09 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/libmpathpersist/mpath_persistent_reserve_out.3 b/libmpathpersist/mpath_persistent_reserve_out.3 -index 70e26028..3dbeae1f 100644 ---- a/libmpathpersist/mpath_persistent_reserve_out.3 -+++ b/libmpathpersist/mpath_persistent_reserve_out.3 -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MPATH_PERSISTENT_RESERVE_OUT 3 2018-06-15 Linux -+.TH MPATH_PERSISTENT_RESERVE_OUT 3 2024-02-09 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in -index 348eb220..b88e9a4c 100644 ---- a/multipath/multipath.8.in -+++ b/multipath/multipath.8.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATH 8 2021-11-12 Linux -+.TH MULTIPATH 8 2023-09-08 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index c1a19ebb..46d3685a 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATH.CONF 5 2023-06-15 Linux -+.TH MULTIPATH.CONF 5 2024-04-17 Linux - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index f1cab3ff..12b77156 100644 ---- a/multipathd/multipathd.8.in -+++ b/multipathd/multipathd.8.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATHD 8 2022-09-03 Linux -+.TH MULTIPATHD 8 2023-12-19 Linux - . - . - .\" ---------------------------------------------------------------------------- diff --git a/0033-libmultipath-export-partmap_in_use.patch b/0033-libmultipath-export-partmap_in_use.patch deleted file mode 100644 index 47a6772..0000000 --- a/0033-libmultipath-export-partmap_in_use.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:13 -0400 -Subject: [PATCH] libmultipath: export partmap_in_use - -A future commit will make use of this function - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - libmultipath/devmapper.h | 1 + - libmultipath/libmultipath.version | 1 + - 3 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 4ce7e82f..a87abf7e 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1043,7 +1043,7 @@ has_partmap(const char *name __attribute__((unused)), - return 1; - } - --static int -+int - partmap_in_use(const char *name, void *data) - { - int part_count, *ret_count = (int *)data; -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index a7d66604..93caa2aa 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -57,6 +57,7 @@ enum { - DM_FLUSH_BUSY, - }; - -+int partmap_in_use(const char *name, void *data); - int _dm_flush_map (const char *, int, int, int, int); - int dm_flush_map_nopaths(const char * mapname, int deferred_remove); - #define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 724786d5..e070f296 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -141,6 +141,7 @@ global: - need_io_err_check; - orphan_path; - parse_prkey_flags; -+ partmap_in_use; - pathcount; - path_discovery; - path_get_tpgs; diff --git a/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch b/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch deleted file mode 100644 index 7c36521..0000000 --- a/0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:14 -0400 -Subject: [PATCH] libmultipath: change flush_on_last_del to fix a multipathd - hang - -Commit 9bd3482e ("multipathd: make flush_map() delete maps like the -multipath command") fixed an issue where deleting a queueing multipath -device through multipathd could hang because the multipath device had -outstanding IO, even though the only openers of it at the time of -deletion were the kpartx partition devices. However it is still possible -to hang multipathd, because autoremoving the device when all paths have -been deleted doesn't disable queueing. To reproduce this hang: - -1. create a multipath device with a kpartx partition on top of it and -no_path_retry set to either "queue" or something long enough to run all -the commands in the reproducer before it disables queueing. -2. disable all the paths to the device with something like: - # echo offline > /sys/block//device/state -3. Write directly to the multipath device with something like: - # dd if=/dev/zero of=/dev/mapper/ bs=4K count=1 -4. delete all the paths to the device with something like: - # echo 1 > /sys/block//device/delete - -Multipathd will hang trying to delete the kpartx device because, as the -last opener, it must flush the multipath device before closing it. -Because it hangs holding the vecs_lock, multipathd will never disable -queueing on the device, so it will hang forever, even if no_path_retry -is set to a number. - -This hang can occur, even if deferred_remove is set. Since nothing has -the kpartx device opened, device-mapper does an immediate remove, which -will still hang. This means that even if deferred_remove is set, -multipathd still cannot delete a map while queueing is enabled. It must -either disable queueing or skip the autoremove. - -Mulitpath can currently be configured to avoid this hang by setting - -flush_on_last_del yes - -However there are good reasons why users wouldn't want to set that. They -may need to be able to survive having all paths getting temporarily -deleted. I should note that this is a pretty rare corner case, since -multipath automatically sets dev_loss_tmo so that it should not trigger -before queueing is disabled. - -This commit avoids the hang by changing the possible values for -flush_on_last_del to "never", "unused", and "always", and sets the -default to "unused". "always" works like "yes" did, "never" will not -disable queueing, and "unused" will only disable queueing if nothing has -the kpartx devices or the multipath device open. In order to be safe, if -the device has queue_if_no_paths set (and in case of "unused", the -device is in-use) the autoremove will be skipped. Also, instead of just -trusting the lack of "queue_if_no_paths" in the current mpp->features, -multipathd will tell the kernel to disable queueing, just to be sure it -actually is. - -I chose "unused" as the default because this should generally only cause -multipathd to work differently from the users perspective when nothing -has the multipath device open but it is queueing and there is -outstanding IO. Without this change, it would have hung instead of -failing the outstanding IO. However, I do understand that an argument -could be made that "never" makes more sense as default, even though it -will cause multipathd to skip autoremoves in cases where it wouldn't -before. The change to the behavior of deffered_remove will be -noticeable, but skipping an autoremove is much better than hanging. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/defaults.h | 2 +- - libmultipath/dict.c | 72 +++++++++++++++++++++++++++++++---- - libmultipath/dict.h | 1 + - libmultipath/hwtable.c | 6 +-- - libmultipath/propsel.c | 4 +- - libmultipath/structs.h | 7 ++-- - multipath/multipath.conf.5.in | 20 +++++++--- - multipathd/main.c | 39 +++++++++++++++---- - 8 files changed, 122 insertions(+), 29 deletions(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 64b633f2..ed08c251 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -43,7 +43,7 @@ - #define DEFAULT_PRIO PRIO_CONST - #define DEFAULT_PRIO_ARGS "" - #define DEFAULT_CHECKER TUR --#define DEFAULT_FLUSH FLUSH_DISABLED -+#define DEFAULT_FLUSH FLUSH_UNUSED - #define DEFAULT_USER_FRIENDLY_NAMES USER_FRIENDLY_NAMES_OFF - #define DEFAULT_FORCE_SYNC 0 - #define UNSET_PARTITION_DELIM "/UNSET/" -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 5af036b7..546103f2 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -791,14 +791,70 @@ declare_def_snprint(checker_timeout, print_nonzero) - declare_def_handler(allow_usb_devices, set_yes_no) - declare_def_snprint(allow_usb_devices, print_yes_no) - --declare_def_handler(flush_on_last_del, set_yes_no_undef) --declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH) --declare_ovr_handler(flush_on_last_del, set_yes_no_undef) --declare_ovr_snprint(flush_on_last_del, print_yes_no_undef) --declare_hw_handler(flush_on_last_del, set_yes_no_undef) --declare_hw_snprint(flush_on_last_del, print_yes_no_undef) --declare_mp_handler(flush_on_last_del, set_yes_no_undef) --declare_mp_snprint(flush_on_last_del, print_yes_no_undef) -+ -+static const char * const flush_on_last_del_optvals[] = { -+ [FLUSH_NEVER] = "never", -+ [FLUSH_ALWAYS] = "always", -+ [FLUSH_UNUSED] = "unused", -+}; -+ -+static int -+set_flush_on_last_del(vector strvec, void *ptr, const char *file, int line_nr) -+{ -+ int i; -+ int *flush_val_ptr = (int *)ptr; -+ char *buff; -+ -+ buff = set_value(strvec); -+ if (!buff) -+ return 1; -+ -+ for (i = FLUSH_NEVER; i <= FLUSH_UNUSED; i++) { -+ if (flush_on_last_del_optvals[i] != NULL && -+ !strcmp(buff, flush_on_last_del_optvals[i])) { -+ *flush_val_ptr = i; -+ break; -+ } -+ } -+ -+ if (i > FLUSH_UNUSED) { -+ bool deprecated = true; -+ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) -+ *flush_val_ptr = FLUSH_UNUSED; -+ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) -+ *flush_val_ptr = FLUSH_ALWAYS; -+ else { -+ deprecated = false; -+ condlog(1, "%s line %d, invalid value for flush_on_last_del: \"%s\"", -+ file, line_nr, buff); -+ } -+ if (deprecated) -+ condlog(2, "%s line %d, \"%s\" is a deprecated value for flush_on_last_del and is treated as \"%s\"", -+ file, line_nr, buff, -+ flush_on_last_del_optvals[*flush_val_ptr]); -+ } -+ -+ free(buff); -+ return 0; -+} -+ -+int -+print_flush_on_last_del(struct strbuf *buff, long v) -+{ -+ if (v == FLUSH_UNDEF) -+ return 0; -+ return append_strbuf_quoted(buff, flush_on_last_del_optvals[(int)v]); -+} -+ -+declare_def_handler(flush_on_last_del, set_flush_on_last_del) -+declare_def_snprint_defint(flush_on_last_del, print_flush_on_last_del, -+ DEFAULT_FLUSH) -+declare_ovr_handler(flush_on_last_del, set_flush_on_last_del) -+declare_ovr_snprint(flush_on_last_del, print_flush_on_last_del) -+declare_hw_handler(flush_on_last_del, set_flush_on_last_del) -+declare_hw_snprint(flush_on_last_del, print_flush_on_last_del) -+declare_mp_handler(flush_on_last_del, set_flush_on_last_del) -+declare_mp_snprint(flush_on_last_del, print_flush_on_last_del) - - declare_def_handler(user_friendly_names, set_yes_no_undef) - declare_def_snprint_defint(user_friendly_names, print_yes_no_undef, -diff --git a/libmultipath/dict.h b/libmultipath/dict.h -index 7e2dfbe0..e1794537 100644 ---- a/libmultipath/dict.h -+++ b/libmultipath/dict.h -@@ -18,4 +18,5 @@ int print_undef_off_zero(struct strbuf *buff, long v); - int print_dev_loss(struct strbuf *buff, unsigned long v); - int print_off_int_undef(struct strbuf *buff, long v); - int print_auto_resize(struct strbuf *buff, long v); -+int print_flush_on_last_del(struct strbuf *buff, long v); - #endif /* _DICT_H */ -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 7aac3f37..d1148de7 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -60,7 +60,7 @@ - .no_path_retry = NO_PATH_RETRY_UNDEF, - .minio = 1000, - .minio_rq = 1, -- .flush_on_last_del = FLUSH_DISABLED, -+ .flush_on_last_del = FLUSH_UNUSED, - .user_friendly_names = USER_FRIENDLY_NAMES_OFF, - .fast_io_fail = 5, - .dev_loss = 600, -@@ -829,7 +829,7 @@ static struct hwentry default_hw[] = { - .no_path_retry = NO_PATH_RETRY_QUEUE, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, -- .flush_on_last_del = FLUSH_ENABLED, -+ .flush_on_last_del = FLUSH_ALWAYS, - .dev_loss = MAX_DEV_LOSS_TMO, - .prio_name = PRIO_ONTAP, - .user_friendly_names = USER_FRIENDLY_NAMES_OFF, -@@ -1160,7 +1160,7 @@ static struct hwentry default_hw[] = { - .no_path_retry = NO_PATH_RETRY_FAIL, - .minio = 1, - .minio_rq = 1, -- .flush_on_last_del = FLUSH_ENABLED, -+ .flush_on_last_del = FLUSH_ALWAYS, - .fast_io_fail = 15, - }, - /* -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 44241e2a..e2dcb316 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -963,6 +963,7 @@ out: - int select_flush_on_last_del(struct config *conf, struct multipath *mp) - { - const char *origin; -+ STRBUF_ON_STACK(buff); - - mp_set_mpe(flush_on_last_del); - mp_set_ovr(flush_on_last_del); -@@ -970,8 +971,9 @@ int select_flush_on_last_del(struct config *conf, struct multipath *mp) - mp_set_conf(flush_on_last_del); - mp_set_default(flush_on_last_del, DEFAULT_FLUSH); - out: -+ print_flush_on_last_del(&buff, mp->flush_on_last_del); - condlog(3, "%s: flush_on_last_del = %s %s", mp->alias, -- (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin); -+ get_strbuf_str(&buff), origin); - return 0; - } - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a25eb9d5..dbaf4d43 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -109,9 +109,10 @@ enum marginal_pathgroups_mode { - }; - - enum flush_states { -- FLUSH_UNDEF = YNU_UNDEF, -- FLUSH_DISABLED = YNU_NO, -- FLUSH_ENABLED = YNU_YES, -+ FLUSH_UNDEF, -+ FLUSH_NEVER, -+ FLUSH_ALWAYS, -+ FLUSH_UNUSED, - }; - - enum log_checker_err_states { -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 46d3685a..1d3d53bb 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -707,12 +707,22 @@ The default is: \fBno\fR - .TP - .B flush_on_last_del - If set to --.I yes -+.I always - , multipathd will disable queueing when the last path to a device has been --deleted. --.RS --.TP --The default is: \fBno\fR -+deleted. If set to -+.I never -+, multipathd will not disable queueing when the last path to a device has -+been deleted. Since multipath cannot safely remove a device while queueing -+is enabled, setting this to \fInever\fR means that multipathd will not -+automatically remove an unused multipath device whose paths are all deleted if -+it is currently set to queue_if_no_path. If set to -+.I unused -+, multipathd will only disable queueing when the last path is removed if -+nothing currently has the multipath device or any of the kpartx partition -+devices on top of it open. -+.RS -+.TP -+The default is: \fBunused\fR - .RE - . - . -diff --git a/multipathd/main.c b/multipathd/main.c -index d8518a92..09286dd0 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -584,19 +584,42 @@ int update_multipath (struct vectors *vecs, char *mapname) - static bool - flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { - int r; -+ bool is_queueing = true; - -+ if (mpp->features) -+ is_queueing = strstr(mpp->features, "queue_if_no_path"); -+ -+ /* It's not safe to do a remove of a map that has "queue_if_no_path" -+ * set, since there could be outstanding IO which will cause -+ * multipathd to hang while attempting the remove */ -+ if (mpp->flush_on_last_del == FLUSH_NEVER && is_queueing) { -+ condlog(2, "%s: map is queueing, can't remove", mpp->alias); -+ return false; -+ } -+ if (mpp->flush_on_last_del == FLUSH_UNUSED && -+ partmap_in_use(mpp->alias, NULL) && is_queueing) { -+ condlog(2, "%s: map in use and queueing, can't remove", -+ mpp->alias); -+ return false; -+ } - /* -- * flush_map will fail if the device is open -+ * This will flush FLUSH_NEVER devices and FLUSH_UNUSED devices -+ * that are in use, but only if they are already marked as not -+ * queueing. That is just to make absolutely certain that they -+ * really are not queueing, like they claim. - */ -- if (mpp->flush_on_last_del == FLUSH_ENABLED) { -- condlog(2, "%s Last path deleted, disabling queueing", -+ condlog(is_queueing ? 2 : 3, "%s Last path deleted, disabling queueing", -+ mpp->alias); -+ mpp->retry_tick = 0; -+ mpp->no_path_retry = NO_PATH_RETRY_FAIL; -+ mpp->disable_queueing = 1; -+ mpp->stat_map_failures++; -+ if (dm_queue_if_no_path(mpp, 0) != 0) { -+ condlog(0, "%s: failed to disable queueing. Not removing", - mpp->alias); -- mpp->retry_tick = 0; -- mpp->no_path_retry = NO_PATH_RETRY_FAIL; -- mpp->disable_queueing = 1; -- mpp->stat_map_failures++; -- dm_queue_if_no_path(mpp, 0); -+ return false; - } -+ - r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove); - if (r != DM_FLUSH_OK) { - if (r == DM_FLUSH_DEFERRED) { diff --git a/0035-libmultipath-remove-redundant-config-option-from-Inf.patch b/0035-libmultipath-remove-redundant-config-option-from-Inf.patch deleted file mode 100644 index 8de5639..0000000 --- a/0035-libmultipath-remove-redundant-config-option-from-Inf.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:15 -0400 -Subject: [PATCH] libmultipath: remove redundant config option from InfiniBox - config - -The InfiniBox config already sets no_path_retry to "fail", so it won't -ever queue IO. That means setting flush_on_last_del to "always" is -redundant, since queueing is always disabled. Remove the -flush_on_last_del parameter, to make it easier for users to override the -default behavior if desired. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index d1148de7..9e008df6 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -1160,7 +1160,6 @@ static struct hwentry default_hw[] = { - .no_path_retry = NO_PATH_RETRY_FAIL, - .minio = 1, - .minio_rq = 1, -- .flush_on_last_del = FLUSH_ALWAYS, - .fast_io_fail = 15, - }, - /* diff --git a/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch b/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch deleted file mode 100644 index f61f658..0000000 --- a/0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:16 -0400 -Subject: [PATCH] libmultipath: pad dev_loss_tmo to avoid race with - no_path_retry - -Currently multipath makes sure that dev_loss_tmo is at least as long as -the configured no path queueing time. The goal is to make sure that path -devices aren't removed while the multipath device is still queueing in -hopes that they will become usable again. - -This is racy. Multipathd may take longer to check the paths than -configured. If strict_timing isn't set, it will definitely take longer. -To account for this, pad the minimum dev_loss_tmo value by five seconds -(one default checker interval) plus one second per minute of no path -queueing time. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 6fd4dabb..e2052422 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -901,6 +901,11 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) - uint64_t no_path_retry_tmo = - (uint64_t)mpp->no_path_retry * conf->checkint; - -+ /* pad no_path_retry_tmo by one standard check interval -+ * plus one second per minute to account for timing -+ * issues with the rechecks */ -+ no_path_retry_tmo += no_path_retry_tmo / 60 + DEFAULT_CHECKINT; -+ - if (no_path_retry_tmo > MAX_DEV_LOSS_TMO) - min_dev_loss = MAX_DEV_LOSS_TMO; - else diff --git a/0037-libmultipath-fix-deferred_remove-function-arguments.patch b/0037-libmultipath-fix-deferred_remove-function-arguments.patch deleted file mode 100644 index 507a056..0000000 --- a/0037-libmultipath-fix-deferred_remove-function-arguments.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Apr 2024 19:35:17 -0400 -Subject: [PATCH] libmultipath: fix deferred_remove function arguments - -Aside from one version of dm_flush_map_nopaths(), all the callers of -_dm_flush_map() and dm_simplecmd() set deferred_remove to 0. But these -functions, as well as some helper functions they called, all treated the -deferred_remove argument as an enum deferred_remove_states, and called -do_deferred() to see if the remove should be deferred. To simplify the -code, make these functions treat deferred_remove as a boolean value -signifying whether a remove is deferred, and make dm_flush_map_nopaths() -do the work of checking if the remove should be deferred. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -Reviewed-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 19 +++++++++---------- - libmultipath/libmultipath.version | 2 +- - 2 files changed, 10 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index a87abf7e..2e7b2c64 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -386,8 +386,6 @@ libmp_dm_task_create(int task) - return dm_task_create(task); - } - --#define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS) -- - static int - dm_simplecmd (int task, const char *name, int no_flush, int need_sync, - uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { -@@ -411,7 +409,7 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, - dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ - #endif - #ifdef LIBDM_API_DEFERRED -- if (do_deferred(deferred_remove)) -+ if (deferred_remove) - dm_task_deferred_remove(dmt); - #endif - if (udev_wait_flag && -@@ -1082,7 +1080,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - - /* If you aren't doing a deferred remove, make sure that no - * devices are in use */ -- if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL)) -+ if (!deferred_remove && partmap_in_use(mapname, NULL)) - return DM_FLUSH_BUSY; - - if (need_suspend && -@@ -1100,7 +1098,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) - return r; - -- if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) { -+ if (!deferred_remove && dm_get_opencount(mapname)) { - condlog(2, "%s: map in use", mapname); - return DM_FLUSH_BUSY; - } -@@ -1112,8 +1110,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - r = dm_device_remove(mapname, need_sync, deferred_remove); - - if (r) { -- if (do_deferred(deferred_remove) -- && dm_map_present(mapname)) { -+ if (deferred_remove && dm_map_present(mapname)) { - condlog(4, "multipath map %s remove deferred", - mapname); - return DM_FLUSH_DEFERRED; -@@ -1147,7 +1144,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - int - dm_flush_map_nopaths(const char * mapname, int deferred_remove) - { -- return _dm_flush_map(mapname, 1, deferred_remove, 0, 0); -+ return _dm_flush_map(mapname, 1, -+ (deferred_remove == DEFERRED_REMOVE_ON || -+ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), -+ 0, 0); - } - - #else -@@ -1539,8 +1539,7 @@ remove_partmap(const char *name, void *data) - - if (dm_get_opencount(name)) { - dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); -- if (!do_deferred(rd->deferred_remove) && -- dm_get_opencount(name)) { -+ if (rd->deferred_remove && dm_get_opencount(name)) { - condlog(2, "%s: map in use", name); - return DM_FLUSH_BUSY; - } -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index e070f296..eb511749 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 { - put_multipath_config; - }; - --LIBMULTIPATH_23.0.0 { -+LIBMULTIPATH_24.0.0 { - global: - /* symbols referenced by multipath and multipathd */ - add_foreign; diff --git a/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch b/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch deleted file mode 100644 index ef922ec..0000000 --- a/0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 May 2024 18:38:24 +0200 -Subject: [PATCH] libmultipath: use bitwise flags for map flushing API - -Rather than passing 3 separate bool variables to _dm_flush_map(), -define bitwise flags to modify the function's behavior, and pass -these flags to called functions accordingly. - -This improves the readability of the code, function calls are -more expressive. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 68 +++++++++++++++++----------------------- - libmultipath/devmapper.h | 18 ++++++++--- - 2 files changed, 41 insertions(+), 45 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 2e7b2c64..a6a9c2b7 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -53,9 +53,8 @@ static int dm_cancel_remove_partmaps(const char * mapname); - #define __DR_UNUSED__ __attribute__((unused)) - #endif - --static int dm_remove_partmaps (const char * mapname, int need_sync, -- int deferred_remove); --static int do_foreach_partmaps(const char * mapname, -+static int dm_remove_partmaps (const char *mapname, int flags); -+static int do_foreach_partmaps(const char *mapname, - int (*partmap_func)(const char *, void *), - void *data); - static int _dm_queue_if_no_path(const char *mapname, int enable); -@@ -439,9 +438,9 @@ int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) - } - - static int --dm_device_remove (const char *name, int needsync, int deferred_remove) { -- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0, -- deferred_remove); -+dm_device_remove (const char *name, int flags) { -+ return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, -+ flags & DMFL_DEFERRED); - } - - static int -@@ -1061,8 +1060,7 @@ partmap_in_use(const char *name, void *data) - return 0; - } - --int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, -- int need_suspend, int retries) -+int _dm_flush_map (const char *mapname, int flags, int retries) - { - int r; - int queue_if_no_path = 0; -@@ -1080,10 +1078,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - - /* If you aren't doing a deferred remove, make sure that no - * devices are in use */ -- if (!deferred_remove && partmap_in_use(mapname, NULL)) -+ if (!(flags & DMFL_DEFERRED) && partmap_in_use(mapname, NULL)) - return DM_FLUSH_BUSY; - -- if (need_suspend && -+ if ((flags & DMFL_SUSPEND) && - dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK && - strstr(params, "queue_if_no_path")) { - if (!_dm_queue_if_no_path(mapname, 0)) -@@ -1095,22 +1093,22 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - free(params); - params = NULL; - -- if ((r = dm_remove_partmaps(mapname, need_sync, deferred_remove))) -+ if ((r = dm_remove_partmaps(mapname, flags))) - return r; - -- if (!deferred_remove && dm_get_opencount(mapname)) { -+ if (!(flags & DMFL_DEFERRED) && dm_get_opencount(mapname)) { - condlog(2, "%s: map in use", mapname); - return DM_FLUSH_BUSY; - } - - do { -- if (need_suspend && queue_if_no_path != -1) -+ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) - dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0); - -- r = dm_device_remove(mapname, need_sync, deferred_remove); -+ r = dm_device_remove(mapname, flags); - - if (r) { -- if (deferred_remove && dm_map_present(mapname)) { -+ if ((flags & DMFL_DEFERRED) && dm_map_present(mapname)) { - condlog(4, "multipath map %s remove deferred", - mapname); - return DM_FLUSH_DEFERRED; -@@ -1124,7 +1122,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - } else { - condlog(2, "failed to remove multipath map %s", - mapname); -- if (need_suspend && queue_if_no_path != -1) { -+ if ((flags & DMFL_SUSPEND) && queue_if_no_path != -1) { - dm_simplecmd_noflush(DM_DEVICE_RESUME, - mapname, udev_flags); - } -@@ -1139,27 +1137,18 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - return DM_FLUSH_FAIL; - } - --#ifdef LIBDM_API_DEFERRED -- - int --dm_flush_map_nopaths(const char * mapname, int deferred_remove) -+dm_flush_map_nopaths(const char *mapname, int deferred_remove __DR_UNUSED__) - { -- return _dm_flush_map(mapname, 1, -- (deferred_remove == DEFERRED_REMOVE_ON || -- deferred_remove == DEFERRED_REMOVE_IN_PROGRESS), -- 0, 0); --} -- --#else -- --int --dm_flush_map_nopaths(const char * mapname, -- int deferred_remove __attribute__((unused))) --{ -- return _dm_flush_map(mapname, 1, 0, 0, 0); --} -+ int flags = DMFL_NEED_SYNC; - -+#ifdef LIBDM_API_DEFERRED -+ flags |= ((deferred_remove == DEFERRED_REMOVE_ON || -+ deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) ? -+ DMFL_DEFERRED : 0); - #endif -+ return _dm_flush_map(mapname, flags, 0); -+} - - int dm_flush_maps (int retries) - { -@@ -1528,8 +1517,7 @@ out: - } - - struct remove_data { -- int need_sync; -- int deferred_remove; -+ int flags; - }; - - static int -@@ -1538,21 +1526,21 @@ remove_partmap(const char *name, void *data) - struct remove_data *rd = (struct remove_data *)data; - - if (dm_get_opencount(name)) { -- dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); -- if (rd->deferred_remove && dm_get_opencount(name)) { -+ dm_remove_partmaps(name, rd->flags); -+ if ((rd->flags & DMFL_DEFERRED) && dm_get_opencount(name)) { - condlog(2, "%s: map in use", name); - return DM_FLUSH_BUSY; - } - } - condlog(4, "partition map %s removed", name); -- dm_device_remove(name, rd->need_sync, rd->deferred_remove); -+ dm_device_remove(name, rd->flags); - return DM_FLUSH_OK; - } - - static int --dm_remove_partmaps (const char * mapname, int need_sync, int deferred_remove) -+dm_remove_partmaps (const char * mapname, int flags) - { -- struct remove_data rd = { need_sync, deferred_remove }; -+ struct remove_data rd = { flags }; - return do_foreach_partmaps(mapname, remove_partmap, &rd); - } - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 93caa2aa..bb4a55a6 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -58,12 +58,20 @@ enum { - }; - - int partmap_in_use(const char *name, void *data); --int _dm_flush_map (const char *, int, int, int, int); --int dm_flush_map_nopaths(const char * mapname, int deferred_remove); --#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0) --#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0, 0, 0, 0) -+ -+enum { -+ DMFL_NONE = 0, -+ DMFL_NEED_SYNC = 1 << 0, -+ DMFL_DEFERRED = 1 << 1, -+ DMFL_SUSPEND = 1 << 2, -+}; -+ -+int _dm_flush_map (const char *mapname, int flags, int retries); -+#define dm_flush_map(mapname) _dm_flush_map(mapname, DMFL_NEED_SYNC, 0) -+#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, DMFL_NONE, 0) - #define dm_suspend_and_flush_map(mapname, retries) \ -- _dm_flush_map(mapname, 1, 0, 1, retries) -+ _dm_flush_map(mapname, DMFL_NEED_SYNC|DMFL_SUSPEND, retries) -+int dm_flush_map_nopaths(const char * mapname, int deferred_remove); - int dm_cancel_deferred_remove(struct multipath *mpp); - int dm_flush_maps (int retries); - int dm_fail_path(const char * mapname, char * path); diff --git a/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch b/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch deleted file mode 100644 index 1aee878..0000000 --- a/0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 May 2024 18:45:17 +0200 -Subject: [PATCH] libmultipath: use bitwise flags for dm_simplecmd API - -Also use bitwise flags for dm_simplecmd() and its relatives. Again, -this makes the code more expressive and more readable, while -simplifying the function calls. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 26 +++++++++++++------------- - libmultipath/devmapper.h | 5 +++-- - 2 files changed, 16 insertions(+), 15 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index a6a9c2b7..08bb3c51 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -386,10 +386,9 @@ libmp_dm_task_create(int task) - } - - static int --dm_simplecmd (int task, const char *name, int no_flush, int need_sync, -- uint16_t udev_flags, int deferred_remove __DR_UNUSED__) { -+dm_simplecmd (int task, const char *name, int flags, uint16_t udev_flags) { - int r = 0; -- int udev_wait_flag = ((need_sync || udev_flags) && -+ int udev_wait_flag = (((flags & DMFL_NEED_SYNC) || udev_flags) && - (task == DM_DEVICE_RESUME || - task == DM_DEVICE_REMOVE)); - uint32_t cookie = 0; -@@ -404,11 +403,11 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, - dm_task_no_open_count(dmt); - dm_task_skip_lockfs(dmt); /* for DM_DEVICE_RESUME */ - #ifdef LIBDM_API_FLUSH -- if (no_flush) -+ if (flags & DMFL_NO_FLUSH) - dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ - #endif - #ifdef LIBDM_API_DEFERRED -- if (deferred_remove) -+ if (flags & DMFL_DEFERRED) - dm_task_deferred_remove(dmt); - #endif - if (udev_wait_flag && -@@ -429,18 +428,17 @@ out: - - int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags) - { -- return dm_simplecmd(task, name, 0, 1, udev_flags, 0); -+ return dm_simplecmd(task, name, DMFL_NEED_SYNC, udev_flags); - } - - int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) - { -- return dm_simplecmd(task, name, 1, 1, udev_flags, 0); -+ return dm_simplecmd(task, name, DMFL_NO_FLUSH|DMFL_NEED_SYNC, udev_flags); - } - - static int - dm_device_remove (const char *name, int flags) { -- return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, flags & DMFL_NEED_SYNC, 0, -- flags & DMFL_DEFERRED); -+ return dm_simplecmd(DM_DEVICE_REMOVE, name, flags, 0); - } - - static int -@@ -594,8 +592,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) - params, ADDMAP_RO, 0); - } - if (r) -- r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, -- 1, udev_flags, 0); -+ r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, -+ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), -+ udev_flags); - if (r) - return r; - -@@ -603,8 +602,9 @@ int dm_addmap_reload(struct multipath *mpp, char *params, int flush) - * drop the new table, so doing a second resume will try using - * the original table */ - if (dm_is_suspended(mpp->alias)) -- dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, !flush, 1, -- udev_flags, 0); -+ dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, -+ DMFL_NEED_SYNC | (flush ? 0 : DMFL_NO_FLUSH), -+ udev_flags); - return 0; - } - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index bb4a55a6..a242381e 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -38,8 +38,8 @@ void skip_libmp_dm_init(void); - void libmp_dm_exit(void); - void libmp_udev_set_sync_support(int on); - struct dm_task *libmp_dm_task_create(int task); --int dm_simplecmd_flush (int, const char *, uint16_t); --int dm_simplecmd_noflush (int, const char *, uint16_t); -+int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); -+int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params, int flush); - int dm_map_present (const char *); -@@ -64,6 +64,7 @@ enum { - DMFL_NEED_SYNC = 1 << 0, - DMFL_DEFERRED = 1 << 1, - DMFL_SUSPEND = 1 << 2, -+ DMFL_NO_FLUSH = 1 << 3, - }; - - int _dm_flush_map (const char *mapname, int flags, int retries); diff --git a/0040-libmultipath-add-argument-names-to-some-prototypes.patch b/0040-libmultipath-add-argument-names-to-some-prototypes.patch deleted file mode 100644 index 3244d55..0000000 --- a/0040-libmultipath-add-argument-names-to-some-prototypes.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 May 2024 18:46:42 +0200 -Subject: [PATCH] libmultipath: add argument names to some prototypes - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.h | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index a242381e..19b79c5b 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -42,12 +42,12 @@ int dm_simplecmd_flush (int task, const char *name, uint16_t udev_flags); - int dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params, int flush); --int dm_map_present (const char *); -+int dm_map_present (const char *name); - int dm_map_present_by_uuid(const char *uuid); --int dm_get_map(const char *, unsigned long long *, char **); --int dm_get_status(const char *, char **); --int dm_type(const char *, char *); --int dm_is_mpath(const char *); -+int dm_get_map(const char *name, unsigned long long *size, char **outparams); -+int dm_get_status(const char *name, char **outstatus); -+int dm_type(const char *name, char *type); -+int dm_is_mpath(const char *name); - - enum { - DM_FLUSH_OK = 0, diff --git a/0041-libmultipath-bump-version-to-0.9.9.patch b/0041-libmultipath-bump-version-to-0.9.9.patch deleted file mode 100644 index 890b047..0000000 --- a/0041-libmultipath-bump-version-to-0.9.9.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 22:09:10 +0200 -Subject: [PATCH] libmultipath: bump version to 0.9.9 - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/version.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/version.h b/libmultipath/version.h -index e102975f..271d8e74 100644 ---- a/libmultipath/version.h -+++ b/libmultipath/version.h -@@ -20,9 +20,9 @@ - #ifndef _VERSION_H - #define _VERSION_H - --#define VERSION_CODE 0x000908 -+#define VERSION_CODE 0x000909 - /* MMDDYY, in hex */ --#define DATE_CODE 0x020F18 -+#define DATE_CODE 0x050318 - - #define PROG "multipath-tools" - diff --git a/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch b/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch deleted file mode 100644 index 47c3949..0000000 --- a/0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 22:28:34 +0200 -Subject: [PATCH] GitHub Workflows: native.yaml: run for Fedora 40 - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 0ef9df94..a062845e 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -33,7 +33,7 @@ jobs: - - debian-buster - - debian-bullseye - - debian-bookworm -- - fedora-39 -+ - fedora-40 - - opensuse-leap - container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} - steps: diff --git a/0043-update-NEWS.md.patch b/0043-update-NEWS.md.patch deleted file mode 100644 index 4edc69d..0000000 --- a/0043-update-NEWS.md.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 23:11:48 +0200 -Subject: [PATCH] update NEWS.md - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 3 ++ - .github/actions/spelling/patterns.txt | 3 +- - NEWS.md | 62 +++++++++++++++++++++++++++ - 3 files changed, 67 insertions(+), 1 deletion(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index fc9f22f8..bdfce83a 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -17,6 +17,7 @@ blkid - bmarzins - cciss - CFLAGS -+cgroups - christophe - clangd - clariion -@@ -67,6 +68,7 @@ fulldescr - gcc - getprkey - getprstatus -+getrlimit - getuid - github - GPT -@@ -170,6 +172,7 @@ rootprefixdir - rpmbuild - rport - rtpi -+rtprio - sas - sbp - scsi -diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt -index 858faee6..aa361654 100644 ---- a/.github/actions/spelling/patterns.txt -+++ b/.github/actions/spelling/patterns.txt -@@ -22,7 +22,7 @@ - \bdmmp_pgs\b - \bdmmp_mpath_kdev_name_get\b - \bfast_io_fail_tmo\b --\bLimitRTPRIO\b -+\bLimitRTPRIO=?\b - \bmax_fds\b - \bmissing_uev_wait_timeout\b - \bMPATH_MAX_PARAM_LEN\b -@@ -87,6 +87,7 @@ - \bprin_resvdescr\b - \bprout_param_descriptor\b - \brq_servact\b -+\bRLIMIT_RTPRIO\b - \bSCHED_RT_PRIO\b - \bssize_t\b - \btrnptid_list\b -diff --git a/NEWS.md b/NEWS.md -index 0b094b98..4c54afa0 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -1,5 +1,67 @@ - # multipath-tools Release Notes - -+## multipath-tools 0.9.9, 2024/05 -+ -+### User-Visible Changes -+ -+* *Changed realtime scheduling:* multipathd used to run at the highest possible -+ realtime priority, 99. This has always been excessive, and on some -+ distributions (e.g. RHEL 8), it hasn't worked at all. It is now possible to -+ set multipathd's real time scheduling by setting the hard limit for -+ `RLIMIT_RTPRIO` (see getrlimit(2)), which corresponds to the `rtprio` -+ setting in limits.conf and to `LimitRTPRIO=` in the systemd unit file. The -+ default in the systemd unit file has been set to 10. If the limit is set to -+ 0, multipathd doesn't attempt to enable real-time scheduling. -+ Otherwise, it will try to set the scheduling priority to the given value. -+ Fixes [#82](https://github.com/opensvc/multipath-tools/issues/82). -+* *Changed normal scheduling:* In order to make sure that multipathd has -+ sufficient priority even if real time scheduling is switched off, the -+ `CPUWeight=` setting in the unit file is set to 1000. This is necessary -+ because regular nice(2) values have no effect in systems with cgroups enabled. -+* *Changed handling of `max_sectors_kb` configuration:* multipathd applies -+ the `max_sectors_kb` setting only during map creation, or when a new path is -+ added to an existing map. The kernel makes sure that the multipath device -+ never has a larger `max_sectors_kb` value than any of its configured path -+ devices. The reason for this change is that applying `max_sectors_kb` on -+ live maps can cause IO errors and data loss in rare situations. -+ It can now happen that some path devices have a higher `max_sectors_kb` -+ value than the map; this is not an error. It is not possible any more to -+ decrease `max_sectors_kb` in `multipath.conf` and run `multipathd -+ reconfigure` to "apply" this setting to the map and its paths. If decreasing -+ the IO size is necessary, either destroy and recreate the map, or remove one -+ path with `multipathd del path $PATH`, run `multipathd reconfigure`, and -+ re-add the path with `multipathd add path $PATH`. -+* *New wildcard %k:* The wildcard `%k` for `max_sectors_kb` has been added to -+ the `multipathd show paths format` and `multipathd show maps format` -+ commands. -+* *Changed semantics of flush_on_last_del:* The `flush_on_last_del` option -+ now takes the values `always` , `unused`, or `never`. `yes` and `no` -+ are still accepted as aliases for `always` and `unused`, respectively. -+ `always` means that when all paths for a multipath map have been removed, -+ *outstanding IO will be failed* and the map will be deleted. `unused` means -+ that this will only happen when the map is not mounted or otherwise opened. -+ `never` means the map will only be removed if the `queue_if_no_path` -+ feature is off. -+ This fixes a problem where multipathd could hang when the last path of -+ a queueing map was deleted. -+ -+### Other major changes -+ -+* Adapted the dm-mpath udev rules such that they will work with the modified -+ device mapper udev rules (`DM_UDEV_RULES_VSN==3`, lvm2 > 2.03.22). They are -+ still compatible with older versions of the device-mapper udev rules. -+ -+### Bug fixes -+ -+* Fixed misspelled DM_UDEV_DISABLE_OTHER_RULES_FLAG in 11-dm-mpath.rules -+* Always use `glibc_basename()` to avoid some issues with MUSL libc. -+ Fixes [#84](https://github.com/opensvc/multipath-tools/pull/84). -+ -+### Other -+ -+* Build: added `TGTDIR` option to simplify building for a different target -+ host (see README.md). -+ - ## multipath-tools 0.9.8, 2024/02 - - ### User-Visible Changes diff --git a/0044-multipath.conf.5.in-fix-man-page-date.patch b/0044-multipath.conf.5.in-fix-man-page-date.patch deleted file mode 100644 index c9f2d5d..0000000 --- a/0044-multipath.conf.5.in-fix-man-page-date.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 May 2024 23:22:50 +0200 -Subject: [PATCH] multipath.conf.5.in: fix man page date - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 1d3d53bb..dacb9b0e 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -6,7 +6,7 @@ - .\" Update the date below if you make any significant change. - .\" ---------------------------------------------------------------------------- - . --.TH MULTIPATH.CONF 5 2024-04-17 Linux -+.TH MULTIPATH.CONF 5 2024-04-25 Linux - . - . - .\" ---------------------------------------------------------------------------- diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 22e6ad7..b898339 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,5 +1,5 @@ Name: device-mapper-multipath -Version: 0.9.8 +Version: 0.9.9 Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 @@ -7,66 +7,22 @@ URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.8.tar.gz -o multipath-tools-0.9.8.tgz -Source0: multipath-tools-0.9.8.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.9.tar.gz -o multipath-tools-0.9.9.tgz +Source0: multipath-tools-0.9.9.tgz Source1: multipath.conf -Patch0001: 0001-11-dm-mpath.rules-fix-misspelled-DM_UDEV_DISABLE_OTH.patch -Patch0002: 0002-multipathd-use-condlog-level-for-setscheduler-error-.patch -Patch0003: 0003-multipathd-make-multipathd-scheduling-configurable.patch -Patch0004: 0004-libmpathutil-really-always-use-glibc-basename.patch -Patch0005: 0005-multipathd-make-multipathd-set-priority-to-RLIMIT_RT.patch -Patch0006: 0006-multipathd-Set-CPUWeight-to-1000-and-LimitRTPRIO-to-.patch -Patch0007: 0007-11-dm-mpath.rules-explain-logic-for-device-becoming-.patch -Patch0008: 0008-11-dm-mpath.rules-don-t-import-DM_NOSCAN-from-udev-d.patch -Patch0009: 0009-11-dm-mpath.rules-don-t-import-ID_FS_VERSION-from-ud.patch -Patch0010: 0010-11-dm-mpath.rules-adapt-MPATH_DEVICE_READY-0-logic-t.patch -Patch0011: 0011-11-dm-mpath.rules-adapt-coldplug-event-handling-ro-1.patch -Patch0012: 0012-11-dm-mpath.rules-don-t-import-properties-with-new-1.patch -Patch0013: 0013-11-dm-mpath.rules-replace-DM_SUSPENDED-by-.DM_SUSPEN.patch -Patch0014: 0014-11-dm-mpath.rules-replace-DM_NOSCAN-by-.DM_NOSCAN.patch -Patch0015: 0015-11-dm-mpath.rules-simplify-PATH_FAILED-case.patch -Patch0016: 0016-11-dm-mpath.rules-make-label-names-more-intuitive.patch -Patch0017: 0017-kpartx.rules-ignore-DM_SUSPENDED.patch -Patch0018: 0018-multipath-tools-tests-fix-CI-failures-on-arm-v7-with.patch -Patch0019: 0019-multipath-tools-tests-fix-CI-failures-with-clang-on-.patch -Patch0020: 0020-GitHub-actions-fixes-for-spelling-CI.patch -Patch0021: 0021-GitHub-workflows-run-workflows-if-workflow-file-has-.patch -Patch0022: 0022-multipath-tools-add-TGTDIR-option.patch -Patch0023: 0023-libmultipath-move-get_udev_for_mpp-to-sysfs.c.patch -Patch0024: 0024-libmultipath-add-mp_find_path_by_devt.patch -Patch0025: 0025-Revert-libmultipath-fix-max_sectors_kb-on-adding-pat.patch -Patch0026: 0026-libmultipath-Only-set-max_sectors_kb-on-map-creation.patch -Patch0027: 0027-libmultipath-set-max_sectors_kb-in-adopt_paths.patch -Patch0028: 0028-libmultipath-add-wildcard-k-for-printing-max_sectors.patch -Patch0029: 0029-multipath.conf-5-update-documentation-for-max_sector.patch -Patch0030: 0030-multipath-tools-simplify-comment-in-hwtable.patch -Patch0031: 0031-multipath-tools-unify-text-in-multipath.conf.5.patch -Patch0032: 0032-multipath-tools-update-man-pages-dates.patch -Patch0033: 0033-libmultipath-export-partmap_in_use.patch -Patch0034: 0034-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch -Patch0035: 0035-libmultipath-remove-redundant-config-option-from-Inf.patch -Patch0036: 0036-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch -Patch0037: 0037-libmultipath-fix-deferred_remove-function-arguments.patch -Patch0038: 0038-libmultipath-use-bitwise-flags-for-map-flushing-API.patch -Patch0039: 0039-libmultipath-use-bitwise-flags-for-dm_simplecmd-API.patch -Patch0040: 0040-libmultipath-add-argument-names-to-some-prototypes.patch -Patch0041: 0041-libmultipath-bump-version-to-0.9.9.patch -Patch0042: 0042-GitHub-Workflows-native.yaml-run-for-Fedora-40.patch -Patch0043: 0043-update-NEWS.md.patch -Patch0044: 0044-multipath.conf.5.in-fix-man-page-date.patch -Patch0045: 0045-RH-fixup-udev-rules-for-redhat.patch -Patch0046: 0046-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0047: 0047-RH-don-t-start-without-a-config-file.patch -Patch0048: 0048-RH-Fix-nvme-function-missing-argument.patch -Patch0049: 0049-RH-use-rpm-optflags-if-present.patch -Patch0050: 0050-RH-add-mpathconf.patch -Patch0051: 0051-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0052: 0052-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0053: 0053-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0054: 0054-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0055: 0055-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0056: 0056-RH-compile-with-libreadline-support.patch -Patch0057: 0057-RH-Add-mpathcleanup.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0013: 0013-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -153,7 +109,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.8 -p1 +%autosetup -n multipath-tools-0.9.9 -p1 cp %{SOURCE1} . %build @@ -275,6 +231,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jun 13 2024 Benjamin Marzinski - 0.9.9-1 +- Update source to upstream version 0.9.9 + * Previous patches 0001-0044 are included in the source tarball +- Rename redhat patches + * Previous patches 0045-0057 are now patches 0001-0013 + * Mon May 20 2024 Benjamin Marzinski - 0.9.8-1 - Update source to upstream version 0.9.8 plus latest staging branch * Previous patches 0014 & 0015 are included in the source tarball diff --git a/sources b/sources index b0337e2..f098bc9 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.8.tgz) = 4d73bcf6bce769a829c306c609b206ddba65a708620f458106e406dd18d12f9a9d97f400662daa8e6a75c9fdf7decb6dcbda92cb807b6c53522c7b4b2795b627 +SHA512 (multipath-tools-0.9.9.tgz) = 65b5d5c48792f6041d700968c87675bc349ede475fe178a203814dbb0325f69895782a22c5c35f6c0157f694951714de9e83cc1464a6c062d911a58faed8960a SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 4e4233829d041b14b0773e59b57ed1aca0de9b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 9 Jul 2024 12:58:25 +0200 Subject: [PATCH 18/33] Rebuilt for the bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b898339..2897380 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Jul 09 2024 Zbigniew JÄ™drzejewski-Szmek - 0.9.9-2 +- Rebuilt for the bin-sbin merge + * Thu Jun 13 2024 Benjamin Marzinski - 0.9.9-1 - Update source to upstream version 0.9.9 * Previous patches 0001-0044 are included in the source tarball From 3cde646adee765e1e8dca298f73db057039f317d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 20:51:42 +0000 Subject: [PATCH 19/33] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2897380..247501d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -231,6 +231,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 17 2024 Fedora Release Engineering - 0.9.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Tue Jul 09 2024 Zbigniew JÄ™drzejewski-Szmek - 0.9.9-2 - Rebuilt for the bin-sbin merge From 519bd15b4dd30fadd1310fae97d8189ea061cae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Thu, 25 Jul 2024 11:35:35 +0200 Subject: [PATCH 20/33] convert GPLv3+ license to SPDX This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- device-mapper-multipath.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 247501d..fb448ed 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -90,7 +90,8 @@ kpartx manages partition creation and removal for device-mapper devices. %package -n libdmmp Summary: device-mapper-multipath C API library -License: GPLv3+ +# Automatically converted from old format: GPLv3+ - review is highly recommended. +License: GPL-3.0-or-later Requires: json-c Requires: %{name} = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release} @@ -231,6 +232,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jul 25 2024 Miroslav Suchý - 0.9.9-4 +- convert license to SPDX + * Wed Jul 17 2024 Fedora Release Engineering - 0.9.9-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From 354f1e7cfbad435492ff429f5a3e98e713a2530b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Mon, 29 Jul 2024 10:25:45 +0200 Subject: [PATCH 21/33] convert GPLv2 license to SPDX This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- device-mapper-multipath.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index fb448ed..6cd8a6d 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,8 +1,9 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper -License: GPLv2 +# Automatically converted from old format: GPLv2 - review is highly recommended. +License: GPL-2.0-only URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the @@ -232,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Mon Jul 29 2024 Miroslav Suchý - 0.9.9-5 +- convert license to SPDX + * Thu Jul 25 2024 Miroslav Suchý - 0.9.9-4 - convert license to SPDX From 0c6649fa32544f07677c7495c8269bd0d95cc62b Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 9 Aug 2024 16:00:03 -0400 Subject: [PATCH 22/33] device-mapper-multipath-0.9.9-6 Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * multipath features tracking on failed removes --- ...tipathd-fix-flush-check-in-flush_map.patch | 28 +++++++++++++++++++ device-mapper-multipath.spec | 7 ++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 0014-multipathd-fix-flush-check-in-flush_map.patch diff --git a/0014-multipathd-fix-flush-check-in-flush_map.patch b/0014-multipathd-fix-flush-check-in-flush_map.patch new file mode 100644 index 0000000..3ff957d --- /dev/null +++ b/0014-multipathd-fix-flush-check-in-flush_map.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 5 Jun 2024 19:22:48 -0400 +Subject: [PATCH] multipathd: fix flush check in flush_map() + +Forgot the comparison in the "if" statement. + +Fixes 8a3898339 ("multipathd: sync features on flush_map failure corner case") + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 09286dd0..58afe14a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -813,7 +813,7 @@ flush_map(struct multipath * mpp, struct vectors * vecs) + { + int r = dm_suspend_and_flush_map(mpp->alias, 0); + if (r != DM_FLUSH_OK) { +- if (DM_FLUSH_FAIL_CANT_RESTORE) ++ if (r == DM_FLUSH_FAIL_CANT_RESTORE) + remove_feature(&mpp->features, "queue_if_no_path"); + condlog(0, "%s: can't flush", mpp->alias); + return r; diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 6cd8a6d..9e74d46 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.9.9 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -24,6 +24,7 @@ Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch Patch0012: 0012-RH-compile-with-libreadline-support.patch Patch0013: 0013-RH-Add-mpathcleanup.patch +Patch0014: 0014-multipathd-fix-flush-check-in-flush_map.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -233,6 +234,10 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Aug 9 2024 Benjamin Marzinski - 0.9.9-6 +- Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch + * multipath features tracking on failed removes + * Mon Jul 29 2024 Miroslav Suchý - 0.9.9-5 - convert license to SPDX From 94144d9276e41dd879043596114d248db042dbc5 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 29 Aug 2024 15:20:13 -0400 Subject: [PATCH 23/33] device-mapper-multipath-0.10.0-1 Update source to upstream version 0.9.9 * Previous patch 0014-multipathd-fix-flush-check-in-flush_map.patch is included in the source tarball Rebase redhat patches --- .gitignore | 1 + 0001-RH-fixup-udev-rules-for-redhat.patch | 20 ++++----- ...property-blacklist-exception-builtin.patch | 8 ++-- ...RH-don-t-start-without-a-config-file.patch | 16 +++---- ...H-Fix-nvme-function-missing-argument.patch | 2 +- 0005-RH-use-rpm-optflags-if-present.patch | 30 ++++++++----- 0006-RH-add-mpathconf.patch | 43 +++++++++++++++---- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 16 +++---- ...-default-find_mutipaths-value-to-off.patch | 8 ++-- ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- ...tipathd-fix-flush-check-in-flush_map.patch | 28 ------------ device-mapper-multipath.spec | 17 +++++--- sources | 2 +- 15 files changed, 105 insertions(+), 92 deletions(-) delete mode 100644 0014-multipathd-fix-flush-check-in-flush_map.patch diff --git a/.gitignore b/.gitignore index 3bea72e..908094d 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.7.tgz /multipath-tools-0.9.8.tgz /multipath-tools-0.9.9.tgz +/multipath-tools-0.10.0.tgz diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch index d78919e..0645240 100644 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -9,13 +9,13 @@ different naming scheme for partitions than SuSE. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 2 +- - kpartx/kpartx.rules | 2 +- - multipath/Makefile | 4 ++-- + Makefile.inc | 2 +- + kpartx/kpartx.rules.in | 2 +- + multipath/Makefile | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 81b86cd8..33dbb99c 100644 +index 729618bd..81cb61d2 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif @@ -27,16 +27,16 @@ index 81b86cd8..33dbb99c 100644 # Prefix for non-essential libraries (libdmmp) usr_prefix := $(if $(prefix),$(prefix),/usr) # Prefix for configuration files (multipath.conf) -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 8dd3369c..7c3c7524 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules +diff --git a/kpartx/kpartx.rules.in b/kpartx/kpartx.rules.in +index 9d879609..2049eb8f 100644 +--- a/kpartx/kpartx.rules.in ++++ b/kpartx/kpartx.rules.in @@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" GOTO="kpartx_end" LABEL="run_kpartx" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" +-RUN+="@BINDIR@/kpartx -un -p -part /dev/$name" ++RUN+="@BINDIR@/kpartx -un /dev/$name" LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch index b039539..a74e6c2 100644 --- a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -19,7 +19,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 75100b20..0b212078 100644 +index 17e1b54a..10d13e98 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c @@ -230,8 +230,6 @@ setup_default_blist (struct config * conf) @@ -42,10 +42,10 @@ index 75100b20..0b212078 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index dacb9b0e..645e8f88 100644 +index 4388baad..af9fbb96 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1468,9 +1468,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1469,9 +1469,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index dacb9b0e..645e8f88 100644 . .RS .PP -@@ -1481,10 +1486,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1482,10 +1487,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch index 267ffa7..02827df 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 83fa7369..002027a7 100644 +index 0e3a5cc1..80f61914 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -959,6 +959,19 @@ int _init_config (const char *file, struct config *conf) +@@ -959,6 +959,19 @@ int init_config__ (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -46,7 +46,7 @@ index 83fa7369..002027a7 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 384193ab..158cebf0 100644 +index 94cdf252..534b6142 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -58,10 +58,10 @@ index 384193ab..158cebf0 100644 enum devtypes { DEV_NONE, diff --git a/multipath/main.c b/multipath/main.c -index ce702e7f..c21e3e0b 100644 +index 28e3a055..346acb61 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -842,11 +842,14 @@ main (int argc, char *argv[]) +@@ -843,11 +843,14 @@ main (int argc, char *argv[]) char *dev = NULL; struct config *conf; bool enable_foreign = false; @@ -76,7 +76,7 @@ index ce702e7f..c21e3e0b 100644 if (init_config(DEFAULT_CONFIGFILE)) exit(RTVL_FAIL); if (atexit(uninit_config)) -@@ -1097,6 +1100,9 @@ main (int argc, char *argv[]) +@@ -1101,6 +1104,9 @@ main (int argc, char *argv[]) while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) condlog(3, "restart multipath configuration process"); @@ -87,7 +87,7 @@ index ce702e7f..c21e3e0b 100644 put_multipath_config(conf); if (dev) diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in -index 780bf852..2c518378 100644 +index 2ac1972f..cc248231 100644 --- a/multipath/multipath.rules.in +++ b/multipath/multipath.rules.in @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" @@ -112,7 +112,7 @@ index 7bc8806e..315884eb 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index a63ddd9a..01ceff7d 100644 +index 646001e6..72e44849 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch index ced7159..74b7b53 100644 --- a/0004-RH-Fix-nvme-function-missing-argument.patch +++ b/0004-RH-Fix-nvme-function-missing-argument.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h -index adb192b6..bfd10ef8 100644 +index e6c54453..0c6c9439 100644 --- a/libmultipath/nvme/argconfig.h +++ b/libmultipath/nvme/argconfig.h @@ -76,7 +76,7 @@ struct argconfig_commandline_options { diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch index 0f354e7..3f115c1 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -9,19 +9,18 @@ still being generic. Signed-off-by: Benjamin Marzinski --- - Makefile.inc | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) + Makefile.inc | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 33dbb99c..94e0ec85 100644 +index 81cb61d2..35334a0c 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -95,11 +95,23 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo +@@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ echo "modprobe@dm_multipath.service") -OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 --WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ +ifndef RPM_OPT_FLAGS + OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 \ + -Wall $(FORTIFY_OPT) -fexceptions -grecord-gcc-switches \ @@ -35,16 +34,27 @@ index 33dbb99c..94e0ec85 100644 +else + OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 +endif -+WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) + + # Set WARN_ONLY=1 to avoid compilation erroring out due to warnings. Useful during development. + WARN_ONLY := + ERROR := $(if $(WARN_ONLY),,error=) + WERROR := $(if $(WARN_ONLY),,-Werror) +-WARNFLAGS := $(WERROR) -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -W$(ERROR)implicit-int \ ++WARNFLAGS := $(WERROR) -Wextra -Wformat=2 $(WFORMATOVERFLOW) -W$(ERROR)implicit-int \ + -W$(ERROR)implicit-function-declaration -W$(ERROR)format-security \ +- $(WNOCLOBBERED) -W$(ERROR)cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) ++ $(WNOCLOBBERED) -W$(ERROR)cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes + -CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ -+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes +CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ -D_FILE_OFFSET_BITS=64 \ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ -@@ -109,7 +121,7 @@ CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ + -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP +-CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ +- -fexceptions ++CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0006-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch index fd65e34..2ae48f3 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -13,19 +13,44 @@ a single command. Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- - libmultipath/config.c | 2 + - multipath/Makefile | 4 + - multipath/mpathconf | 658 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 151 ++++++++++ - 4 files changed, 815 insertions(+) + .github/actions/spelling/expect.txt | 3 + + libmultipath/config.c | 2 + + multipath/Makefile | 4 + + multipath/mpathconf | 658 ++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 151 +++++++ + 5 files changed, 818 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 934f582e..61351583 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -124,9 +124,11 @@ lvmteam + Marzinski + mpath + mpathb ++mpathconf + mpathpersist + mpathvalid + msecs ++multipathable + multipathc + multipathd + multipathed +@@ -144,6 +146,7 @@ ontap + OOM + opensvc + OPTFLAGS ++outfile + paramp + partx + pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index 002027a7..3d5943d3 100644 +index 80f61914..1373f15b 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -961,6 +961,8 @@ int _init_config (const char *file, struct config *conf) +@@ -961,6 +961,8 @@ int init_config__ (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -735,7 +760,7 @@ index 00000000..ce430075 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..ea025f31 +index 00000000..ec4e5c56 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,151 @@ @@ -877,7 +902,7 @@ index 00000000..ea025f31 +.B service multipathd stop +to stop the multipathd daemon on \fB--disable\fP, and +.B service multipathd reload -+to reconfigure multipathd on \fB--user_frindly_names\fP and ++to reconfigure multipathd on \fB--user_friendly_names\fP and +\fB--find_multipaths\fP. +This option is set to \fBn\fP by default. +.SH FILES diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 9884258..4e781fa 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index c21e3e0b..3f3ac9fb 100644 +index 346acb61..adc50d69 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -120,7 +120,7 @@ usage (char * progname) @@ -41,7 +41,7 @@ index c21e3e0b..3f3ac9fb 100644 " -c check if a device should be a path in a multipath device\n" " -C check if a multipath device has usable paths\n" " -q allow queue_if_no_path when multipathd is not running\n" -@@ -448,6 +450,50 @@ static void cleanup_vecs(void) +@@ -449,6 +451,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index c21e3e0b..3f3ac9fb 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -861,7 +907,7 @@ main (int argc, char *argv[]) +@@ -860,7 +906,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); if (atexit(cleanup_bindings)) condlog(1, "failed to register cleanup handler for bindings: %m"); @@ -101,7 +101,7 @@ index c21e3e0b..3f3ac9fb 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -932,6 +978,10 @@ main (int argc, char *argv[]) +@@ -931,6 +977,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -138,14 +138,14 @@ index b88e9a4c..edd742aa 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 01ceff7d..e0c2011b 100644 +index 72e44849..69a6c39d 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -17,6 +17,7 @@ ConditionVirtualization=!container [Service] Type=notify NotifyAccess=main -+ExecStartPre=-/sbin/multipath -A - ExecStart=/sbin/multipathd -d -s - ExecReload=/sbin/multipathd reconfigure ++ExecStartPre=-@BINDIR@/multipath -A + ExecStart=@BINDIR@/multipathd -d -s + ExecReload=@BINDIR@/multipathd reconfigure TasksMax=infinity diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch index 04ad52c..5789916 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index ed08c251..4b033ff9 100644 +index 02f7e57c..cd03fd1a 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -23,7 +23,7 @@ +@@ -24,7 +24,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 @@ -27,10 +27,10 @@ index ed08c251..4b033ff9 100644 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 645e8f88..a7543939 100644 +index af9fbb96..0c1eff40 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1225,7 +1225,7 @@ as non-multipath and passed on to upper layers. +@@ -1226,7 +1226,7 @@ as non-multipath and passed on to upper layers. \fBNote:\fR this may cause delays during device detection if there are single-path devices which aren\'t blacklisted. .TP diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index c090da0..06194f6 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e2052422..3bcd94ce 100644 +index e94705bf..61ac27ef 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch index 7624c5b..3debe8a 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 94e0ec85..49514b06 100644 +index 35334a0c..377125b6 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch index eb0ab13..db04640 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0012-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 49514b06..a3ed9f28 100644 +index 377125b6..4a6528a9 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0014-multipathd-fix-flush-check-in-flush_map.patch b/0014-multipathd-fix-flush-check-in-flush_map.patch deleted file mode 100644 index 3ff957d..0000000 --- a/0014-multipathd-fix-flush-check-in-flush_map.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 5 Jun 2024 19:22:48 -0400 -Subject: [PATCH] multipathd: fix flush check in flush_map() - -Forgot the comparison in the "if" statement. - -Fixes 8a3898339 ("multipathd: sync features on flush_map failure corner case") - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 09286dd0..58afe14a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -813,7 +813,7 @@ flush_map(struct multipath * mpp, struct vectors * vecs) - { - int r = dm_suspend_and_flush_map(mpp->alias, 0); - if (r != DM_FLUSH_OK) { -- if (DM_FLUSH_FAIL_CANT_RESTORE) -+ if (r == DM_FLUSH_FAIL_CANT_RESTORE) - remove_feature(&mpp->features, "queue_if_no_path"); - condlog(0, "%s: can't flush", mpp->alias); - return r; diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 9e74d46..da97503 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath -Version: 0.9.9 -Release: 6%{?dist} +Version: 0.10.0 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -8,8 +8,8 @@ URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.9.tar.gz -o multipath-tools-0.9.9.tgz -Source0: multipath-tools-0.9.9.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.10.0.tar.gz -o multipath-tools-0.10.0.tgz +Source0: multipath-tools-0.10.0.tgz Source1: multipath.conf Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -24,7 +24,6 @@ Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch Patch0012: 0012-RH-compile-with-libreadline-support.patch Patch0013: 0013-RH-Add-mpathcleanup.patch -Patch0014: 0014-multipathd-fix-flush-check-in-flush_map.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -112,7 +111,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.9.9 -p1 +%autosetup -n multipath-tools-0.10.0 -p1 cp %{SOURCE1} . %build @@ -234,6 +233,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-1 +- Update source to upstream version 0.9.9 + * Previous patch 0014-multipathd-fix-flush-check-in-flush_map.patch is + included in the source tarball +- Rebase redhat patches + * Fri Aug 9 2024 Benjamin Marzinski - 0.9.9-6 - Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch * multipath features tracking on failed removes diff --git a/sources b/sources index f098bc9..da06e16 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.9.9.tgz) = 65b5d5c48792f6041d700968c87675bc349ede475fe178a203814dbb0325f69895782a22c5c35f6c0157f694951714de9e83cc1464a6c062d911a58faed8960a +SHA512 (multipath-tools-0.10.0.tgz) = 8f545609fa20df7547428f2929571dc0df87c17d9f61f11aad3559446c2e94755e18b1c4b3780b3de92ec2cbc450939ca15a9d6c95551eee4084064d83874b2d SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 75d5c0c70a04b7033f662e60c47f6634298a067e Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 29 Aug 2024 18:11:38 -0400 Subject: [PATCH 24/33] device-mapper-multipath-0.10.0-2 Update CI tests. --- device-mapper-multipath.spec | 5 +- tests/bindings/main.sh | 126 ++++++++--- tests/find_multipaths/Makefile | 49 ----- tests/find_multipaths/main.sh | 208 ++++++++++++------- tests/include/ec.sh | 14 +- tests/medium_error_scsi_debug/main.sh | 66 +++--- tests/restate_module/main.sh | 6 +- tests/user_friendly_names/main.sh | 151 ++++++++++---- tests/user_friendly_names/multipath.conf.no | 3 - tests/user_friendly_names/multipath.conf.yes | 11 - 10 files changed, 395 insertions(+), 244 deletions(-) delete mode 100644 tests/find_multipaths/Makefile delete mode 100644 tests/user_friendly_names/multipath.conf.no delete mode 100644 tests/user_friendly_names/multipath.conf.yes diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index da97503..4363b49 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-2 +- update CI tests. + * Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-1 - Update source to upstream version 0.9.9 * Previous patch 0014-multipathd-fix-flush-check-in-flush_map.patch is diff --git a/tests/bindings/main.sh b/tests/bindings/main.sh index 2d6f284..76292e4 100755 --- a/tests/bindings/main.sh +++ b/tests/bindings/main.sh @@ -18,40 +18,110 @@ # Author: Lin Li #set -x -source ../include/ec.sh || exit 200 - +source ../include/tc.sh || exit 200 tlog "running $0" -trun "service multipathd stop" -rpm -q device-mapper-multipath || yum install -y device-mapper-multipath -trun "mpathconf --enable --with_multipathd y --user_friendly_names y" -trun "service multipathd status" -sleep 5 +cleanup () +{ + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove deviece" + tend + fi + tlog "removing multipath device" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" +} -trun "multipath -F" -sleep 5 -terr "modprobe -r scsi_debug" -terr "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ -max_luns=2 no_lun_0=1" -sleep 60 +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -disk_path=$(get_scsi_debug_devices) -disk=$(basename $disk_path) -mpath_name=$(get_mpath_disk_by_scsi_device $disk) +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf + +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +_EOF_ + trun "cat /etc/multipath.conf" +} + +do_reconfigure () +{ + tok "multipathd reconfigure" + sleep 5 +} + +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath +cleanup +setup_config +trun "rm -r /etc/multipath/bindings" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done + +trun 'multipathd show maps raw format "%n"' +mpath_name=`multipathd show maps raw format "%n" | head -1` +assert "[[ -n $mpath_name ]] && [[ $mpath_name != ok ]]" new_alias="mpath_test_$$" trun "sed -i 's/$mpath_name/$new_alias/' /etc/multipath/bindings" -trun "multipath -r" -sleep 5 -tok "[[ -b /dev/mapper/$new_alias ]]" -tok is_mpath $new_alias -sleep 5 +do_reconfigure +trun 'multipathd show maps raw format "%n"' +mpath_name=`multipathd show maps raw format "%n" | head -1` +assert "[[ $mpath_name = $new_alias ]]" -trun "multipath -F" -sleep 5 -trun "modprobe -r scsi_debug" -trun "service multipathd stop" -sleep 3 -trun "multipath -W" -trun "rm /etc/multipath/bindings" +cleanup tend diff --git a/tests/find_multipaths/Makefile b/tests/find_multipaths/Makefile deleted file mode 100644 index b78dc57..0000000 --- a/tests/find_multipaths/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # This program is free software: you can redistribute it and/or modify -# # it under the terms of the GNU General Public License as published by -# # the Free Software Foundation, either version 3 of the License, or -# # (at your option) any later version. -# # -# # This program is distributed in the hope that it will be useful, -# # but WITHOUT ANY WARRANTY; without even the implied warranty of -# # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# # GNU General Public License for more details. -# # -# # You should have received a copy of the GNU General Public License -# # along with this program. If not, see . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: find_multipaths" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/find_multipaths/main.sh b/tests/find_multipaths/main.sh index 4d94c87..28c325c 100755 --- a/tests/find_multipaths/main.sh +++ b/tests/find_multipaths/main.sh @@ -18,39 +18,92 @@ # Author: Lin Li #set -x -source ../include/ec.sh || exit 200 +source ../include/tc.sh || exit 200 +tlog "running $0" + +remove_devices () +{ + local retries + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove devices" + cleanup + tend + fi + tlog "removing multipath devices" + trun "udevadm settle" + trun "multipath -F" + sleep 2 + done +} cleanup () { - trun "multipathd disablequeueing maps" - trun "service multipathd stop" - sleep 5 - trun "udevadm settle" - trun "multipath -F" - sleep 5 - trun "modprobe -r scsi_debug" + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove devices" + tend + fi + tlog "removing multipath devices" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" + trun "rm -f /etc/multipath/wwids" + trun "rm -r /etc/multipath/bindings" } -tlog "running $0" +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -# which not set find_multipaths yes, so multipath always create a multipath device for single device -# so stop service and reconfig with --find_multipaths y, and reload/start the service again. -rpm -q device-mapper-multipath || yum install -y device-mapper-multipath +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y --find_multipaths y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf -# test with find_multipath=y, will not multipath for the single device; reload/start the service to enable the config -cleanup -trun "rm -f /etc/multipath.conf" -trun "rm -f /etc/multipath/wwids" -trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd n" -sed -i '/^blacklist[[:space:]]*{/ a\ - device {\n vendor ".*"\n product ".*"\n } -' /etc/multipath.conf -if grep -qw blacklist_exceptions /etc/multipath.conf ; then - sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ - device {\n vendor Linux\n product scsi_debug\n } -' /etc/multipath.conf -else - cat << _EOF_ >> /etc/multipath.conf blacklist_exceptions { device { vendor Linux @@ -58,56 +111,69 @@ blacklist_exceptions { } } _EOF_ -fi -trun "service multipathd start" + trun "cat /etc/multipath.conf" +} + +do_reconfigure () +{ + trun "cat /etc/multipath.conf" + tok "multipathd reconfigure" + sleep 5 +} + +trun "rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath" +cleanup +setup_config + +# test with find_multipath=y, will not multipath the single device trun "modprobe scsi_debug" sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ $mpath_name = '[orphan]' ]]" +remove_devices + +# test with find_multipath=n, will multipath the single device +trun 'mpathconf --find_multipaths n' +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" +remove_devices + +# test with find_multipath=y, with multipath single device with known WWID +trun 'mpathconf --find_multipaths y' +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" +remove_devices + +# Clear WWID, test with find_multipath=y, will not multipath single device trun "multipath -W" -cat /etc/multipath/wwids -trun "multipath" -disk_path=$(get_scsi_debug_devices) -disk_node=$(basename $disk_path) -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ $mpath_name = "[orphan]" ]]' - -# test with find_multipath=n, will multipath for the single device -trun "mpathconf --user_friendly_names y --find_multipaths n --with_multipathd y" -sleep 5 -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" - -# flush new created path -trun "multipath -F" -sleep 1 - -# test with find_multipath=y, A path has the same WWID as a multipath device that was previously created -trun "mpathconf --user_friendly_names y --find_multipaths y --with_multipathd y" -sleep 5 -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" -trun "multipath -F" -sleep 1 - -# Clear wwid, test with find_multipath=y, will not multipath for the single device -trun "multipath -W" -trun "service multipathd reload" -sleep 5 -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ $mpath_name = "[orphan]" ]]' - -trun "multipath -F" -sleep 5 -trun "modprobe -r scsi_debug" +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ $mpath_name = '[orphan]' ]]" +remove_devices +assert 'rmmod scsi_debug' # test find_multipaths=y create device for paths have same wwid -tok "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1" -sleep 10 -disk_paths=$(get_scsi_debug_devices) -disk_node=$(basename $disk_paths) -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" cleanup -trun "multipath -W" -cat /etc/multipath/wwids tend diff --git a/tests/include/ec.sh b/tests/include/ec.sh index 22dfc40..4b0aba9 100755 --- a/tests/include/ec.sh +++ b/tests/include/ec.sh @@ -44,9 +44,12 @@ function _init (){ } function _destroy (){ - sleep 10 - Cmd "multipath -F" + Cmd "multipathd disablequeueing maps" sleep 5 + Cmd "multipath -DF -R2" + Cmd "service multipathd stop" + sleep 5 + Cmd "udevadm settle" Cmd "modprobe -r scsi_debug" } @@ -174,10 +177,7 @@ AA fi #setup scsi_debug echo "INFO: Loading scsi_debug module for simulation of mpath" - modprobe scsi_debug \ - num_tgts=1 vpd_use_hostno=0 \ - add_host=4 delay=20 \ - max_luns=2 no_lun_0=1 2>&1 1>/dev/null + modprobe scsi_debug vpd_use_hostno=0 add_host=2 echo "INFO: Waiting for udev to create /dev/sdX" sleep 15s #wait for udev to create /dev/sdX @@ -189,8 +189,6 @@ AA #enable multipath for scsi_debug. cat << AA > /etc/multipath.conf defaults { -#Enable multibus is for mutlbus testing - path_grouping_policy multibus user_friendly_names yes } blacklist { diff --git a/tests/medium_error_scsi_debug/main.sh b/tests/medium_error_scsi_debug/main.sh index db2f008..35c6e6f 100755 --- a/tests/medium_error_scsi_debug/main.sh +++ b/tests/medium_error_scsi_debug/main.sh @@ -16,47 +16,51 @@ # along with this program. If not, see . # Author: LiLin +source ../include/tc.sh || exit 200 -function cleanup() +cleanup() { sleep 5 udevadm settle - multipath -F + trun "multipath -DF" sleep 5 - modprobe -r scsi_debug - - return 0 + trun "modprobe -r scsi_debug" } -yum -y install device-mapper device-mapper-multipath -mpathconf --enable -service multipathd stop -modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1 opts=2 +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} + +tlog "running $0" +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath +trun "multipathd disablequeueing maps" +cleanup +trun "service multipathd stop" +trun "rm -f /etc/multipath.conf" +trun "mpathconf --enable" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2 opts=2" sleep 5 -multipath > /dev/null +trun "multipath" sleep 5 +trun "multipath -l" mpathdev=`multipath -l | grep scsi_debug | awk '{print $1}' | head -1` -if [ -z "$mpathdev" ]; then - echo "------- FAIL, no multipath device created -----" - cleanup - exit 1 -fi +assert "[[ -n \"$mpathdev\" ]]" before_active=`multipath -l $mpathdev | grep "active undef" | wc -l` +tlog "before active = ${before_active}" IO_error=`dd if=/dev/zero of=/dev/mapper/$mpathdev bs=1024 seek=2330 count=10 2>&1 | grep -o "Input/output error" ` -if [ -n "$IO_error" ];then - after_active=`multipath -l $mpathdev | grep "active undef" | wc -l` - if [ "$before_active" -eq "$after_active" ]; then - echo "------- PASS, a medium error, correctly generated an I/O error and did not fail paths -----" - cleanup - exit 0 - else - echo "------- FAIL, paths failed -----" - cleanup - exit 1 - fi -else - echo "------- FAIL, did not generate an I/O error -----" - cleanup - exit 1 -fi +assert "[[ -n \"$IO_error\" ]]" +after_active=`multipath -l $mpathdev | grep "active undef" | wc -l` +tlog "after active = ${after_active}" +assert "[[ \"$before_active\" -eq \"$after_active\" ]]" +cleanup +tend diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index 565e59c..be60eba 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -48,10 +48,8 @@ rpm -q device-mapper-multipath || yum install -y device-mapper-multipath tlog "device-mapper-multipath is installed" # cleanup existing devices trun "rm /etc/multipath.conf" -trun "mpathconf --enable --with_module y" -sed -i '/^defaults[[:space:]]*{/ a\ - max_polling_interval 10 -' /etc/multipath.conf +trun "mpathconf --enable --with_module y --option max_polling_interval:10" +trun "mpathconf --option detect_pgpolicy_use_tpg:yes" trun "service multipathd stop" trun "multipath -F" sleep 5 diff --git a/tests/user_friendly_names/main.sh b/tests/user_friendly_names/main.sh index 56082fd..1d48801 100755 --- a/tests/user_friendly_names/main.sh +++ b/tests/user_friendly_names/main.sh @@ -17,50 +17,125 @@ # Author: Lin Li -source ../include/ec.sh || exit 200 - +source ../include/tc.sh || exit 200 tlog "running $0" -trun "rpm -q device-mapper-multipath || yum install -y device-mapper-multipath" -trun "mpathconf --enable --with_multipathd y --user_friendly_names y" +cleanup () +{ + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove deviece" + tend + fi + tlog "removing multipath device" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" +} -# backup the /etc/multipath.conf -trun "cp /etc/multipath.conf /etc/multipath.conf.$$" -trun "multipath -F" +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -trun "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ -max_luns=2 no_lun_0=1" -trun "multipath" -# wwid shown slowly on s390x by the script framework, but normally when run by multipath command directly -# so extend sleep time -sleep 20 +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf -disk=$(get_scsi_debug_devices) -disk=$(basename $disk) -wwid=$(get_wwid_of_disk $disk) -mpath=$(get_mpath_disk_by_scsi_device $disk) +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} -# user_friendly_names = yes and mpath=test -#cur_dir=/mnt/tests/kernel/storage/multipath/user_friendly_names/ -#cur_dir=/home/test/scratch/device-mapper-multipath/user_friendly_names -trun "cat multipath.conf.yes | sed "s/your_wwid/$wwid/g" > /etc/multipath.conf" -trun "cat -n /etc/multipath.conf" -trun "multipath -r" -echo ">>> Verify 'test ($wwid)' is present ..." -trun "multipath -ll" -tok "multipath -ll | egrep \"^test\"" +multipaths { + multipath { + wwid TEST_WWID + alias test + } +} +_EOF_ + trun "cat /etc/multipath.conf" +} -# user_friendly_names = no -trun "cat multipath.conf.no > /etc/multipath.conf" -trun "multipath -r" -echo ">>> Verify 'test' is gone but '$wwid' present ..." -trun "multipath -ll" -tok "multipath -ll | egrep \"^$wwid\"" -sleep 10 -tok "multipath -F $wwid" -sleep 10 -trun "modprobe -r scsi_debug" +do_reconfigure () +{ + trun "cat /etc/multipath.conf" + tok "multipathd reconfigure" + sleep 5 +} -trun "cp /etc/multipath.conf.$$ /etc/multipath.conf" -trun "multipath -F; multipath" +trun "rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath" +cleanup +setup_config +trun "rm -r /etc/multipath/bindings" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done +trun 'multipathd show maps raw format "%n %w"' +# verify user_friendly_name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q mpath' +wwid=`multipathd show maps raw format "%w" | head -1` +assert "[[ -n $wwid ]] && [[ $wwid != ok ]]" +sed -i 's/TEST_WWID/'"$wwid"'/' /etc/multipath.conf +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +# verify configured alias takes precedence over user_friendly_name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q test' +trun "mpathconf --user_friendly_names n" +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +# verify configured alias takes precedence over wwid name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q test' +sed -i 's/'"$wwid"'/TEST_WWID/' /etc/multipath.conf +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +tok 'multipathd show maps raw format "%n" | head -1 | grep -q '"$wwid" +cleanup tend diff --git a/tests/user_friendly_names/multipath.conf.no b/tests/user_friendly_names/multipath.conf.no deleted file mode 100644 index b916bfb..0000000 --- a/tests/user_friendly_names/multipath.conf.no +++ /dev/null @@ -1,3 +0,0 @@ -defaults { - user_friendly_names no -} diff --git a/tests/user_friendly_names/multipath.conf.yes b/tests/user_friendly_names/multipath.conf.yes deleted file mode 100644 index ffc21bb..0000000 --- a/tests/user_friendly_names/multipath.conf.yes +++ /dev/null @@ -1,11 +0,0 @@ -defaults { - user_friendly_names yes -} - -multipaths { - multipath { - wwid your_wwid - alias test - } -} - From 4ec4661deede93f7134c87624f89a07ac166e3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Jan 2025 14:25:51 +0100 Subject: [PATCH 25/33] Rebuilt for the bin-sbin merge (2nd attempt) https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 4363b49..2eebd2f 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Sun Jan 12 2025 Zbigniew JÄ™drzejewski-Szmek - 0.10.0-3 +- Rebuilt for the bin-sbin merge (2nd attempt) + * Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-2 - update CI tests. From 61847c90be2f7afa60de098651ff5c92cd0f1374 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 15:37:12 +0000 Subject: [PATCH 26/33] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2eebd2f..8ff030a 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper # Automatically converted from old format: GPLv2 - review is highly recommended. License: GPL-2.0-only @@ -233,6 +233,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 0.10.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Sun Jan 12 2025 Zbigniew JÄ™drzejewski-Szmek - 0.10.0-3 - Rebuilt for the bin-sbin merge (2nd attempt) From 05ecb26e7c73e0563c5b4096bf6288324b753cea Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 28 Jan 2025 23:12:39 -0500 Subject: [PATCH 27/33] Fix build with userspace-rcu 0.15.0 C11 (or C++11) are now required for atomics in userspace-rcu: https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f --- 0005-RH-use-rpm-optflags-if-present.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch index 3f115c1..266e224 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -54,7 +54,7 @@ index 81cb61d2..35334a0c 100644 -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP -CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions -+CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe ++CFLAGS := -std=gnu11 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared From 3c2eb3f84ecbc2fd6790437dc83955ab4fd6cc33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Mon, 20 Jan 2025 08:06:30 +0000 Subject: [PATCH 28/33] Migrate to SPDX license This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_4 --- device-mapper-multipath.spec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 8ff030a..d2c3cc6 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -2,8 +2,8 @@ Name: device-mapper-multipath Version: 0.10.0 Release: 4%{?dist} Summary: Tools to manage multipath devices using device-mapper -# Automatically converted from old format: GPLv2 - review is highly recommended. -License: GPL-2.0-only +# readline uses GPL-3.0-only +License: GPL-2.0-only AND GPL-3.0-only URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the @@ -65,8 +65,8 @@ The tools are : %package libs Summary: The %{name} modules and shared library -# only libmpathcmd is LGPLv2+ -License: GPLv2 and LGPLv2+ +# only libmpathcmd is LGPL-2.1-or-later AND LGPL-2.0-or-later +License: GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later %description libs The %{name}-libs provides the path checker From f2377371e3fef1c096acab223bd842dbd755f5d0 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Sun, 2 Feb 2025 01:54:16 -0500 Subject: [PATCH 29/33] device-mapper-multipath-0.10.0-5 - Update source to upstream staging branch for 0.10.y (will be 0.10.2 when merged). - Rebase redhat patches --- ...lows-use-upload-download-artifact-v4.patch | 122 ++++++++++++++++ ...-update-dawidd6-action-download-arti.patch | 24 +++ ...-native.yml-use-mosteo-actions-docke.patch | 98 +++++++++++++ ...s-native.yml-use-extra-job-for-clang.patch | 43 ++++++ ...-native.yaml-make-test-and-archive-s.patch | 51 +++++++ ...-enable-unit-tests-for-stable-branch.patch | 133 +++++++++++++++++ ...ws-add-abi-check-for-stable-branches.patch | 110 ++++++++++++++ ...get_maps-don-t-bail-out-for-single-m.patch | 32 ++++ ...s.in-import-DM_COLDPLUG_SUSPENDED-on.patch | 42 ++++++ ...s.in-handle-inactive-suspended-devic.patch | 66 +++++++++ ...rules.in-clarify-DM_ACTIVATION-logic.patch | 78 ++++++++++ ...h-rules.in-skip-one-.DM_NOSCAN-check.patch | 28 ++++ ...s.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch | 44 ++++++ ...-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch | 31 ++++ ...eferred_failback_tick-for-reload-rem.patch | 35 +++++ ...ipathd-fix-an-unsigned-int-ovwerflow.patch | 28 ++++ ...id-Wcast-function-type-mismatch-erro.patch | 36 +++++ 0018-Update-NEWS.md-for-0.10.1.patch | 44 ++++++ ...-t-print-error-message-if-WATCHDOG_U.patch | 30 ++++ ...uce-log-level-of-map-X-has-multiple-.patch | 38 +++++ ...eign-fix-memory-leak-in-nvme-foreign.patch | 54 +++++++ ...-condition-for-enqueueing-path-to-io.patch | 41 ++++++ ...dditional-NEWS.md-updates-for-0.10.1.patch | 63 ++++++++ ...multipath-fix-handling-of-pp-pgindex.patch | 138 ++++++++++++++++++ ...e-pgcmp-detect-if-map-is-missing-a-p.patch | 70 +++++++++ ...gger-uevents-upon-map-creation-in-do.patch | 94 ++++++++++++ ...er-uevents-upon-map-removal-in-coale.patch | 41 ++++++ ...h-Don-t-skip-set_path_max_sectors_kb.patch | 31 ++++ ...p-static-analyzer-complaint-in-init_.patch | 27 ++++ ...lenient-in-allowing-the-alua-based-p.patch | 44 ++++++ 0031-Update-NEWS.md-for-0.10.2.patch | 64 ++++++++ ...-fix-abi-stable.yaml-for-pull-reques.patch | 61 ++++++++ ... 0033-RH-fixup-udev-rules-for-redhat.patch | 0 ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 4 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ... 0037-RH-use-rpm-optflags-if-present.patch | 3 +- ...hconf.patch => 0038-RH-add-mpathconf.patch | 12 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 0 ...-default-find_mutipaths-value-to-off.patch | 0 ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 2 +- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...-RH-compile-with-libreadline-support.patch | 2 +- ...up.patch => 0045-RH-Add-mpathcleanup.patch | 0 device-mapper-multipath.spec | 65 +++++++-- 46 files changed, 1905 insertions(+), 26 deletions(-) create mode 100644 0001-GitHub-workflows-use-upload-download-artifact-v4.patch create mode 100644 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch create mode 100644 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch create mode 100644 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch create mode 100644 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch create mode 100644 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch create mode 100644 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch create mode 100644 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch create mode 100644 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch create mode 100644 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch create mode 100644 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch create mode 100644 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch create mode 100644 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch create mode 100644 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch create mode 100644 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch create mode 100644 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch create mode 100644 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch create mode 100644 0018-Update-NEWS.md-for-0.10.1.patch create mode 100644 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch create mode 100644 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch create mode 100644 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch create mode 100644 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch create mode 100644 0023-Additional-NEWS.md-updates-for-0.10.1.patch create mode 100644 0024-libmultipath-fix-handling-of-pp-pgindex.patch create mode 100644 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch create mode 100644 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch create mode 100644 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch create mode 100644 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch create mode 100644 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch create mode 100644 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch create mode 100644 0031-Update-NEWS.md-for-0.10.2.patch create mode 100644 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch rename 0001-RH-fixup-udev-rules-for-redhat.patch => 0033-RH-fixup-udev-rules-for-redhat.patch (100%) rename 0002-RH-Remove-the-property-blacklist-exception-builtin.patch => 0034-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0003-RH-don-t-start-without-a-config-file.patch => 0035-RH-don-t-start-without-a-config-file.patch (98%) rename 0004-RH-Fix-nvme-function-missing-argument.patch => 0036-RH-Fix-nvme-function-missing-argument.patch (100%) rename 0005-RH-use-rpm-optflags-if-present.patch => 0037-RH-use-rpm-optflags-if-present.patch (97%) rename 0006-RH-add-mpathconf.patch => 0038-RH-add-mpathconf.patch (99%) rename 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (100%) rename 0008-RH-reset-default-find_mutipaths-value-to-off.patch => 0040-RH-reset-default-find_mutipaths-value-to-off.patch (100%) rename 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (98%) rename 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) rename 0012-RH-compile-with-libreadline-support.patch => 0044-RH-compile-with-libreadline-support.patch (96%) rename 0013-RH-Add-mpathcleanup.patch => 0045-RH-Add-mpathcleanup.patch (100%) diff --git a/0001-GitHub-workflows-use-upload-download-artifact-v4.patch b/0001-GitHub-workflows-use-upload-download-artifact-v4.patch new file mode 100644 index 0000000..c8247ca --- /dev/null +++ b/0001-GitHub-workflows-use-upload-download-artifact-v4.patch @@ -0,0 +1,122 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 09:09:19 +0200 +Subject: [PATCH] GitHub workflows: use {upload,download}-artifact@v4 + +The @v1 releases are deprecated. +https://github.blog/changelog/2024-02-13-deprecation-notice-v1-and-v2-of-the-artifact-actions/ + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 6 ++++-- + .github/workflows/foreign.yaml | 15 +++++++-------- + .github/workflows/native.yaml | 5 +++-- + 3 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 393322e5..dce09f5c 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -45,10 +45,11 @@ jobs: + - name: create ABI + run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + - name: save ABI +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: abi + path: abi ++ overwrite: true + - name: compare ABI against reference + id: compare + continue-on-error: true +@@ -56,10 +57,11 @@ jobs: + run: make abi-test + - name: save differences + if: ${{ steps.compare.outcome == 'failure' }} +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: abi-test + path: abi-test ++ overwrite: true + + - name: fail + # MUST use >- here, otherwise the condition always evaluates to true +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 9e4d35e0..d68650df 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -36,14 +36,13 @@ jobs: + - name: checkout + uses: actions/checkout@v1 + - name: build +- run: make -j8 -Orecurse test-progs +- - name: create binary archive +- run: make test-progs.tar ++ run: make -j -Orecurse test-progs.tar + - name: upload binary archive +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: cross-${{ matrix.os }}-${{ matrix.arch }} + path: test-progs.tar ++ overwrite: true + + test: + runs-on: ubuntu-22.04 +@@ -61,11 +60,11 @@ jobs: + run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV + if: ${{ matrix.arch == 'armhf' }} + - name: download binary archive +- uses: actions/download-artifact@v1 ++ uses: actions/download-artifact@v4 + with: + name: cross-${{ matrix.os }}-${{ matrix.arch }} + - name: unpack binary archive +- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar ++ run: tar xfv test-progs.tar + - name: enable foreign arch + uses: dbhi/qus/action@main + - name: run tests +@@ -100,11 +99,11 @@ jobs: + run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV + if: ${{ matrix.arch == 'armhf' }} + - name: download binary archive +- uses: actions/download-artifact@v1 ++ uses: actions/download-artifact@v4 + with: + name: cross-${{ matrix.os }}-${{ matrix.arch }} + - name: unpack binary archive +- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar ++ run: tar xfv test-progs.tar + - name: enable foreign arch + uses: dbhi/qus/action@main + - name: run tests +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 80ff6df5..500becaa 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -57,10 +57,11 @@ jobs: + - name: create binary archive + run: make ${{ env.ARCHIVE_TGT }} + - name: upload binary archive +- uses: actions/upload-artifact@v1 ++ uses: actions/upload-artifact@v4 + with: + name: native-${{ matrix.os }} + path: ${{ env.ARCHIVE_TGT }} ++ overwrite: true + + - name: clean + run: make clean +@@ -98,7 +99,7 @@ jobs: + uses: actions/checkout@v1 + + - name: download binary archive +- uses: actions/download-artifact@v1 ++ uses: actions/download-artifact@v4 + with: + name: native-${{ matrix.os }} + - name: unpack binary archive diff --git a/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch b/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch new file mode 100644 index 0000000..423bf56 --- /dev/null +++ b/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 09:10:38 +0200 +Subject: [PATCH] GitHub workflows: update dawidd6/action-download-artifact + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index dce09f5c..d5f8b477 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -28,7 +28,7 @@ jobs: + - name: get reference ABI + id: reference + continue-on-error: true +- uses: dawidd6/action-download-artifact@v2 ++ uses: dawidd6/action-download-artifact@v6 + with: + workflow: abi.yaml + branch: ${{ env.ABI_BRANCH }} diff --git a/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch b/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch new file mode 100644 index 0000000..63aa273 --- /dev/null +++ b/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 09:45:25 +0200 +Subject: [PATCH] Github workflows: native.yml: use mosteo-actions/docker-run + +We can't use "container:" any more because upload-artifact@v4 doesn't +work on Debian Jessie. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 45 +++++++++++++++++++++-------------- + 1 file changed, 27 insertions(+), 18 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 500becaa..70d01c55 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -35,17 +35,9 @@ jobs: + - debian-bookworm + - fedora-40 + - opensuse-leap +- container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} + steps: + - name: checkout + uses: actions/checkout@v1 +- - name: build and test +- if: ${{ matrix.os != 'debian-jessie' }} +- run: make -j -Orecurse test +- - name: build and test (jessie) +- # On jessie, we use libreadline 5 (no licensing issue) +- if: ${{ matrix.os == 'debian-jessie' }} +- run: make -j -Orecurse READLINE=libreadline test + + - name: set archive name + # Leap containers have cpio but not tar +@@ -54,8 +46,21 @@ jobs: + - name: set archive name + run: echo ARCHIVE_TGT=test-progs.tar >> $GITHUB_ENV + if: ${{ matrix.os != 'opensuse-leap' }} +- - name: create binary archive +- run: make ${{ env.ARCHIVE_TGT }} ++ ++ - name: build and test ++ if: ${{ matrix.os != 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test ++ - name: build and test (jessie) ++ # On jessie, we use libreadline 5 (no licensing issue) ++ if: ${{ matrix.os == 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test ++ + - name: upload binary archive + uses: actions/upload-artifact@v4 + with: +@@ -67,14 +72,18 @@ jobs: + run: make clean + - name: clang + if: ${{ matrix.os != 'debian-jessie' }} +- env: +- CC: clang +- run: make -j -Orecurse test ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ params: -e CC=clang ++ command: -j -Orecurse test + - name: clang (jessie) + if: ${{ matrix.os == 'debian-jessie' }} +- env: +- CC: clang +- run: make READLINE=libreadline test ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ params: -e CC=clang ++ command: -j -Orecurse READLINE=libreadline test + + root-test: + runs-on: ubuntu-22.04 +@@ -103,10 +112,10 @@ jobs: + with: + name: native-${{ matrix.os }} + - name: unpack binary archive +- run: cpio -idv < native-${{ matrix.os }}/test-progs.cpio ++ run: cpio -idv < test-progs.cpio + if: ${{ matrix.os == 'opensuse-leap' }} + - name: unpack binary archive +- run: tar xfmv native-${{ matrix.os }}/test-progs.tar ++ run: tar xfmv test-progs.tar + if: ${{ matrix.os != 'opensuse-leap' }} + + - name: run root tests diff --git a/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch b/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch new file mode 100644 index 0000000..e6d618c --- /dev/null +++ b/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 10:17:17 +0200 +Subject: [PATCH] GitHub workflows: native.yml: use extra job for clang + +Running "make" in a container and "make clean" outside doesn't +work (access right issues). So just use separate jobs. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 70d01c55..95b53b87 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -68,8 +68,22 @@ jobs: + path: ${{ env.ARCHIVE_TGT }} + overwrite: true + +- - name: clean +- run: make clean ++ clang: ++ runs-on: ubuntu-22.04 ++ strategy: ++ fail-fast: false ++ matrix: ++ os: ++ - debian-jessie ++ - debian-buster ++ - debian-bullseye ++ - debian-bookworm ++ - fedora-40 ++ - opensuse-leap ++ steps: ++ - name: checkout ++ uses: actions/checkout@v1 ++ + - name: clang + if: ${{ matrix.os != 'debian-jessie' }} + uses: mosteo-actions/docker-run@v1 diff --git a/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch b/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch new file mode 100644 index 0000000..cabfbcf --- /dev/null +++ b/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 13 Sep 2024 10:30:47 +0200 +Subject: [PATCH] GitHub workflows: native.yaml: make test and archive + separately + +Avoid "text file busy" error on GitHub. + +dmevents-test: Text file busy +Makefile:74: recipe for target 'dmevents.out' failed + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 95b53b87..f06b09df 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -52,14 +52,27 @@ jobs: + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} +- command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test ++ command: -j -Orecurse test + - name: build and test (jessie) + # On jessie, we use libreadline 5 (no licensing issue) + if: ${{ matrix.os == 'debian-jessie' }} + uses: mosteo-actions/docker-run@v1 + with: + image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} +- command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test ++ command: -j -Orecurse READLINE=libreadline test ++ ++ - name: create ${{ env.ARCHIVE_TGT }} ++ if: ${{ matrix.os != 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: ${{ env.ARCHIVE_TGT }} ++ - name: create ${{ env.ARCHIVE_TGT }} (jessie) ++ if: ${{ matrix.os == 'debian-jessie' }} ++ uses: mosteo-actions/docker-run@v1 ++ with: ++ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} ++ command: READLINE=libreadline ${{ env.ARCHIVE_TGT }} + + - name: upload binary archive + uses: actions/upload-artifact@v4 diff --git a/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch b/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch new file mode 100644 index 0000000..4a9b254 --- /dev/null +++ b/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch @@ -0,0 +1,133 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 16:02:38 +0100 +Subject: [PATCH] GitHub workflows: enable unit tests for stable branches + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 2 ++ + .github/workflows/foreign.yaml | 2 ++ + .github/workflows/multiarch-stable.yaml | 2 ++ + .github/workflows/multiarch.yaml | 2 ++ + .github/workflows/native.yaml | 2 ++ + .github/workflows/rolling.yaml | 2 ++ + 6 files changed, 12 insertions(+) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index a838f9a2..1a727e14 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -5,10 +5,12 @@ on: + - master + - queue + - tip ++ - 'stable-*' + pull_request: + branches: + - master + - queue ++ - 'stable-*' + jobs: + jammy: + runs-on: ubuntu-22.04 +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index d68650df..0f80957b 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/foreign.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/foreign.yaml' + - '**.h' +diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml +index e51d383c..ffede53d 100644 +--- a/.github/workflows/multiarch-stable.yaml ++++ b/.github/workflows/multiarch-stable.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/multiarch-stable.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/multiarch-stable.yaml' + - '**.h' +diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml +index df95a02f..d2b833a4 100644 +--- a/.github/workflows/multiarch.yaml ++++ b/.github/workflows/multiarch.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/multiarch.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/multiarch.yaml' + - '**.h' +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index f06b09df..c9d9df9e 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/native.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/native.yaml' + - '**.h' +diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml +index 3536b944..66af7a44 100644 +--- a/.github/workflows/rolling.yaml ++++ b/.github/workflows/rolling.yaml +@@ -5,6 +5,7 @@ on: + - master + - queue + - tip ++ - 'stable-*' + paths: + - '.github/workflows/rolling.yaml' + - '**.h' +@@ -15,6 +16,7 @@ on: + branches: + - master + - queue ++ - 'stable-*' + paths: + - '.github/workflows/rolling.yaml' + - '**.h' diff --git a/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch b/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch new file mode 100644 index 0000000..c19980f --- /dev/null +++ b/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch @@ -0,0 +1,110 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 16:51:05 +0100 +Subject: [PATCH] GitHub Workflows: add abi check for stable branches + +The ABI should never change on a stable branch. This workflow +asserts that. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi-stable.yaml | 89 +++++++++++++++++++++++++++++++ + 1 file changed, 89 insertions(+) + create mode 100644 .github/workflows/abi-stable.yaml + +diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml +new file mode 100644 +index 00000000..a6746f23 +--- /dev/null ++++ b/.github/workflows/abi-stable.yaml +@@ -0,0 +1,89 @@ ++name: check-abi for stable branch ++on: ++ push: ++ branches: ++ - 'stable-*' ++ paths: ++ - '.github/workflows/abi-stable.yaml' ++ - '**.h' ++ - '**.c' ++ - '**.version' ++ pull_request: ++ branches: ++ - 'stable-*' ++ workflow_dispatch: ++ ++jobs: ++ reference-abi: ++ runs-on: ubuntu-20.04 ++ steps: ++ - name: get parent tag ++ run: > ++ echo ${{ github.ref }} | ++ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ - name: assert parent tag ++ run: /bin/false ++ if: ${{ env.PARENT_TAG == '' }} ++ - name: update ++ run: sudo apt-get update ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc ++ gcc make pkg-config abigail-tools ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev ++ - name: checkout ${{ env.PARENT_TAG }} ++ uses: actions/checkout@v4 ++ with: ++ ref: ${{ env.PARENT_TAG }} ++ - name: build ABI for ${{ env.PARENT_TAG }} ++ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi ++ - name: save ABI ++ uses: actions/upload-artifact@v4 ++ with: ++ name: multipath-abi-${{ env.PARENT_TAG }} ++ path: abi ++ ++ check-abi: ++ runs-on: ubuntu-20.04 ++ needs: reference-abi ++ steps: ++ - name: get parent tag ++ run: > ++ echo ${{ github.ref }} | ++ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ - name: assert parent tag ++ run: /bin/false ++ if: ${{ env.PARENT_TAG == '' }} ++ - name: checkout ${{ env.PARENT_TAG }} ++ uses: actions/checkout@v4 ++ with: ++ ref: ${{ env.PARENT_TAG }} ++ - name: download ABI for ${{ env.PARENT_TAG }} ++ id: download_abi ++ uses: actions/download-artifact@v4 ++ with: ++ name: multipath-abi-${{ env.PARENT_TAG }} ++ path: reference-abi ++ - name: update ++ run: sudo apt-get update ++ if: steps.download_abi.outcome != 'success' ++ - name: dependencies ++ run: > ++ sudo apt-get install --yes gcc ++ gcc make pkg-config abigail-tools ++ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev ++ - name: check ABI of ${{ github.ref }} against ${{ env.PARENT_TAG }} ++ id: check_abi ++ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi-test ++ continue-on-error: true ++ - name: save differences ++ if: ${{ steps.check_abi.outcome != 'success' }} ++ uses: actions/upload-artifact@v4 ++ with: ++ name: abi-test ++ path: abi-test ++ - name: fail ++ run: /bin/false ++ if: steps.check_abi.outcome != 'success' diff --git a/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch b/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch new file mode 100644 index 0000000..88122b0 --- /dev/null +++ b/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 12 Nov 2024 13:06:10 +0100 +Subject: [PATCH] libmultipath: dm_get_maps(): don't bail out for single-map + failures + +dm_get_maps() traverses the entire list of dm maps. We shouldn't +give up just because probing a single map failed. + +Fixes: bf3a4ad ("libmultipath: simplify dm_get_maps()") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index c497c225..52bfe9ce 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1262,10 +1262,8 @@ int dm_get_maps(vector mp) + } + vector_set_slot(mp, mpp); + break; +- case DMP_NO_MATCH: +- break; + default: +- return 1; ++ break; + } + next = names->next; + names = (void *) names + next; diff --git a/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch b/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch new file mode 100644 index 0000000..b380f75 --- /dev/null +++ b/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 31 Oct 2024 12:08:08 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: import DM_COLDPLUG_SUSPENDED only once + +We import DM_COLDPLUG_SUSPENDED in all code flows below mpath_coldplug_end. +Clarify this in the code. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 30647b99..67838261 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -24,12 +24,13 @@ ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ + ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" + LABEL="mpath_coldplug_end" + ++IMPORT{db}="DM_COLDPLUG_SUSPENDED" ++ + # If this uevent didn't come from dm, don't try to update the + # device state + # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the + # device below at mpath_is_ready, which is correct. + ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ +- IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ + GOTO="check_mpath_ready" + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" +@@ -67,7 +68,6 @@ LABEL="check_mpath_unchanged" + # A previous coldplug event occurred while the device was suspended. + # Activation might have been partially skipped. Activate the device now, + # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. +-IMPORT{db}="DM_COLDPLUG_SUSPENDED" + ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ + ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ diff --git a/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch b/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch new file mode 100644 index 0000000..f34e699 --- /dev/null +++ b/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 31 Oct 2024 12:59:03 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: handle inactive suspended devices + correctly + +Since b22c273 ("11-dm-mpath.rules: Don't force activation while device is +suspended"), we've handled the case where a device is suspended while +an uevent is processed (e.g. because multipathd is reloading the +map again at the same time). But we were missing the case where +The device had never been initialized before. If .MPATH_DEVICE_READY_OLD +was empty, we'd jump to scan_import without setting MPATH_DEVICE_READY +to 0. This can cause a device not to be fully activated at boot time, +because in follow-up uevents we'd assume that the device had already +been set up. + +Treat the case in which an uevent is processed for a previously not +fully set-up, suspended device like other situations where we set +MPATH_DEVICE_READY to 0. + +Fixes: b22c273 ("11-dm-mpath.rules: Don't force activation while device is +suspended") +Reviewed-by: Benjamin Marzinski + +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 67838261..20f8c6ac 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -35,6 +35,13 @@ ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ + + ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" + ++# If the device wasn't ready previously and is currently suspended, ++# we have to postpone the activation until the next event. ++# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the ++# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. ++ENV{.MPATH_DEVICE_READY_OLD}!="1", ENV{.DM_SUSPENDED}=="1", \ ++ ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" ++ + # multipath sets DM_SUBSYSTEM_UDEV_FLAG2 when it reloads a + # table with no active devices. If this happens, mark the + # device not ready +@@ -106,14 +113,10 @@ GOTO="scan_import" + LABEL="mpath_is_ready" + + # If the device comes back online, set DM_ACTIVATION so that +-# upper layers do a rescan. If the device is currently suspended, +-# we have to postpone the activation until the next event. +-# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the +-# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. +-ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" +-ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" +- +-ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" ++# upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD ++# is just empty (see comment above the DM_COOKIE test above). ++ENV{.MPATH_DEVICE_READY_OLD}=="0", \ ++ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or diff --git a/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch b/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch new file mode 100644 index 0000000..cb129bf --- /dev/null +++ b/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch @@ -0,0 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 31 Oct 2024 13:11:21 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: clarify DM_ACTIVATION logic + +Our code is always setting MPATH_UNCHANGED and DM_ACTIVATION in +pairs. While DM_ACTIVATION is a global DM property, MPATH_UNCHANGED +is owned by us. Just set MPATH_UNCHANGED, and adapt DM_ACTIVATION +when necessary just in one place. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 20f8c6ac..a2655cb2 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -74,25 +74,25 @@ LABEL="check_mpath_unchanged" + + # A previous coldplug event occurred while the device was suspended. + # Activation might have been partially skipped. Activate the device now, +-# i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. ++# i.e. disable the MPATH_UNCHANGED logic. + ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ +- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ ++ ENV{MPATH_UNCHANGED}="0", \ + PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ + GOTO="check_mpath_ready" + + # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. +-# Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its ++# Set the MPATH_UNCHANGED flag here as mpath reloads tables if any of its + # paths are lost/recovered. For any stack above the mpath device, this is not + # something that should be reacted upon since it would be useless extra work. + # It's exactly mpath's job to provide *seamless* device access to any of the + # paths that are available underneath. + ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ +- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" ++ ENV{MPATH_UNCHANGED}="1" + +-# For path failed or reinstated events, unset DM_ACTIVATION. ++# For path failed or reinstated events, set MPATH_UNCHANGED. + # This is similar to the DM_SUBSYSTEM_UDEV_FLAG0 case above. + ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ +- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" ++ ENV{MPATH_UNCHANGED}="1" + + LABEL="check_mpath_ready" + +@@ -112,11 +112,10 @@ GOTO="scan_import" + + LABEL="mpath_is_ready" + +-# If the device comes back online, set DM_ACTIVATION so that ++# If the device comes back online, clear MPATH_UNCHANGED so that + # upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD + # is just empty (see comment above the DM_COOKIE test above). +-ENV{.MPATH_DEVICE_READY_OLD}=="0", \ +- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" ++ENV{.MPATH_DEVICE_READY_OLD}=="0", ENV{MPATH_UNCHANGED}="0" + + # The code to check multipath state ends here. We need to set + # properties and symlinks regardless whether the map is usable or +@@ -146,6 +145,10 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" + + LABEL="import_end" + ++# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. ++ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" ++ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" ++ + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now + ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" + diff --git a/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch b/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch new file mode 100644 index 0000000..cb1620a --- /dev/null +++ b/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sun, 3 Nov 2024 23:04:08 +0100 +Subject: [PATCH] 11-dm-mpath-rules.in: skip one .DM_NOSCAN check + +We set .DM_NOSCAN above where we set DM_UDEV_DISABLE_OTHER_RULES_FLAG, too. If +the latter isn't set, .DM_NOSCAN can't be set. Skip the redundant test. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index a2655cb2..79227bec 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -132,7 +132,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" + ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" + + # Don't import the properties from db if we will run blkid later. +-ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" ++ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" + + IMPORT{db}="ID_FS_TYPE" + IMPORT{db}="ID_FS_USAGE" diff --git a/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch b/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch new file mode 100644 index 0000000..36cd91d --- /dev/null +++ b/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sun, 3 Nov 2024 23:07:23 +0100 +Subject: [PATCH] 11-dm-mpath.rules.in: set .DM_NOSCAN if MPATH_UNCHANGED is + set + +When multipath reloads a device or fails or restores a path, the udev +rules disable LVM scanning, but since .DM_NOSCAN isn't set, blkid is +still run on the device. When multipath devices that are set to +queue_if_no_path lose all their paths at close to the same time, udev +workers can hang trying to run blkid. The blkid results shouldn't +change when multipathd is adding, removing, failing or reinstating +paths, aside from avoiding hanging udev processes, we're skipping +unnecessary work. + +Hence, set .DM_NOSCAN if MPATH_UNCHANGED is set, to avoid blkid from +being called in 13-dm.rules. + +Suggested-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/11-dm-mpath.rules.in | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in +index 79227bec..a816edbf 100644 +--- a/multipath/11-dm-mpath.rules.in ++++ b/multipath/11-dm-mpath.rules.in +@@ -145,9 +145,11 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" + + LABEL="import_end" + +-# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. ++# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION and DM_NOSCAN. ++# .DM_NOSCAN controls whether blkid will be run in 13-dm-disk.rules; ++# we don't want to do that if MPATH_UNCHANGED is 1. + ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" +-ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" ++ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0", ENV{.DM_NOSCAN}="1" + + # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now + ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" diff --git a/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch b/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch new file mode 100644 index 0000000..b7ae3c4 --- /dev/null +++ b/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 7 Nov 2024 22:07:03 +0100 +Subject: [PATCH] libmultipath: don't set dev_loss_tmo to 0 for + NO_PATH_RETRY_FAIL + +If pp->dev_loss is DEV_LOSS_TMO_UNSET and min_dev_loss is 0 (which is +the case if no_path_retry is NO_PATH_RETRY_FAIL or NO_PATH_RETRY_UNDEF), +we will set pp->dev_loss to 0, which is wrong. Fix it. + +Fixes: 058b5f5 ("libmultipath: fix dev_loss_tmo even if not set in configuration") +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index e94705bf..5043330c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -942,7 +942,7 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) + continue; + } + +- if (pp->dev_loss == DEV_LOSS_TMO_UNSET) ++ if (pp->dev_loss == DEV_LOSS_TMO_UNSET && min_dev_loss != 0) + pp->dev_loss = min_dev_loss; + else if (pp->dev_loss < min_dev_loss) { + pp->dev_loss = min_dev_loss; diff --git a/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch b/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch new file mode 100644 index 0000000..f775e85 --- /dev/null +++ b/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 14 Oct 2024 23:28:30 -0400 +Subject: [PATCH] multipathd: fix deferred_failback_tick for reload removes + +If reload_and_sync_map() removes the multipath device, +deferred_failback_tick() needs to decrement the counter so that it +doesn't skip the following device. + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 1b7fd04f..e4ef9a1d 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2080,9 +2080,12 @@ deferred_failback_tick (struct vectors *vecs) + + if (!mpp->failback_tick && + need_switch_pathgroup(mpp, &need_reload)) { +- if (need_reload) +- reload_and_sync_map(mpp, vecs); +- else ++ if (need_reload) { ++ if (reload_and_sync_map(mpp, vecs) == 2) { ++ /* multipath device removed */ ++ i--; ++ } ++ } else + switch_pathgroup(mpp); + } + } diff --git a/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch b/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch new file mode 100644 index 0000000..12c9a51 --- /dev/null +++ b/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 13 Nov 2024 16:19:49 +0100 +Subject: [PATCH] multipathd: fix an unsigned int ovwerflow + +Reported by coverity: "i--" may cause an underflow, which will again +cause an overflow when the loop continues. Use a signed int for +loops like this to make coverity happy. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index e4ef9a1d..3fb623fd 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2068,7 +2068,7 @@ static void + deferred_failback_tick (struct vectors *vecs) + { + struct multipath * mpp; +- unsigned int i; ++ int i; + bool need_reload; + + vector_foreach_slot (vecs->mpvec, mpp, i) { diff --git a/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch b/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch new file mode 100644 index 0000000..64b90d7 --- /dev/null +++ b/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Nov 2024 22:17:16 +0100 +Subject: [PATCH] libmpathutil: avoid -Wcast-function-type-mismatch error with + clang 19 + +Avoid the following error with clang 19: + +msort.c:268:27: error: cast from '__compar_fn_t' (aka 'int (*)(const void *, const void *)') to '__compar_d_fn_t' (aka 'int (*)(const void *, const void *, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-mismatch] + 268 | return msort_r (b, n, s, (__compar_d_fn_t)cmp, NULL); + | ^~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathutil/msort.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libmpathutil/msort.c b/libmpathutil/msort.c +index 50f799d9..9df7b267 100644 +--- a/libmpathutil/msort.c ++++ b/libmpathutil/msort.c +@@ -259,9 +259,12 @@ msort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) + * If this is safe for them, it should be for us, too. + */ + #pragma GCC diagnostic push +-#if __GNUC__ >= 8 ++#if __GNUC__ >= 8 || __clang_major__ >= 19 + #pragma GCC diagnostic ignored "-Wcast-function-type" + #endif ++#if __clang_major__ >= 19 ++#pragma GCC diagnostic ignored "-Wcast-function-type-mismatch" ++#endif + void + msort (void *b, size_t n, size_t s, __compar_fn_t cmp) + { diff --git a/0018-Update-NEWS.md-for-0.10.1.patch b/0018-Update-NEWS.md-for-0.10.1.patch new file mode 100644 index 0000000..601b6e5 --- /dev/null +++ b/0018-Update-NEWS.md-for-0.10.1.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 17:59:14 +0100 +Subject: [PATCH] Update NEWS.md for 0.10.1 + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + NEWS.md | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/NEWS.md b/NEWS.md +index 69acda47..b740efb1 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -1,5 +1,28 @@ + # multipath-tools Release Notes + ++## multipath-tools 0.10.1, 2024/11 ++ ++This is the first bug fix release on the `stable-0.10.y` branch. It contains ++bug fixes from 0.11.0, and some CI-related fixes. ++ ++### Bug fixes ++ ++* Fixed the problem that multipathd wouldn't start on systems with certain types ++ of device mapper devices, in particular devices with multiple DM targets. ++ The problem was introduced in 0.10.0. ++ Fixes [#102](https://github.com/opensvc/multipath-tools/issues/102). ++* Fixed a corner case in the udev rules which could cause a device not to be ++ activated during boot if a cold plug uevent is processed for a previously ++ not configured multipath map while this map was suspended. This problem existed ++ since 0.9.8. ++* Fixed the problem that devices with `no_path_retry fail` and no setting ++ for `dev_loss_tmo` might get the `dev_loss_tmo` set to 0, causing the ++ device to be deleted immediately in the event of a transport disruption. ++ This bug was introduced in 0.9.6. ++* Fixed the problem that, if there were multiple maps with deferred failback ++ (`failback` value > 0 in `multipath.conf`), some maps might fail back later ++ than configured. The problem existed since 0.9.6. ++ + ## multipath-tools 0.10.0, 2024/08 + + ### User-Visible Changes diff --git a/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch b/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch new file mode 100644 index 0000000..18fb614 --- /dev/null +++ b/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 14 Nov 2024 15:20:24 +0100 +Subject: [PATCH] libmultipath: don't print error message if WATCHDOG_USEC is 0 + +WATCHDOG_USEC may be set to 0, which means that the watchdog +is disabled in systemd. + +Fixes: 9366cfb ("multipathd: Implement systemd watchdog integration") +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 0e3a5cc1..226ddecb 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -865,6 +865,9 @@ static void set_max_checkint_from_watchdog(struct config *conf) + unsigned long checkint; + + if (envp && sscanf(envp, "%lu", &checkint) == 1) { ++ if (checkint == 0) ++ /* watchdog disabled */ ++ return; + /* Value is in microseconds */ + checkint /= 1000000; + if (checkint < 1 || checkint > UINT_MAX) { diff --git a/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch b/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch new file mode 100644 index 0000000..7467627 --- /dev/null +++ b/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Nov 2024 18:01:32 +0100 +Subject: [PATCH] libmultipath: reduce log level of "map X has multiple + targets" + +On systems with LVM volumes, "multipath -ll" will spit out lots of messages +like + + libmp_mapinfo: map vg-lv0 has multiple targets + +which is irritating. Reduce the log level of these messages to 3, as they +are harmless most of the time. + +This is a backport of e8949c2 ("libmultipath: reduce log level of +libmp_mapinfo() messages") from the master branch. We can't apply exactly +the same fix because the stable branch is missing 8c772d3 ("libmultipath: +check DM UUID earlier in libmp_mapinfo__"). + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 52bfe9ce..fe5637b3 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -718,7 +718,7 @@ static int libmp_mapinfo__(int flags, mapid_t id, mapinfo_t info, const char *ma + if (info.target || info.status || info.size || flags & MAPINFO_TGT_TYPE__) { + if (dm_get_next_target(dmt, NULL, &start, &length, + &target_type, ¶ms) != NULL) { +- condlog(2, "%s: map %s has multiple targets", fname__, map_id); ++ condlog(3, "%s: map %s has multiple targets", fname__, map_id); + return DMP_NOT_FOUND; + } + if (!params) { diff --git a/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch b/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch new file mode 100644 index 0000000..2610c6d --- /dev/null +++ b/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 8 Jan 2025 19:06:53 -0500 +Subject: [PATCH] libmultipath/foreign: fix memory leak in nvme foreign handler + +_find_controllers() needs to free the udev device if it doesn't get +added to a path. Otherwise it can leak memory whenever check_foreign() +is called, causing multipathd's memory usage to continually grow. + +Fixes: 7b47762 ("libmultipath: nvme: fix path detection for kernel 4.16") +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit 5a3d334e416a4a35ee88d7b8f1433ff7f57923ad) +--- + libmultipath/foreign/nvme.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c +index 0b7f4eab..cde660ce 100644 +--- a/libmultipath/foreign/nvme.c ++++ b/libmultipath/foreign/nvme.c +@@ -675,7 +675,8 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + pthread_cleanup_push_cast(free_scandir_result, &sr); + for (i = 0; i < r; i++) { + char *fn = di[i]->d_name; +- struct udev_device *ctrl, *udev; ++ struct udev_device *ctrl; ++ struct udev_device *udev __attribute__((cleanup(cleanup_udev_device))) = NULL; + + if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, "/%s", fn)) + continue; +@@ -719,11 +720,11 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + continue; + + path->gen.ops = &nvme_path_ops; +- path->udev = udev; ++ path->udev = steal_ptr(udev); + path->seen = true; + path->map = map; + path->ctl = udev_device_get_parent_with_subsystem_devtype +- (udev, "nvme", NULL); ++ (path->udev, "nvme", NULL); + if (path->ctl == NULL) { + condlog(1, "%s: %s: failed to get controller for %s", + __func__, THIS, fn); +@@ -744,7 +745,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + } + vector_set_slot(&map->pgvec, &path->pg); + condlog(3, "%s: %s: new path %s added to %s", +- __func__, THIS, udev_device_get_sysname(udev), ++ __func__, THIS, udev_device_get_sysname(path->udev), + udev_device_get_sysname(map->udev)); + } + pthread_cleanup_pop(1); diff --git a/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch b/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch new file mode 100644 index 0000000..cf8d80a --- /dev/null +++ b/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chenrenhui +Date: Fri, 10 Jan 2025 14:38:16 +0800 +Subject: [PATCH] libmultipath: add condition for enqueueing path to io error + check + +In function io_err_stat_handle_pathfail(), path->io_err_dis_reinstate_time +is set to 0 to enqueue path to io error check as soon as possible. But +multipathd can not do it within marginal_path_err_recheck_gap_time seconds +after power-on, because curr_time is less than +marginal_path_err_recheck_gap_time. + +To handle the early marginal path, we can enqueue path when +io_err_dis_reinstate_time is 0. + +Signed-off-by: chenrenhui +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck + +> + +(cherry picked from commit a1e3cf2d42cc4bab10753e466c8adb7efa83c99e) +Signed-off-by: Benjamin Marzinski +--- + libmultipath/io_err_stat.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c +index 4996c0b0..879c310a 100644 +--- a/libmultipath/io_err_stat.c ++++ b/libmultipath/io_err_stat.c +@@ -367,7 +367,8 @@ int need_io_err_check(struct path *pp) + return 1; + get_monotonic_time(&curr_time); + if ((curr_time.tv_sec - pp->io_err_dis_reinstate_time) > +- pp->mpp->marginal_path_err_recheck_gap_time) { ++ pp->mpp->marginal_path_err_recheck_gap_time || ++ pp->io_err_dis_reinstate_time == 0) { + io_err_stat_log(4, "%s: reschedule checking after %d seconds", + pp->dev, + pp->mpp->marginal_path_err_recheck_gap_time); diff --git a/0023-Additional-NEWS.md-updates-for-0.10.1.patch b/0023-Additional-NEWS.md-updates-for-0.10.1.patch new file mode 100644 index 0000000..1093bd0 --- /dev/null +++ b/0023-Additional-NEWS.md-updates-for-0.10.1.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 17 Jan 2025 22:38:26 +0100 +Subject: [PATCH] Additional NEWS.md updates for 0.10.1 + +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 4 ++-- + NEWS.md | 8 ++++++++ + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 934f582e..000d5ebb 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -184,7 +184,6 @@ sas + sbp + scsi + sda +-sdc + setmarginal + setprkey + setprstatus +@@ -205,11 +204,11 @@ suse + svg + switchgroup + sys ++SYSDIR + sysfs + sysinit + tcp + terabytes +-SYSDIR + TESTDEPS + testname + tgill +@@ -231,6 +230,7 @@ unsetprkey + unsetprstatus + unspec + usb ++USEC + userdata + userspace + usr +diff --git a/NEWS.md b/NEWS.md +index b740efb1..3c51553e 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -22,6 +22,14 @@ bug fixes from 0.11.0, and some CI-related fixes. + * Fixed the problem that, if there were multiple maps with deferred failback + (`failback` value > 0 in `multipath.conf`), some maps might fail back later + than configured. The problem existed since 0.9.6. ++* Removed a warning message that multipathd would print if systemd's ++ `WATCHDOG_USEC` environment variable had the value "0", which means that the ++ watchdog is simply disabled. This (minor) problem existed since 0.4.9. ++* Fixed a memory leak in the nvme foreign library. The bug existed since ++ 0.7.8. ++* Fixed a problem in the marginal path detection algorithm that could cause ++ the io error check for a recently failed path to be delayed. This bug ++ existed since 0.7.4. + + ## multipath-tools 0.10.0, 2024/08 + diff --git a/0024-libmultipath-fix-handling-of-pp-pgindex.patch b/0024-libmultipath-fix-handling-of-pp-pgindex.patch new file mode 100644 index 0000000..a9da346 --- /dev/null +++ b/0024-libmultipath-fix-handling-of-pp-pgindex.patch @@ -0,0 +1,138 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Nov 2024 13:11:07 +0100 +Subject: [PATCH] libmultipath: fix handling of pp->pgindex + +pp->pgindex is set in disassemble_map() when a map is parsed. +There are various possiblities for this index to become invalid. +pp->pgindex is only used in enable_group() and followover_should_fallback(), +and both callers take no action if it is 0, which is the right +thing to do if we don't know the path's pathgroup. + +Make sure pp->pgindex is reset to 0 in various places: +- when it's orphaned, +- before (re)grouping paths, +- when we detect a bad mpp assignment in update_pathvec_from_dm(). +- when a pathgroup is deleted in update_pathvec_from_dm(). In this + case, pgindex needs to be invalidated for all paths in all pathgroups + after the one that was deleted. + +The hunk in group_paths is mostly redundant with the hunk in free_pgvec(), but +because we're looping over pg->paths in the former and over pg->pgp in +the latter, I think it's better too play safe. + +Fixes: 99db1bd ("[multipathd] re-enable disabled PG when at least one path is up") +Fixes: https://github.com/opensvc/multipath-tools/issues/105 +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +(cherry picked from commit cd912cffa2797a18c47426c816afa8eb2eae5b22) +(cherry picked from commit 714c20bebba6911255a527d937e7a62764ffe338) +Signed-off-by: Benjamin Marzinski +--- + libmultipath/pgpolicies.c | 6 ++++++ + libmultipath/structs.c | 12 +++++++++++- + libmultipath/structs_vec.c | 15 +++++++++++++++ + 3 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c +index edc3c611..23ef2bdc 100644 +--- a/libmultipath/pgpolicies.c ++++ b/libmultipath/pgpolicies.c +@@ -127,6 +127,8 @@ fail: + int group_paths(struct multipath *mp, int marginal_pathgroups) + { + vector normal, marginal; ++ struct path *pp; ++ int i; + + if (!mp->pg) + mp->pg = vector_alloc(); +@@ -138,6 +140,10 @@ int group_paths(struct multipath *mp, int marginal_pathgroups) + if (!mp->pgpolicyfn) + goto fail; + ++ /* Reset pgindex, we're going to invalidate it */ ++ vector_foreach_slot(mp->paths, pp, i) ++ pp->pgindex = 0; ++ + if (!marginal_pathgroups || + split_marginal_paths(mp->paths, &normal, &marginal) != 0) { + if (mp->pgpolicyfn(mp, mp->paths) != 0) +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index 61c8f32c..48517252 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -239,8 +239,18 @@ free_pgvec (vector pgvec, enum free_path_mode free_paths) + if (!pgvec) + return; + +- vector_foreach_slot(pgvec, pgp, i) ++ vector_foreach_slot(pgvec, pgp, i) { ++ ++ /* paths are going to be re-grouped, reset pgindex */ ++ if (free_paths != FREE_PATHS) { ++ struct path *pp; ++ int j; ++ ++ vector_foreach_slot(pgp->paths, pp, j) ++ pp->pgindex = 0; ++ } + free_pathgroup(pgp, free_paths); ++ } + + vector_free(pgvec); + } +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 5df495b3..9dc5a5ca 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -108,6 +108,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + struct config *conf; + bool mpp_has_wwid; + bool must_reload = false; ++ bool pg_deleted = false; + + if (!mpp->pg) + return false; +@@ -125,6 +126,10 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + + vector_foreach_slot(pgp->paths, pp, j) { + ++ /* A pathgroup has been deleted before. Invalidate pgindex */ ++ if (pg_deleted) ++ pp->pgindex = 0; ++ + if (pp->mpp && pp->mpp != mpp) { + condlog(0, "BUG: %s: found path %s which is already in %s", + mpp->alias, pp->dev, pp->mpp->alias); +@@ -139,6 +144,13 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + must_reload = true; + dm_fail_path(mpp->alias, pp->dev_t); + vector_del_slot(pgp->paths, j--); ++ /* ++ * pp->pgindex has been set in disassemble_map(), ++ * which has probably been called just before for ++ * mpp. So he pgindex relates to mpp and may be ++ * wrong for pp->mpp. Invalidate it. ++ */ ++ pp->pgindex = 0; + continue; + } + pp->mpp = mpp; +@@ -237,6 +249,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + vector_del_slot(mpp->pg, i--); + free_pathgroup(pgp, KEEP_PATHS); + must_reload = true; ++ /* Invalidate pgindex for all other pathgroups */ ++ pg_deleted = true; + } + mpp->need_reload = mpp->need_reload || must_reload; + return must_reload; +@@ -354,6 +368,7 @@ void orphan_path(struct path *pp, const char *reason) + { + condlog(3, "%s: orphan path, %s", pp->dev, reason); + pp->mpp = NULL; ++ pp->pgindex = 0; + uninitialize_path(pp); + } + diff --git a/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch b/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch new file mode 100644 index 0000000..b2b9e48 --- /dev/null +++ b/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Mon, 25 Nov 2024 15:18:15 +0100 +Subject: [PATCH] libmultipath: make pgcmp detect if map is missing a path + group + +The previous algorithm didn't detect the case case where cpgp +contained a path that was not contained in pgp. Fix this. + +Cherry-picked from d4b35f61cb75c6e9b289e56c98457fc04ce4835e +Fixes: 90773ba ("libmultipath: resolve hash collisions in pgcmp()") +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index a7257981..e86c1fd5 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -426,6 +426,11 @@ compute_pgid(struct pathgroup * pgp) + pgp->id ^= (long)pp; + } + ++static void cleanup_bitfield(struct bitfield **p) ++{ ++ free(*p); ++} ++ + static int + pgcmp (struct multipath * mpp, struct multipath * cmpp) + { +@@ -433,16 +438,25 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) + struct pathgroup * pgp; + struct pathgroup * cpgp; + int r = 0; ++ struct bitfield *bf __attribute__((cleanup(cleanup_bitfield))) = NULL; + + if (!mpp) + return 0; + ++ if (VECTOR_SIZE(mpp->pg) != VECTOR_SIZE(cmpp->pg)) ++ return 1; ++ ++ bf = alloc_bitfield(VECTOR_SIZE(cmpp->pg)); ++ if (!bf) ++ return 1; ++ + vector_foreach_slot (mpp->pg, pgp, i) { + compute_pgid(pgp); + + vector_foreach_slot (cmpp->pg, cpgp, j) { + if (pgp->id == cpgp->id && + !pathcmp(pgp, cpgp)) { ++ set_bit_in_bitfield(j, bf); + r = 0; + break; + } +@@ -451,6 +465,10 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) + if (r) + return r; + } ++ vector_foreach_slot (cmpp->pg, cpgp, j) { ++ if (!is_bit_set_in_bitfield(j, bf)) ++ return 1; ++ } + return r; + } + diff --git a/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch b/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch new file mode 100644 index 0000000..bd3a7a4 --- /dev/null +++ b/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 26 Nov 2024 22:37:20 +0100 +Subject: [PATCH] libmultipath: trigger uevents upon map creation in domap() + +If map creation succeeds, previously not multipathed devices are +now multipathed. udev may not have noticed this yet, thus trigger +path uevents to make it aware of the situation. Likewise, if +creating a map fails, the paths in question were likely considered +multipath members by udev, too. They will now be marked as failed, +so trigger an event in this situation as well. + +Fixes: https://github.com/opensvc/multipath-tools/issues/103 +Suggested-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +(cherry picked from commit 98b3a7bd9ed2a89f068fe40c253843cf78261905) +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 11 ++++------- + libmultipath/devmapper.c | 9 +++------ + 2 files changed, 7 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e86c1fd5..d9fac384 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -581,8 +581,6 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + vector_foreach_slot(pgp->paths, pp, j) + trigger_path_udev_change(pp, is_mpath); + } +- +- mpp->needs_paths_uevent = 0; + } + + static int sysfs_set_max_sectors_kb(struct multipath *mpp) +@@ -954,10 +952,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + * succeeded + */ + mpp->force_udev_reload = 0; +- if (mpp->action == ACT_CREATE && +- (remember_wwid(mpp->wwid) == 1 || +- mpp->needs_paths_uevent)) ++ if (mpp->action == ACT_CREATE) { ++ remember_wwid(mpp->wwid); + trigger_paths_udev_change(mpp, true); ++ } + if (!is_daemon) { + /* multipath client mode */ + dm_switchgroup(mpp->alias, mpp->bestpg); +@@ -982,8 +980,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + } + dm_setgeometry(mpp); + return DOMAP_OK; +- } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE && +- mpp->needs_paths_uevent) ++ } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE) + trigger_paths_udev_change(mpp, false); + + return DOMAP_FAIL; +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index fe5637b3..a0070c56 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -536,7 +536,7 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) + MPATH_UDEV_RELOAD_FLAG : 0); + } + +-int dm_addmap_create (struct multipath *mpp, char * params) ++int dm_addmap_create (struct multipath *mpp, char *params) + { + int ro; + uint16_t udev_flags = build_udev_flags(mpp, 0); +@@ -546,9 +546,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) + + if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro, + udev_flags)) { +- if (unmark_failed_wwid(mpp->wwid) == +- WWID_FAILED_CHANGED) +- mpp->needs_paths_uevent = 1; ++ unmark_failed_wwid(mpp->wwid); + return 1; + } + /* +@@ -566,8 +564,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) + break; + } + } +- if (mark_failed_wwid(mpp->wwid) == WWID_FAILED_CHANGED) +- mpp->needs_paths_uevent = 1; ++ mark_failed_wwid(mpp->wwid); + return 0; + } + diff --git a/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch b/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch new file mode 100644 index 0000000..f43ca0c --- /dev/null +++ b/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 27 Nov 2024 20:39:50 +0100 +Subject: [PATCH] multipathd: trigger uevents upon map removal in + coalesce_maps() + +... if a map has been flushed. In this case, we know that the +the paths haven't been multipathed by coalesce_paths() because of the current +configuration (failure to create the map can't be the reason if the map +exists in coalesce_maps()). Make sure udev sees the paths which have +been released from the map as non-multipath. + +Note that this is the only case where maps are flushed where it is correct +to trigger paths uevents. In other cases, e.g. after a "remove map" CLI +command, the configuration is unchanged and if we triggered an uevent, +the map would be re-created by multipathd when the uevent arrived. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +(cherry picked from commit ad3ea472b587c0c20d2100331b5c66f8602f8414) +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3fb623fd..4b089c0e 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -794,8 +794,10 @@ coalesce_maps(struct vectors *vecs, vector nmpv) + vector_del_slot(ompv, i); + i--; + } +- else ++ else { + condlog(2, "%s devmap removed", ompp->alias); ++ trigger_paths_udev_change(ompp, false); ++ } + } else if (reassign_maps) { + condlog(3, "%s: Reassign existing device-mapper" + " devices", ompp->alias); diff --git a/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch b/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch new file mode 100644 index 0000000..6c001f5 --- /dev/null +++ b/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 4 Dec 2024 22:56:36 -0500 +Subject: [PATCH] libmultipath: Don't skip set_path_max_sectors_kb() + +If a multipath device already has need_reload set when a path is +adopted, it won't call set_path_max_sectors_kb() because of +short-circuit evaluation. This isn't what's intended. + +Fixes: e5e20c7b ("libmultipath: set max_sectors_kb in adopt_paths()") +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit f5c0c4b25c5eaac87b78e6e0c8d52b0828c29893) +--- + libmultipath/structs_vec.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 9dc5a5ca..683ab473 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -349,8 +349,7 @@ int adopt_paths(vector pathvec, struct multipath *mpp, + */ + if (!current_mpp || + !mp_find_path_by_devt(current_mpp, pp->dev_t)) +- mpp->need_reload = mpp->need_reload || +- set_path_max_sectors_kb(pp, mpp->max_sectors_kb); ++ mpp->need_reload = set_path_max_sectors_kb(pp, mpp->max_sectors_kb) || mpp->need_reload; + } + + pp->mpp = mpp; diff --git a/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch b/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch new file mode 100644 index 0000000..e293a0e --- /dev/null +++ b/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 22 Jan 2025 22:16:42 -0500 +Subject: [PATCH] libmultipath: stop static analyzer complaint in init_foreign + +This change doesn't actually fix anything. The code was already safe. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit 85ec51e7930b4cadfbc12718afa91ce3a4adf4b5) +--- + libmultipath/foreign.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c +index 28d1b115..af5b0ed3 100644 +--- a/libmultipath/foreign.c ++++ b/libmultipath/foreign.c +@@ -129,7 +129,7 @@ static void free_pre(void *arg) + static int _init_foreign(const char *enable) + { + char pathbuf[PATH_MAX]; +- struct dirent **di; ++ struct dirent **di = NULL; + struct scandir_result sr; + int r, i; + regex_t *enable_re = NULL; diff --git a/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch b/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch new file mode 100644 index 0000000..06a1b0f --- /dev/null +++ b/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 22 Jan 2025 22:16:43 -0500 +Subject: [PATCH] libmultipath: be lenient in allowing the alua-based + pgpolicies + +multipath wouldn't autodetect the GROUP_BY_PRIO path grouping policy or +allow the GROUP_BY_TPG policy if there was a path that didn't have its +prioritizer selected (for instance because multipathd was reconfigured +while it was offline). To avoid this, make verify_alua_prio() assume an +alua multipath device if all the paths with a prioritizer selected +(there must be at least one) use an alua-based prioritizer. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +(cherry picked from commit b47a577998eaff203018a00b57ba5e3674645848) +--- + libmultipath/propsel.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index a3fce203..c09a0619 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -255,14 +255,18 @@ verify_alua_prio(struct multipath *mp) + { + int i; + struct path *pp; ++ bool assume_alua = false; + + vector_foreach_slot(mp->paths, pp, i) { + const char *name = prio_name(&pp->prio); ++ if (!prio_selected(&pp->prio)) ++ continue; + if (strncmp(name, PRIO_ALUA, PRIO_NAME_LEN) && + strncmp(name, PRIO_SYSFS, PRIO_NAME_LEN)) + return false; ++ assume_alua = true; + } +- return true; ++ return assume_alua; + } + + int select_detect_pgpolicy(struct config *conf, struct multipath *mp) diff --git a/0031-Update-NEWS.md-for-0.10.2.patch b/0031-Update-NEWS.md-for-0.10.2.patch new file mode 100644 index 0000000..fd31420 --- /dev/null +++ b/0031-Update-NEWS.md-for-0.10.2.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 24 Jan 2025 20:03:15 +0100 +Subject: [PATCH] Update NEWS.md for 0.10.2 + +Signed-off-by: Benjamin Marzinski +--- + .github/actions/spelling/expect.txt | 2 ++ + NEWS.md | 23 ++++++++++++++++++++++- + 2 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index 000d5ebb..4ac57510 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -11,6 +11,7 @@ ata + autoconfig + autodetected + autoresize ++backported + barbie + BINDIR + blkid +@@ -122,6 +123,7 @@ Lun + lvm + lvmteam + Marzinski ++misdetection + mpath + mpathb + mpathpersist +diff --git a/NEWS.md b/NEWS.md +index 3c51553e..1b239ffa 100644 +--- a/NEWS.md ++++ b/NEWS.md +@@ -1,6 +1,27 @@ + # multipath-tools Release Notes + +-## multipath-tools 0.10.1, 2024/11 ++## multipath-tools 0.10.2, 2025/02 ++ ++This release contains backported bug fixes from the stable-0.11.y branch. ++ ++### Bug fixes ++ ++* Fix multipathd crash because of invalid path group index value, for example ++ if an invalid path device was removed from a map. ++ Fixes [#105](https://github.com/opensvc/multipath-tools/issues/105). ++* Make sure maps are reloaded in the path checker loop after detecting an ++ inconsistent or wrong kernel state (e.g. missing or falsely mapped path ++ device). Wrongly mapped paths will be unmapped and released to the system. ++ Fixes another issue reported in ++ [#105](https://github.com/opensvc/multipath-tools/issues/105). ++* Fix the problem that `group_by_tpg` might be disabled if one or more ++ paths were offline during initial configuration. ++* Fix possible misdetection of changed pathgroups in a map. ++* Fix the problem that if a map was scheduled to be reloaded already, ++ `max_sectors_kb` might not be set on a path device that ++ was being added to a multipath map. This problem was introduced in 0.9.9. ++ ++## multipath-tools 0.10.1, 2025/01 + + This is the first bug fix release on the `stable-0.10.y` branch. It contains + bug fixes from 0.11.0, and some CI-related fixes. diff --git a/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch b/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch new file mode 100644 index 0000000..3ddab39 --- /dev/null +++ b/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Sat, 25 Jan 2025 00:49:19 +0100 +Subject: [PATCH] GitHub Workflows: fix abi-stable.yaml for pull request + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi-stable.yaml | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml +index a6746f23..472914ce 100644 +--- a/.github/workflows/abi-stable.yaml ++++ b/.github/workflows/abi-stable.yaml +@@ -15,12 +15,16 @@ on: + + jobs: + reference-abi: +- runs-on: ubuntu-20.04 ++ runs-on: ubuntu-22.04 + steps: + - name: get parent tag + run: > + echo ${{ github.ref }} | + sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ if: ${{ github.event_name == 'push' }} ++ - name: get parent tag ++ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV ++ if: ${{ github.event_name == 'pull_request' }} + - name: assert parent tag + run: /bin/false + if: ${{ env.PARENT_TAG == '' }} +@@ -45,20 +49,24 @@ jobs: + path: abi + + check-abi: +- runs-on: ubuntu-20.04 ++ runs-on: ubuntu-22.04 + needs: reference-abi + steps: + - name: get parent tag + run: > + echo ${{ github.ref }} | + sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV ++ if: ${{ github.event_name == 'push' }} ++ - name: get parent tag ++ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV ++ if: ${{ github.event_name == 'pull_request' }} + - name: assert parent tag + run: /bin/false + if: ${{ env.PARENT_TAG == '' }} +- - name: checkout ${{ env.PARENT_TAG }} ++ - name: checkout ${{ github.base_ref }} + uses: actions/checkout@v4 + with: +- ref: ${{ env.PARENT_TAG }} ++ ref: ${{ github.base_ref }} + - name: download ABI for ${{ env.PARENT_TAG }} + id: download_abi + uses: actions/download-artifact@v4 diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0033-RH-fixup-udev-rules-for-redhat.patch similarity index 100% rename from 0001-RH-fixup-udev-rules-for-redhat.patch rename to 0033-RH-fixup-udev-rules-for-redhat.patch diff --git a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0034-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0034-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0035-RH-don-t-start-without-a-config-file.patch similarity index 98% rename from 0003-RH-don-t-start-without-a-config-file.patch rename to 0035-RH-don-t-start-without-a-config-file.patch index 02827df..8a3c5b6 100644 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ b/0035-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 0e3a5cc1..80f61914 100644 +index 226ddecb..588ae9ee 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -959,6 +959,19 @@ int init_config__ (const char *file, struct config *conf) +@@ -962,6 +962,19 @@ int init_config__ (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0036-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0036-RH-Fix-nvme-function-missing-argument.patch diff --git a/0005-RH-use-rpm-optflags-if-present.patch b/0037-RH-use-rpm-optflags-if-present.patch similarity index 97% rename from 0005-RH-use-rpm-optflags-if-present.patch rename to 0037-RH-use-rpm-optflags-if-present.patch index 266e224..66d14bc 100644 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ b/0037-RH-use-rpm-optflags-if-present.patch @@ -7,13 +7,14 @@ Use the passed in optflags when compiling as an RPM, and keep the default flags as close as possible to the current fedora flags, while still being generic. +Co-authored-by: Yaakov Selkowitz Signed-off-by: Benjamin Marzinski --- Makefile.inc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 81cb61d2..35334a0c 100644 +index 81cb61d2..a5024bb7 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo diff --git a/0006-RH-add-mpathconf.patch b/0038-RH-add-mpathconf.patch similarity index 99% rename from 0006-RH-add-mpathconf.patch rename to 0038-RH-add-mpathconf.patch index 2ae48f3..103ca55 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0038-RH-add-mpathconf.patch @@ -23,11 +23,11 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 934f582e..61351583 100644 +index 4ac57510..3602a071 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt -@@ -124,9 +124,11 @@ lvmteam - Marzinski +@@ -126,9 +126,11 @@ Marzinski + misdetection mpath mpathb +mpathconf @@ -38,7 +38,7 @@ index 934f582e..61351583 100644 multipathc multipathd multipathed -@@ -144,6 +146,7 @@ ontap +@@ -146,6 +148,7 @@ ontap OOM opensvc OPTFLAGS @@ -47,10 +47,10 @@ index 934f582e..61351583 100644 partx pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index 80f61914..1373f15b 100644 +index 588ae9ee..3cb8449c 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -961,6 +961,8 @@ int init_config__ (const char *file, struct config *conf) +@@ -964,6 +964,8 @@ int init_config__ (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); diff --git a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 100% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0040-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0040-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 98% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 06194f6..0d5baa3 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e94705bf..61ac27ef 100644 +index 5043330c..e14507e8 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch index 3debe8a..ef0ee42 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 35334a0c..377125b6 100644 +index a5024bb7..834b63b9 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0012-RH-compile-with-libreadline-support.patch b/0044-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0012-RH-compile-with-libreadline-support.patch rename to 0044-RH-compile-with-libreadline-support.patch index db04640..50781c3 100644 --- a/0012-RH-compile-with-libreadline-support.patch +++ b/0044-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 377125b6..4a6528a9 100644 +index 834b63b9..c482a181 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0013-RH-Add-mpathcleanup.patch b/0045-RH-Add-mpathcleanup.patch similarity index 100% rename from 0013-RH-Add-mpathcleanup.patch rename to 0045-RH-Add-mpathcleanup.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index d2c3cc6..8e469ab 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.10.0 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -11,19 +11,51 @@ URL: http://christophe.varoqui.free.fr/ # curl -L https://github.com/opensvc/multipath-tools/archive/0.10.0.tar.gz -o multipath-tools-0.10.0.tgz Source0: multipath-tools-0.10.0.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0012: 0012-RH-compile-with-libreadline-support.patch -Patch0013: 0013-RH-Add-mpathcleanup.patch +Patch0001: 0001-GitHub-workflows-use-upload-download-artifact-v4.patch +Patch0002: 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch +Patch0003: 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch +Patch0004: 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch +Patch0005: 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch +Patch0006: 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch +Patch0007: 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch +Patch0008: 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch +Patch0009: 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch +Patch0010: 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch +Patch0011: 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch +Patch0012: 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch +Patch0013: 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch +Patch0014: 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch +Patch0015: 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch +Patch0016: 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch +Patch0017: 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch +Patch0018: 0018-Update-NEWS.md-for-0.10.1.patch +Patch0019: 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch +Patch0020: 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch +Patch0021: 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch +Patch0022: 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch +Patch0023: 0023-Additional-NEWS.md-updates-for-0.10.1.patch +Patch0024: 0024-libmultipath-fix-handling-of-pp-pgindex.patch +Patch0025: 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch +Patch0026: 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch +Patch0027: 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch +Patch0028: 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch +Patch0029: 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch +Patch0030: 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch +Patch0031: 0031-Update-NEWS.md-for-0.10.2.patch +Patch0032: 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch +Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch +Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0035: 0035-RH-don-t-start-without-a-config-file.patch +Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch +Patch0037: 0037-RH-use-rpm-optflags-if-present.patch +Patch0038: 0038-RH-add-mpathconf.patch +Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0044: 0044-RH-compile-with-libreadline-support.patch +Patch0045: 0045-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -233,6 +265,11 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Sat Feb 1 2025 Benjamin Marzinski - 0.10.0-5 +- Update source to upstream staging branch for 0.10.y (will be 0.10.2 when + merged). +- Rebase redhat patches + * Thu Jan 16 2025 Fedora Release Engineering - 0.10.0-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From 30306052cc8ded97742c95e1b7e1c4a5ceeab621 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Mon, 3 Mar 2025 12:33:06 -0500 Subject: [PATCH 30/33] device-mapper-multipath-0.11.1-1 Update source to upstream staging branch for 0.11.1 plus additional stable branch patches. * Previous patches 0001-0032 are included in the tarball Rename redhat patches * Previous patches 0033-0045 are now patches 0005-0017 --- .gitignore | 1 + ...lows-use-upload-download-artifact-v4.patch | 122 ---------------- ...er-uevents-for-blacklisted-paths-in-.patch | 101 +++++++++++++ ...-update-dawidd6-action-download-arti.patch | 24 --- ...fix-compilation-with-latest-userspac.patch | 63 ++++++++ ...-native.yml-use-mosteo-actions-docke.patch | 98 ------------- ...-include-urcu.h-before-urcu-atomic.h.patch | 40 +++++ ...s-native.yml-use-extra-job-for-clang.patch | 43 ------ ...uxsock.c-Include-string.h-for-memcpy.patch | 29 ++++ ...-native.yaml-make-test-and-archive-s.patch | 51 ------- ... 0005-RH-fixup-udev-rules-for-redhat.patch | 2 +- ...-enable-unit-tests-for-stable-branch.patch | 133 ----------------- ...property-blacklist-exception-builtin.patch | 0 ...ws-add-abi-check-for-stable-branches.patch | 110 -------------- ...RH-don-t-start-without-a-config-file.patch | 8 +- ...H-Fix-nvme-function-missing-argument.patch | 0 ...get_maps-don-t-bail-out-for-single-m.patch | 32 ---- ...s.in-import-DM_COLDPLUG_SUSPENDED-on.patch | 42 ------ ... 0009-RH-use-rpm-optflags-if-present.patch | 7 +- ...s.in-handle-inactive-suspended-devic.patch | 66 --------- ...hconf.patch => 0010-RH-add-mpathconf.patch | 10 +- ...rules.in-clarify-DM_ACTIVATION-logic.patch | 78 ---------- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 6 +- ...h-rules.in-skip-one-.DM_NOSCAN-check.patch | 28 ---- ...-default-find_mutipaths-value-to-off.patch | 0 ...s.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch | 44 ------ ...empt-to-get-ANA-info-via-sysfs-first.patch | 0 ...-parse_vpd_pg83-match-scsi_id-output.patch | 6 +- ...-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch | 31 ---- ...si-device-handlers-to-modules-load.d.patch | 2 +- ...eferred_failback_tick-for-reload-rem.patch | 35 ----- ...-RH-compile-with-libreadline-support.patch | 2 +- ...ipathd-fix-an-unsigned-int-ovwerflow.patch | 28 ---- ...up.patch => 0017-RH-Add-mpathcleanup.patch | 0 ...id-Wcast-function-type-mismatch-erro.patch | 36 ----- 0018-Update-NEWS.md-for-0.10.1.patch | 44 ------ ...-t-print-error-message-if-WATCHDOG_U.patch | 30 ---- ...uce-log-level-of-map-X-has-multiple-.patch | 38 ----- ...eign-fix-memory-leak-in-nvme-foreign.patch | 54 ------- ...-condition-for-enqueueing-path-to-io.patch | 41 ------ ...dditional-NEWS.md-updates-for-0.10.1.patch | 63 -------- ...multipath-fix-handling-of-pp-pgindex.patch | 138 ------------------ ...e-pgcmp-detect-if-map-is-missing-a-p.patch | 70 --------- ...gger-uevents-upon-map-creation-in-do.patch | 94 ------------ ...er-uevents-upon-map-removal-in-coale.patch | 41 ------ ...h-Don-t-skip-set_path_max_sectors_kb.patch | 31 ---- ...p-static-analyzer-complaint-in-init_.patch | 27 ---- ...lenient-in-allowing-the-alua-based-p.patch | 44 ------ 0031-Update-NEWS.md-for-0.10.2.patch | 64 -------- ...-fix-abi-stable.yaml-for-pull-reques.patch | 61 -------- device-mapper-multipath.spec | 79 ++++------ sources | 2 +- 52 files changed, 285 insertions(+), 1914 deletions(-) delete mode 100644 0001-GitHub-workflows-use-upload-download-artifact-v4.patch create mode 100644 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch delete mode 100644 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch create mode 100644 0002-multipath-tools-fix-compilation-with-latest-userspac.patch delete mode 100644 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch create mode 100644 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch delete mode 100644 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch create mode 100644 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch delete mode 100644 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch rename 0033-RH-fixup-udev-rules-for-redhat.patch => 0005-RH-fixup-udev-rules-for-redhat.patch (98%) delete mode 100644 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch rename 0034-RH-Remove-the-property-blacklist-exception-builtin.patch => 0006-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) delete mode 100644 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch rename 0035-RH-don-t-start-without-a-config-file.patch => 0007-RH-don-t-start-without-a-config-file.patch (96%) rename 0036-RH-Fix-nvme-function-missing-argument.patch => 0008-RH-Fix-nvme-function-missing-argument.patch (100%) delete mode 100644 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch delete mode 100644 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch rename 0037-RH-use-rpm-optflags-if-present.patch => 0009-RH-use-rpm-optflags-if-present.patch (92%) delete mode 100644 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch rename 0038-RH-add-mpathconf.patch => 0010-RH-add-mpathconf.patch (99%) delete mode 100644 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch rename 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (97%) delete mode 100644 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch rename 0040-RH-reset-default-find_mutipaths-value-to-off.patch => 0012-RH-reset-default-find_mutipaths-value-to-off.patch (100%) delete mode 100644 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch rename 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (100%) rename 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (94%) delete mode 100644 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch rename 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch (96%) delete mode 100644 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch rename 0044-RH-compile-with-libreadline-support.patch => 0016-RH-compile-with-libreadline-support.patch (96%) delete mode 100644 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch rename 0045-RH-Add-mpathcleanup.patch => 0017-RH-Add-mpathcleanup.patch (100%) delete mode 100644 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch delete mode 100644 0018-Update-NEWS.md-for-0.10.1.patch delete mode 100644 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch delete mode 100644 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch delete mode 100644 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch delete mode 100644 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch delete mode 100644 0023-Additional-NEWS.md-updates-for-0.10.1.patch delete mode 100644 0024-libmultipath-fix-handling-of-pp-pgindex.patch delete mode 100644 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch delete mode 100644 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch delete mode 100644 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch delete mode 100644 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch delete mode 100644 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch delete mode 100644 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch delete mode 100644 0031-Update-NEWS.md-for-0.10.2.patch delete mode 100644 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch diff --git a/.gitignore b/.gitignore index 908094d..8cd21df 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.8.tgz /multipath-tools-0.9.9.tgz /multipath-tools-0.10.0.tgz +/multipath-tools-0.11.1.tgz diff --git a/0001-GitHub-workflows-use-upload-download-artifact-v4.patch b/0001-GitHub-workflows-use-upload-download-artifact-v4.patch deleted file mode 100644 index c8247ca..0000000 --- a/0001-GitHub-workflows-use-upload-download-artifact-v4.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 09:09:19 +0200 -Subject: [PATCH] GitHub workflows: use {upload,download}-artifact@v4 - -The @v1 releases are deprecated. -https://github.blog/changelog/2024-02-13-deprecation-notice-v1-and-v2-of-the-artifact-actions/ - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 6 ++++-- - .github/workflows/foreign.yaml | 15 +++++++-------- - .github/workflows/native.yaml | 5 +++-- - 3 files changed, 14 insertions(+), 12 deletions(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index 393322e5..dce09f5c 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -45,10 +45,11 @@ jobs: - - name: create ABI - run: make -Orecurse -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz - - name: save ABI -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: abi - path: abi -+ overwrite: true - - name: compare ABI against reference - id: compare - continue-on-error: true -@@ -56,10 +57,11 @@ jobs: - run: make abi-test - - name: save differences - if: ${{ steps.compare.outcome == 'failure' }} -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: abi-test - path: abi-test -+ overwrite: true - - - name: fail - # MUST use >- here, otherwise the condition always evaluates to true -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index 9e4d35e0..d68650df 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -36,14 +36,13 @@ jobs: - - name: checkout - uses: actions/checkout@v1 - - name: build -- run: make -j8 -Orecurse test-progs -- - name: create binary archive -- run: make test-progs.tar -+ run: make -j -Orecurse test-progs.tar - - name: upload binary archive -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: cross-${{ matrix.os }}-${{ matrix.arch }} - path: test-progs.tar -+ overwrite: true - - test: - runs-on: ubuntu-22.04 -@@ -61,11 +60,11 @@ jobs: - run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV - if: ${{ matrix.arch == 'armhf' }} - - name: download binary archive -- uses: actions/download-artifact@v1 -+ uses: actions/download-artifact@v4 - with: - name: cross-${{ matrix.os }}-${{ matrix.arch }} - - name: unpack binary archive -- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar -+ run: tar xfv test-progs.tar - - name: enable foreign arch - uses: dbhi/qus/action@main - - name: run tests -@@ -100,11 +99,11 @@ jobs: - run: echo CONTAINER_ARCH="arm/v7" >> $GITHUB_ENV - if: ${{ matrix.arch == 'armhf' }} - - name: download binary archive -- uses: actions/download-artifact@v1 -+ uses: actions/download-artifact@v4 - with: - name: cross-${{ matrix.os }}-${{ matrix.arch }} - - name: unpack binary archive -- run: tar xfv cross-${{ matrix.os }}-${{ matrix.arch }}/test-progs.tar -+ run: tar xfv test-progs.tar - - name: enable foreign arch - uses: dbhi/qus/action@main - - name: run tests -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 80ff6df5..500becaa 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -57,10 +57,11 @@ jobs: - - name: create binary archive - run: make ${{ env.ARCHIVE_TGT }} - - name: upload binary archive -- uses: actions/upload-artifact@v1 -+ uses: actions/upload-artifact@v4 - with: - name: native-${{ matrix.os }} - path: ${{ env.ARCHIVE_TGT }} -+ overwrite: true - - - name: clean - run: make clean -@@ -98,7 +99,7 @@ jobs: - uses: actions/checkout@v1 - - - name: download binary archive -- uses: actions/download-artifact@v1 -+ uses: actions/download-artifact@v4 - with: - name: native-${{ matrix.os }} - - name: unpack binary archive diff --git a/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch b/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch new file mode 100644 index 0000000..72bcf69 --- /dev/null +++ b/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 23 Jan 2025 22:19:39 +0100 +Subject: [PATCH] multipathd: trigger uevents for blacklisted paths in + reconfigure + +If multipathd has already configured maps, and the user changes the +blacklist or other parameters that cause currently multipathed +devices to be skipped, and then runs "multipathd reconfigure" +or restarts multipathd, multipathd flushes the maps in question, +but doesn't trigger uevents for the now-blacklisted paths. + +This is because the blacklisted paths are removed from the discovered +maps internally when update_pathvec_from_dm() is called through +map_discovery() and update_multipath_table(); when later +trigger_paths_udev_change() is called from coalesce_maps(), the +map contains no paths for which an uevent could be triggered. + +The map_discovery() code flow is special, because we will call +coalesce_paths() afterwards anyway and reconstruct the mpvec. Unlike the +regular code flow, we don't want the maps to be "corrected" in this +case, because the maps discovered here aren't going to be reloaded. +We just want update_pathvec_from_dm() to populate the pathvec. + +Therefore add a new flag DI_DISCOVERY, which is only set when +update_multipath_table() is called from map_discovery(), and if +this flag is set, keep PATHINFO_SKIPPED paths in the map's table in +update_pathvec_from_dm(). Later on, the paths will still be visible +in the old mpp (ompp) in coalesce_maps(), and uevents will be +triggered for them to release them to systemd. + +We can't always do this for PATHINFO_SKIPPED, because in some cases +paths may be accepted in a map first and SKIPPED later (for example if +the WWID wasn't yet available at startup). Therefore the special +case for DI_DISCOVERY is necessary. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.h | 2 ++ + libmultipath/structs_vec.c | 6 +++++- + multipathd/main.c | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h +index 7d42eae5..9824a8d3 100644 +--- a/libmultipath/discovery.h ++++ b/libmultipath/discovery.h +@@ -72,6 +72,7 @@ enum discovery_mode { + DI_BLACKLIST__, + DI_NOIO__, + DI_NOFALLBACK__, ++ DI_DISCOVERY__, + }; + + #define DI_SYSFS (1 << DI_SYSFS__) +@@ -82,6 +83,7 @@ enum discovery_mode { + #define DI_BLACKLIST (1 << DI_BLACKLIST__) + #define DI_NOIO (1 << DI_NOIO__) /* Avoid IO on the device */ + #define DI_NOFALLBACK (1 << DI_NOFALLBACK__) /* do not allow wwid fallback */ ++#define DI_DISCOVERY (1 << DI_DISCOVERY__) /* set only during map discovery */ + + #define DI_ALL (DI_SYSFS | DI_SERIAL | DI_CHECKER | DI_PRIO | \ + DI_WWID) +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index 7a4e3eb0..5ccdaea0 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -109,6 +109,9 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + bool mpp_has_wwid; + bool must_reload = false; + bool pg_deleted = false; ++ bool map_discovery = !!(pathinfo_flags & DI_DISCOVERY); ++ ++ pathinfo_flags &= ~DI_DISCOVERY; + + if (!mpp->pg) + return false; +@@ -195,7 +198,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + rc = pathinfo(pp, conf, + DI_SYSFS|DI_WWID|DI_BLACKLIST|DI_NOFALLBACK|pathinfo_flags); + pthread_cleanup_pop(1); +- if (rc != PATHINFO_OK) { ++ if (rc == PATHINFO_FAILED || ++ (rc == PATHINFO_SKIPPED && !map_discovery)) { + condlog(1, "%s: error %d in pathinfo, discarding path", + pp->dev, rc); + vector_del_slot(pgp->paths, j--); +diff --git a/multipathd/main.c b/multipathd/main.c +index 9ed27da0..fb3e44a8 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1763,7 +1763,7 @@ map_discovery (struct vectors * vecs) + return 1; + + vector_foreach_slot (vecs->mpvec, mpp, i) +- if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) { ++ if (update_multipath_table(mpp, vecs->pathvec, DI_DISCOVERY) != DMP_OK) { + remove_map(mpp, vecs->pathvec, vecs->mpvec); + i--; + } diff --git a/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch b/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch deleted file mode 100644 index 423bf56..0000000 --- a/0002-GitHub-workflows-update-dawidd6-action-download-arti.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 09:10:38 +0200 -Subject: [PATCH] GitHub workflows: update dawidd6/action-download-artifact - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml -index dce09f5c..d5f8b477 100644 ---- a/.github/workflows/abi.yaml -+++ b/.github/workflows/abi.yaml -@@ -28,7 +28,7 @@ jobs: - - name: get reference ABI - id: reference - continue-on-error: true -- uses: dawidd6/action-download-artifact@v2 -+ uses: dawidd6/action-download-artifact@v6 - with: - workflow: abi.yaml - branch: ${{ env.ABI_BRANCH }} diff --git a/0002-multipath-tools-fix-compilation-with-latest-userspac.patch b/0002-multipath-tools-fix-compilation-with-latest-userspac.patch new file mode 100644 index 0000000..03d7d9d --- /dev/null +++ b/0002-multipath-tools-fix-compilation-with-latest-userspac.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 3 Feb 2025 16:43:42 -0500 +Subject: [PATCH] multipath-tools: fix compilation with latest userspace-rcu + code + +starting with version 0.15, userspace-rcu can be compiled with +CONFIG_RCU_USE_ATOMIC_BUILTINS. If it is, then any programs using it +must be compiled with at least the C11 standard. See: +https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f + +To deal with this, check if compiling with gnu99 fails, and if so, +switch to using gnu11. + +Based-on-patch-by: Yaakov Selkowitz +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + Makefile.inc | 2 +- + create-config.mk | 13 +++++++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 729618bd..65f6efc8 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -115,7 +115,7 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ + -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ + -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP +-CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ ++CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -fexceptions + BIN_CFLAGS := -fPIE -DPIE + LIB_CFLAGS := -fPIC +diff --git a/create-config.mk b/create-config.mk +index 8bd2c20c..ab163ed1 100644 +--- a/create-config.mk ++++ b/create-config.mk +@@ -157,6 +157,18 @@ FORTIFY_OPT := $(shell \ + echo "-D_FORTIFY_SOURCE=2"; \ + fi) + ++# Check is you can compile with the urcu.h header, using the C99 standard. ++# If urcu/config-.h defines CONFIG_RCU_USE_ATOMIC_BUILTINS, then anything ++# including urcu.h must be compiled with at least the C11 standard. See: ++# https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f ++C_STD := $(shell \ ++ if printf '$(__HASH__)include \nint main(void) { return 0; }\n' | $(CC) -o /dev/null -c -xc --std=gnu99 - 2>/dev/null; \ ++ then \ ++ echo "gnu99"; \ ++ else \ ++ echo "gnu11"; \ ++ fi) ++ + STACKPROT := + + all: $(TOPDIR)/config.mk +@@ -182,3 +194,4 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h + @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ + @echo "W_URCU_TYPE_LIMITS := $(call TEST_URCU_TYPE_LIMITS)" >>$@ + @echo "ENABLE_LIBDMMP := $(ENABLE_LIBDMMP)" >>$@ ++ @echo "C_STD := $(C_STD)" >>$@ diff --git a/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch b/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch deleted file mode 100644 index 63aa273..0000000 --- a/0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 09:45:25 +0200 -Subject: [PATCH] Github workflows: native.yml: use mosteo-actions/docker-run - -We can't use "container:" any more because upload-artifact@v4 doesn't -work on Debian Jessie. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 45 +++++++++++++++++++++-------------- - 1 file changed, 27 insertions(+), 18 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 500becaa..70d01c55 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -35,17 +35,9 @@ jobs: - - debian-bookworm - - fedora-40 - - opensuse-leap -- container: ghcr.io/mwilck/multipath-build-${{ matrix.os }} - steps: - - name: checkout - uses: actions/checkout@v1 -- - name: build and test -- if: ${{ matrix.os != 'debian-jessie' }} -- run: make -j -Orecurse test -- - name: build and test (jessie) -- # On jessie, we use libreadline 5 (no licensing issue) -- if: ${{ matrix.os == 'debian-jessie' }} -- run: make -j -Orecurse READLINE=libreadline test - - - name: set archive name - # Leap containers have cpio but not tar -@@ -54,8 +46,21 @@ jobs: - - name: set archive name - run: echo ARCHIVE_TGT=test-progs.tar >> $GITHUB_ENV - if: ${{ matrix.os != 'opensuse-leap' }} -- - name: create binary archive -- run: make ${{ env.ARCHIVE_TGT }} -+ -+ - name: build and test -+ if: ${{ matrix.os != 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test -+ - name: build and test (jessie) -+ # On jessie, we use libreadline 5 (no licensing issue) -+ if: ${{ matrix.os == 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test -+ - - name: upload binary archive - uses: actions/upload-artifact@v4 - with: -@@ -67,14 +72,18 @@ jobs: - run: make clean - - name: clang - if: ${{ matrix.os != 'debian-jessie' }} -- env: -- CC: clang -- run: make -j -Orecurse test -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ params: -e CC=clang -+ command: -j -Orecurse test - - name: clang (jessie) - if: ${{ matrix.os == 'debian-jessie' }} -- env: -- CC: clang -- run: make READLINE=libreadline test -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ params: -e CC=clang -+ command: -j -Orecurse READLINE=libreadline test - - root-test: - runs-on: ubuntu-22.04 -@@ -103,10 +112,10 @@ jobs: - with: - name: native-${{ matrix.os }} - - name: unpack binary archive -- run: cpio -idv < native-${{ matrix.os }}/test-progs.cpio -+ run: cpio -idv < test-progs.cpio - if: ${{ matrix.os == 'opensuse-leap' }} - - name: unpack binary archive -- run: tar xfmv native-${{ matrix.os }}/test-progs.tar -+ run: tar xfmv test-progs.tar - if: ${{ matrix.os != 'opensuse-leap' }} - - - name: run root tests diff --git a/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch b/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch new file mode 100644 index 0000000..8da3ce7 --- /dev/null +++ b/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 11 Feb 2025 13:11:03 -0500 +Subject: [PATCH] libmultipath: include urcu.h before urcu/atomic.h + +urcu/atomic.h requires some header files included by urcu.h. Make sure +to include it first. + +Fixes: https://github.com/opensvc/multipath-tools/issues/112 +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/checkers/tur.c | 1 + + libmultipath/lock.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index e70a2e11..0010acf8 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + + #include "checkers.h" +diff --git a/libmultipath/lock.h b/libmultipath/lock.h +index 38473a8c..5f323055 100644 +--- a/libmultipath/lock.h ++++ b/libmultipath/lock.h +@@ -2,6 +2,7 @@ + #define LOCK_H_INCLUDED + + #include ++#include + #include + #include + diff --git a/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch b/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch deleted file mode 100644 index e6d618c..0000000 --- a/0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 10:17:17 +0200 -Subject: [PATCH] GitHub workflows: native.yml: use extra job for clang - -Running "make" in a container and "make clean" outside doesn't -work (access right issues). So just use separate jobs. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 70d01c55..95b53b87 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -68,8 +68,22 @@ jobs: - path: ${{ env.ARCHIVE_TGT }} - overwrite: true - -- - name: clean -- run: make clean -+ clang: -+ runs-on: ubuntu-22.04 -+ strategy: -+ fail-fast: false -+ matrix: -+ os: -+ - debian-jessie -+ - debian-buster -+ - debian-bullseye -+ - debian-bookworm -+ - fedora-40 -+ - opensuse-leap -+ steps: -+ - name: checkout -+ uses: actions/checkout@v1 -+ - - name: clang - if: ${{ matrix.os != 'debian-jessie' }} - uses: mosteo-actions/docker-run@v1 diff --git a/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch b/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch new file mode 100644 index 0000000..8fc3211 --- /dev/null +++ b/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Mon, 17 Feb 2025 12:05:03 -0800 +Subject: [PATCH] libmpathutils/uxsock.c: Include string.h for memcpy + +Fixes +uxsock.c:72:2: error: call to undeclared library function 'memcpy' with type 'void *(void *, const void *, unsigned long)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] + +Signed-off-by: Khem Raj +Cc: Benjamin Marzinski +Cc: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmpathutil/uxsock.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libmpathutil/uxsock.c b/libmpathutil/uxsock.c +index 2135476d..a474874e 100644 +--- a/libmpathutil/uxsock.c ++++ b/libmpathutil/uxsock.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch b/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch deleted file mode 100644 index cabfbcf..0000000 --- a/0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 13 Sep 2024 10:30:47 +0200 -Subject: [PATCH] GitHub workflows: native.yaml: make test and archive - separately - -Avoid "text file busy" error on GitHub. - -dmevents-test: Text file busy -Makefile:74: recipe for target 'dmevents.out' failed - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/native.yaml | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index 95b53b87..f06b09df 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -52,14 +52,27 @@ jobs: - uses: mosteo-actions/docker-run@v1 - with: - image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -- command: -j -Orecurse ${{ env.ARCHIVE_TGT }} test -+ command: -j -Orecurse test - - name: build and test (jessie) - # On jessie, we use libreadline 5 (no licensing issue) - if: ${{ matrix.os == 'debian-jessie' }} - uses: mosteo-actions/docker-run@v1 - with: - image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -- command: -j -Orecurse READLINE=libreadline ${{ env.ARCHIVE_TGT }} test -+ command: -j -Orecurse READLINE=libreadline test -+ -+ - name: create ${{ env.ARCHIVE_TGT }} -+ if: ${{ matrix.os != 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: ${{ env.ARCHIVE_TGT }} -+ - name: create ${{ env.ARCHIVE_TGT }} (jessie) -+ if: ${{ matrix.os == 'debian-jessie' }} -+ uses: mosteo-actions/docker-run@v1 -+ with: -+ image: ghcr.io/mwilck/multipath-build-${{ matrix.os }} -+ command: READLINE=libreadline ${{ env.ARCHIVE_TGT }} - - - name: upload binary archive - uses: actions/upload-artifact@v4 diff --git a/0033-RH-fixup-udev-rules-for-redhat.patch b/0005-RH-fixup-udev-rules-for-redhat.patch similarity index 98% rename from 0033-RH-fixup-udev-rules-for-redhat.patch rename to 0005-RH-fixup-udev-rules-for-redhat.patch index 0645240..0135f49 100644 --- a/0033-RH-fixup-udev-rules-for-redhat.patch +++ b/0005-RH-fixup-udev-rules-for-redhat.patch @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 729618bd..81cb61d2 100644 +index 65f6efc8..c225a1ed 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif diff --git a/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch b/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch deleted file mode 100644 index 4a9b254..0000000 --- a/0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 16:02:38 +0100 -Subject: [PATCH] GitHub workflows: enable unit tests for stable branches - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/build-and-unittest.yaml | 2 ++ - .github/workflows/foreign.yaml | 2 ++ - .github/workflows/multiarch-stable.yaml | 2 ++ - .github/workflows/multiarch.yaml | 2 ++ - .github/workflows/native.yaml | 2 ++ - .github/workflows/rolling.yaml | 2 ++ - 6 files changed, 12 insertions(+) - -diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml -index a838f9a2..1a727e14 100644 ---- a/.github/workflows/build-and-unittest.yaml -+++ b/.github/workflows/build-and-unittest.yaml -@@ -5,10 +5,12 @@ on: - - master - - queue - - tip -+ - 'stable-*' - pull_request: - branches: - - master - - queue -+ - 'stable-*' - jobs: - jammy: - runs-on: ubuntu-22.04 -diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml -index d68650df..0f80957b 100644 ---- a/.github/workflows/foreign.yaml -+++ b/.github/workflows/foreign.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/foreign.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/foreign.yaml' - - '**.h' -diff --git a/.github/workflows/multiarch-stable.yaml b/.github/workflows/multiarch-stable.yaml -index e51d383c..ffede53d 100644 ---- a/.github/workflows/multiarch-stable.yaml -+++ b/.github/workflows/multiarch-stable.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/multiarch-stable.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/multiarch-stable.yaml' - - '**.h' -diff --git a/.github/workflows/multiarch.yaml b/.github/workflows/multiarch.yaml -index df95a02f..d2b833a4 100644 ---- a/.github/workflows/multiarch.yaml -+++ b/.github/workflows/multiarch.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/multiarch.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/multiarch.yaml' - - '**.h' -diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml -index f06b09df..c9d9df9e 100644 ---- a/.github/workflows/native.yaml -+++ b/.github/workflows/native.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/native.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/native.yaml' - - '**.h' -diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml -index 3536b944..66af7a44 100644 ---- a/.github/workflows/rolling.yaml -+++ b/.github/workflows/rolling.yaml -@@ -5,6 +5,7 @@ on: - - master - - queue - - tip -+ - 'stable-*' - paths: - - '.github/workflows/rolling.yaml' - - '**.h' -@@ -15,6 +16,7 @@ on: - branches: - - master - - queue -+ - 'stable-*' - paths: - - '.github/workflows/rolling.yaml' - - '**.h' diff --git a/0034-RH-Remove-the-property-blacklist-exception-builtin.patch b/0006-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0034-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0006-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch b/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch deleted file mode 100644 index c19980f..0000000 --- a/0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 16:51:05 +0100 -Subject: [PATCH] GitHub Workflows: add abi check for stable branches - -The ABI should never change on a stable branch. This workflow -asserts that. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi-stable.yaml | 89 +++++++++++++++++++++++++++++++ - 1 file changed, 89 insertions(+) - create mode 100644 .github/workflows/abi-stable.yaml - -diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml -new file mode 100644 -index 00000000..a6746f23 ---- /dev/null -+++ b/.github/workflows/abi-stable.yaml -@@ -0,0 +1,89 @@ -+name: check-abi for stable branch -+on: -+ push: -+ branches: -+ - 'stable-*' -+ paths: -+ - '.github/workflows/abi-stable.yaml' -+ - '**.h' -+ - '**.c' -+ - '**.version' -+ pull_request: -+ branches: -+ - 'stable-*' -+ workflow_dispatch: -+ -+jobs: -+ reference-abi: -+ runs-on: ubuntu-20.04 -+ steps: -+ - name: get parent tag -+ run: > -+ echo ${{ github.ref }} | -+ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ - name: assert parent tag -+ run: /bin/false -+ if: ${{ env.PARENT_TAG == '' }} -+ - name: update -+ run: sudo apt-get update -+ - name: dependencies -+ run: > -+ sudo apt-get install --yes gcc -+ gcc make pkg-config abigail-tools -+ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev -+ - name: checkout ${{ env.PARENT_TAG }} -+ uses: actions/checkout@v4 -+ with: -+ ref: ${{ env.PARENT_TAG }} -+ - name: build ABI for ${{ env.PARENT_TAG }} -+ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi -+ - name: save ABI -+ uses: actions/upload-artifact@v4 -+ with: -+ name: multipath-abi-${{ env.PARENT_TAG }} -+ path: abi -+ -+ check-abi: -+ runs-on: ubuntu-20.04 -+ needs: reference-abi -+ steps: -+ - name: get parent tag -+ run: > -+ echo ${{ github.ref }} | -+ sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ - name: assert parent tag -+ run: /bin/false -+ if: ${{ env.PARENT_TAG == '' }} -+ - name: checkout ${{ env.PARENT_TAG }} -+ uses: actions/checkout@v4 -+ with: -+ ref: ${{ env.PARENT_TAG }} -+ - name: download ABI for ${{ env.PARENT_TAG }} -+ id: download_abi -+ uses: actions/download-artifact@v4 -+ with: -+ name: multipath-abi-${{ env.PARENT_TAG }} -+ path: reference-abi -+ - name: update -+ run: sudo apt-get update -+ if: steps.download_abi.outcome != 'success' -+ - name: dependencies -+ run: > -+ sudo apt-get install --yes gcc -+ gcc make pkg-config abigail-tools -+ libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev -+ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev -+ - name: check ABI of ${{ github.ref }} against ${{ env.PARENT_TAG }} -+ id: check_abi -+ run: make -j$(grep -c ^processor /proc/cpuinfo) -Orecurse abi-test -+ continue-on-error: true -+ - name: save differences -+ if: ${{ steps.check_abi.outcome != 'success' }} -+ uses: actions/upload-artifact@v4 -+ with: -+ name: abi-test -+ path: abi-test -+ - name: fail -+ run: /bin/false -+ if: steps.check_abi.outcome != 'success' diff --git a/0035-RH-don-t-start-without-a-config-file.patch b/0007-RH-don-t-start-without-a-config-file.patch similarity index 96% rename from 0035-RH-don-t-start-without-a-config-file.patch rename to 0007-RH-don-t-start-without-a-config-file.patch index 8a3c5b6..edbc647 100644 --- a/0035-RH-don-t-start-without-a-config-file.patch +++ b/0007-RH-don-t-start-without-a-config-file.patch @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 226ddecb..588ae9ee 100644 +index 8b424d18..b8317f4d 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -962,6 +962,19 @@ int init_config__ (const char *file, struct config *conf) +@@ -937,6 +937,19 @@ int init_config__ (const char *file, struct config *conf) } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); validate_pctable(conf->overrides, 0, file); @@ -46,7 +46,7 @@ index 226ddecb..588ae9ee 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index 94cdf252..534b6142 100644 +index 5b4ebf8c..2302eacc 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -10,6 +10,7 @@ @@ -112,7 +112,7 @@ index 7bc8806e..315884eb 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 646001e6..72e44849 100644 +index b6a25b31..3d957733 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ diff --git a/0036-RH-Fix-nvme-function-missing-argument.patch b/0008-RH-Fix-nvme-function-missing-argument.patch similarity index 100% rename from 0036-RH-Fix-nvme-function-missing-argument.patch rename to 0008-RH-Fix-nvme-function-missing-argument.patch diff --git a/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch b/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch deleted file mode 100644 index 88122b0..0000000 --- a/0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 Nov 2024 13:06:10 +0100 -Subject: [PATCH] libmultipath: dm_get_maps(): don't bail out for single-map - failures - -dm_get_maps() traverses the entire list of dm maps. We shouldn't -give up just because probing a single map failed. - -Fixes: bf3a4ad ("libmultipath: simplify dm_get_maps()") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index c497c225..52bfe9ce 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1262,10 +1262,8 @@ int dm_get_maps(vector mp) - } - vector_set_slot(mp, mpp); - break; -- case DMP_NO_MATCH: -- break; - default: -- return 1; -+ break; - } - next = names->next; - names = (void *) names + next; diff --git a/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch b/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch deleted file mode 100644 index b380f75..0000000 --- a/0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 31 Oct 2024 12:08:08 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: import DM_COLDPLUG_SUSPENDED only once - -We import DM_COLDPLUG_SUSPENDED in all code flows below mpath_coldplug_end. -Clarify this in the code. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 30647b99..67838261 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -24,12 +24,13 @@ ENV{DM_UDEV_RULES_VSN}=="1|2", ENV{.DM_SUSPENDED}!="1", ENV{DISK_RO}!="1", \ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="", GOTO="scan_import" - LABEL="mpath_coldplug_end" - -+IMPORT{db}="DM_COLDPLUG_SUSPENDED" -+ - # If this uevent didn't come from dm, don't try to update the - # device state - # Note that .MPATH_DEVICE_READY_OLD=="" here. Thus we won't activate the - # device below at mpath_is_ready, which is correct. - ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ -- IMPORT{db}="DM_COLDPLUG_SUSPENDED", \ - GOTO="check_mpath_ready" - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" -@@ -67,7 +68,6 @@ LABEL="check_mpath_unchanged" - # A previous coldplug event occurred while the device was suspended. - # Activation might have been partially skipped. Activate the device now, - # i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. --IMPORT{db}="DM_COLDPLUG_SUSPENDED" - ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ - ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ diff --git a/0037-RH-use-rpm-optflags-if-present.patch b/0009-RH-use-rpm-optflags-if-present.patch similarity index 92% rename from 0037-RH-use-rpm-optflags-if-present.patch rename to 0009-RH-use-rpm-optflags-if-present.patch index 66d14bc..1b96a3a 100644 --- a/0037-RH-use-rpm-optflags-if-present.patch +++ b/0009-RH-use-rpm-optflags-if-present.patch @@ -7,14 +7,13 @@ Use the passed in optflags when compiling as an RPM, and keep the default flags as close as possible to the current fedora flags, while still being generic. -Co-authored-by: Yaakov Selkowitz Signed-off-by: Benjamin Marzinski --- Makefile.inc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 81cb61d2..a5024bb7 100644 +index c225a1ed..7774f1f4 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo @@ -53,9 +52,9 @@ index 81cb61d2..a5024bb7 100644 -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP --CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ +-CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions -+CFLAGS := -std=gnu11 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe ++CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe BIN_CFLAGS := -fPIE -DPIE LIB_CFLAGS := -fPIC SHARED_FLAGS := -shared diff --git a/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch b/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch deleted file mode 100644 index f34e699..0000000 --- a/0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 31 Oct 2024 12:59:03 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: handle inactive suspended devices - correctly - -Since b22c273 ("11-dm-mpath.rules: Don't force activation while device is -suspended"), we've handled the case where a device is suspended while -an uevent is processed (e.g. because multipathd is reloading the -map again at the same time). But we were missing the case where -The device had never been initialized before. If .MPATH_DEVICE_READY_OLD -was empty, we'd jump to scan_import without setting MPATH_DEVICE_READY -to 0. This can cause a device not to be fully activated at boot time, -because in follow-up uevents we'd assume that the device had already -been set up. - -Treat the case in which an uevent is processed for a previously not -fully set-up, suspended device like other situations where we set -MPATH_DEVICE_READY to 0. - -Fixes: b22c273 ("11-dm-mpath.rules: Don't force activation while device is -suspended") -Reviewed-by: Benjamin Marzinski - -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 67838261..20f8c6ac 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -35,6 +35,13 @@ ENV{DM_COOKIE}!="?*", ENV{DM_ACTION}!="PATH_*", \ - - ENV{.MPATH_DEVICE_READY_OLD}="$env{MPATH_DEVICE_READY}" - -+# If the device wasn't ready previously and is currently suspended, -+# we have to postpone the activation until the next event. -+# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the -+# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. -+ENV{.MPATH_DEVICE_READY_OLD}!="1", ENV{.DM_SUSPENDED}=="1", \ -+ ENV{MPATH_DEVICE_READY}="0", GOTO="check_mpath_unchanged" -+ - # multipath sets DM_SUBSYSTEM_UDEV_FLAG2 when it reloads a - # table with no active devices. If this happens, mark the - # device not ready -@@ -106,14 +113,10 @@ GOTO="scan_import" - LABEL="mpath_is_ready" - - # If the device comes back online, set DM_ACTIVATION so that --# upper layers do a rescan. If the device is currently suspended, --# we have to postpone the activation until the next event. --# In this case, we have to set MPATH_DEVICE_READY=0; otherwise, the --# MPATH_UNCHANGED logic will cause later rules to skipped in the next event. --ENV{.MPATH_DEVICE_READY_OLD}!="0", GOTO="scan_import" --ENV{.DM_SUSPENDED}=="1", ENV{MPATH_DEVICE_READY}="0", GOTO="scan_import" -- --ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" -+# upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD -+# is just empty (see comment above the DM_COOKIE test above). -+ENV{.MPATH_DEVICE_READY_OLD}=="0", \ -+ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or diff --git a/0038-RH-add-mpathconf.patch b/0010-RH-add-mpathconf.patch similarity index 99% rename from 0038-RH-add-mpathconf.patch rename to 0010-RH-add-mpathconf.patch index 103ca55..c587841 100644 --- a/0038-RH-add-mpathconf.patch +++ b/0010-RH-add-mpathconf.patch @@ -23,10 +23,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 4ac57510..3602a071 100644 +index 7843c380..ab5259cf 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt -@@ -126,9 +126,11 @@ Marzinski +@@ -127,9 +127,11 @@ Marzinski misdetection mpath mpathb @@ -38,7 +38,7 @@ index 4ac57510..3602a071 100644 multipathc multipathd multipathed -@@ -146,6 +148,7 @@ ontap +@@ -147,6 +149,7 @@ ontap OOM opensvc OPTFLAGS @@ -47,10 +47,10 @@ index 4ac57510..3602a071 100644 partx pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index 588ae9ee..3cb8449c 100644 +index b8317f4d..0bbaa981 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -964,6 +964,8 @@ int init_config__ (const char *file, struct config *conf) +@@ -939,6 +939,8 @@ int init_config__ (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); diff --git a/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch b/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch deleted file mode 100644 index cb129bf..0000000 --- a/0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 31 Oct 2024 13:11:21 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: clarify DM_ACTIVATION logic - -Our code is always setting MPATH_UNCHANGED and DM_ACTIVATION in -pairs. While DM_ACTIVATION is a global DM property, MPATH_UNCHANGED -is owned by us. Just set MPATH_UNCHANGED, and adapt DM_ACTIVATION -when necessary just in one place. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 20f8c6ac..a2655cb2 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -74,25 +74,25 @@ LABEL="check_mpath_unchanged" - - # A previous coldplug event occurred while the device was suspended. - # Activation might have been partially skipped. Activate the device now, --# i.e. disable the MPATH_UNCHANGED logic and set DM_ACTIVATION=1. -+# i.e. disable the MPATH_UNCHANGED logic. - ENV{DM_COLDPLUG_SUSPENDED}=="1", ENV{.DM_SUSPENDED}!="1", \ -- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0", \ -+ ENV{MPATH_UNCHANGED}="0", \ - PROGRAM="@SYSDIR_BIN@/logger -t 11-dm-mpath.rules -p daemon.notice \"Forcing activation of previously suspended device\"", \ - GOTO="check_mpath_ready" - - # DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem. --# Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its -+# Set the MPATH_UNCHANGED flag here as mpath reloads tables if any of its - # paths are lost/recovered. For any stack above the mpath device, this is not - # something that should be reacted upon since it would be useless extra work. - # It's exactly mpath's job to provide *seamless* device access to any of the - # paths that are available underneath. - ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", \ -- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" -+ ENV{MPATH_UNCHANGED}="1" - --# For path failed or reinstated events, unset DM_ACTIVATION. -+# For path failed or reinstated events, set MPATH_UNCHANGED. - # This is similar to the DM_SUBSYSTEM_UDEV_FLAG0 case above. - ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", \ -- ENV{DM_ACTIVATION}="0", ENV{MPATH_UNCHANGED}="1" -+ ENV{MPATH_UNCHANGED}="1" - - LABEL="check_mpath_ready" - -@@ -112,11 +112,10 @@ GOTO="scan_import" - - LABEL="mpath_is_ready" - --# If the device comes back online, set DM_ACTIVATION so that -+# If the device comes back online, clear MPATH_UNCHANGED so that - # upper layers will do a rescan. Don't do this if .MPATH_DEVICE_READY_OLD - # is just empty (see comment above the DM_COOKIE test above). --ENV{.MPATH_DEVICE_READY_OLD}=="0", \ -- ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" -+ENV{.MPATH_DEVICE_READY_OLD}=="0", ENV{MPATH_UNCHANGED}="0" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or -@@ -146,6 +145,10 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" - - LABEL="import_end" - -+# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. -+ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" -+ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" -+ - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now - ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" - diff --git a/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 97% rename from 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 4e781fa..612d876 100644 --- a/0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -138,14 +138,14 @@ index b88e9a4c..edd742aa 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 72e44849..69a6c39d 100644 +index 3d957733..7ef6e99e 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in -@@ -17,6 +17,7 @@ ConditionVirtualization=!container +@@ -19,6 +19,7 @@ StartLimitBurst=3 [Service] Type=notify NotifyAccess=main +ExecStartPre=-@BINDIR@/multipath -A ExecStart=@BINDIR@/multipathd -d -s ExecReload=@BINDIR@/multipathd reconfigure - TasksMax=infinity + Restart=on-failure diff --git a/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch b/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch deleted file mode 100644 index cb1620a..0000000 --- a/0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sun, 3 Nov 2024 23:04:08 +0100 -Subject: [PATCH] 11-dm-mpath-rules.in: skip one .DM_NOSCAN check - -We set .DM_NOSCAN above where we set DM_UDEV_DISABLE_OTHER_RULES_FLAG, too. If -the latter isn't set, .DM_NOSCAN can't be set. Skip the redundant test. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index a2655cb2..79227bec 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -132,7 +132,7 @@ ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="import_end" - ENV{DM_UDEV_RULES_VSN}!="1|2", GOTO="import_end" - - # Don't import the properties from db if we will run blkid later. --ENV{.DM_NOSCAN}!="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" -+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}!="1", GOTO="import_end" - - IMPORT{db}="ID_FS_TYPE" - IMPORT{db}="ID_FS_USAGE" diff --git a/0040-RH-reset-default-find_mutipaths-value-to-off.patch b/0012-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0040-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0012-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch b/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch deleted file mode 100644 index 36cd91d..0000000 --- a/0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sun, 3 Nov 2024 23:07:23 +0100 -Subject: [PATCH] 11-dm-mpath.rules.in: set .DM_NOSCAN if MPATH_UNCHANGED is - set - -When multipath reloads a device or fails or restores a path, the udev -rules disable LVM scanning, but since .DM_NOSCAN isn't set, blkid is -still run on the device. When multipath devices that are set to -queue_if_no_path lose all their paths at close to the same time, udev -workers can hang trying to run blkid. The blkid results shouldn't -change when multipathd is adding, removing, failing or reinstating -paths, aside from avoiding hanging udev processes, we're skipping -unnecessary work. - -Hence, set .DM_NOSCAN if MPATH_UNCHANGED is set, to avoid blkid from -being called in 13-dm.rules. - -Suggested-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/11-dm-mpath.rules.in | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/multipath/11-dm-mpath.rules.in b/multipath/11-dm-mpath.rules.in -index 79227bec..a816edbf 100644 ---- a/multipath/11-dm-mpath.rules.in -+++ b/multipath/11-dm-mpath.rules.in -@@ -145,9 +145,11 @@ IMPORT{db}="ID_PART_GPT_AUTO_ROOT" - - LABEL="import_end" - --# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION. -+# If MPATH_UNCHANGED is set, adapt DM_ACTIVATION and DM_NOSCAN. -+# .DM_NOSCAN controls whether blkid will be run in 13-dm-disk.rules; -+# we don't want to do that if MPATH_UNCHANGED is 1. - ENV{MPATH_UNCHANGED}=="0", ENV{DM_ACTIVATION}="1" --ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0" -+ENV{MPATH_UNCHANGED}=="1", ENV{DM_ACTIVATION}="0", ENV{.DM_NOSCAN}="1" - - # Reset previous DM_COLDPLUG_SUSPENDED if activation happens now - ENV{.DM_SUSPENDED}!="1", ENV{DM_ACTIVATION}=="1", ENV{DM_COLDPLUG_SUSPENDED}="" diff --git a/0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 100% rename from 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch diff --git a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 94% rename from 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 0d5baa3..3243375 100644 --- a/0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 5043330c..e14507e8 100644 +index b5851561..a3cc6e83 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1219,13 +1219,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 5043330c..e14507e8 100644 good_len = 8; break; default: -@@ -1245,10 +1241,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1243,10 +1239,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch b/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch deleted file mode 100644 index b7ae3c4..0000000 --- a/0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 7 Nov 2024 22:07:03 +0100 -Subject: [PATCH] libmultipath: don't set dev_loss_tmo to 0 for - NO_PATH_RETRY_FAIL - -If pp->dev_loss is DEV_LOSS_TMO_UNSET and min_dev_loss is 0 (which is -the case if no_path_retry is NO_PATH_RETRY_FAIL or NO_PATH_RETRY_UNDEF), -we will set pp->dev_loss to 0, which is wrong. Fix it. - -Fixes: 058b5f5 ("libmultipath: fix dev_loss_tmo even if not set in configuration") -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e94705bf..5043330c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -942,7 +942,7 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) - continue; - } - -- if (pp->dev_loss == DEV_LOSS_TMO_UNSET) -+ if (pp->dev_loss == DEV_LOSS_TMO_UNSET && min_dev_loss != 0) - pp->dev_loss = min_dev_loss; - else if (pp->dev_loss < min_dev_loss) { - pp->dev_loss = min_dev_loss; diff --git a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 96% rename from 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch index ef0ee42..97fb4df 100644 --- a/0043-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index a5024bb7..834b63b9 100644 +index 7774f1f4..0e836f0a 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch b/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch deleted file mode 100644 index f775e85..0000000 --- a/0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 14 Oct 2024 23:28:30 -0400 -Subject: [PATCH] multipathd: fix deferred_failback_tick for reload removes - -If reload_and_sync_map() removes the multipath device, -deferred_failback_tick() needs to decrement the counter so that it -doesn't skip the following device. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 1b7fd04f..e4ef9a1d 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2080,9 +2080,12 @@ deferred_failback_tick (struct vectors *vecs) - - if (!mpp->failback_tick && - need_switch_pathgroup(mpp, &need_reload)) { -- if (need_reload) -- reload_and_sync_map(mpp, vecs); -- else -+ if (need_reload) { -+ if (reload_and_sync_map(mpp, vecs) == 2) { -+ /* multipath device removed */ -+ i--; -+ } -+ } else - switch_pathgroup(mpp); - } - } diff --git a/0044-RH-compile-with-libreadline-support.patch b/0016-RH-compile-with-libreadline-support.patch similarity index 96% rename from 0044-RH-compile-with-libreadline-support.patch rename to 0016-RH-compile-with-libreadline-support.patch index 50781c3..e7579b0 100644 --- a/0044-RH-compile-with-libreadline-support.patch +++ b/0016-RH-compile-with-libreadline-support.patch @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 834b63b9..c482a181 100644 +index 0e836f0a..e1d3fcd1 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch b/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch deleted file mode 100644 index 12c9a51..0000000 --- a/0016-multipathd-fix-an-unsigned-int-ovwerflow.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 13 Nov 2024 16:19:49 +0100 -Subject: [PATCH] multipathd: fix an unsigned int ovwerflow - -Reported by coverity: "i--" may cause an underflow, which will again -cause an overflow when the loop continues. Use a signed int for -loops like this to make coverity happy. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index e4ef9a1d..3fb623fd 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2068,7 +2068,7 @@ static void - deferred_failback_tick (struct vectors *vecs) - { - struct multipath * mpp; -- unsigned int i; -+ int i; - bool need_reload; - - vector_foreach_slot (vecs->mpvec, mpp, i) { diff --git a/0045-RH-Add-mpathcleanup.patch b/0017-RH-Add-mpathcleanup.patch similarity index 100% rename from 0045-RH-Add-mpathcleanup.patch rename to 0017-RH-Add-mpathcleanup.patch diff --git a/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch b/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch deleted file mode 100644 index 64b90d7..0000000 --- a/0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 6 Nov 2024 22:17:16 +0100 -Subject: [PATCH] libmpathutil: avoid -Wcast-function-type-mismatch error with - clang 19 - -Avoid the following error with clang 19: - -msort.c:268:27: error: cast from '__compar_fn_t' (aka 'int (*)(const void *, const void *)') to '__compar_d_fn_t' (aka 'int (*)(const void *, const void *, void *)') converts to incompatible function type [-Werror,-Wcast-function-type-mismatch] - 268 | return msort_r (b, n, s, (__compar_d_fn_t)cmp, NULL); - | ^~~~~~~~~~~~~~~~~~~~ - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathutil/msort.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libmpathutil/msort.c b/libmpathutil/msort.c -index 50f799d9..9df7b267 100644 ---- a/libmpathutil/msort.c -+++ b/libmpathutil/msort.c -@@ -259,9 +259,12 @@ msort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) - * If this is safe for them, it should be for us, too. - */ - #pragma GCC diagnostic push --#if __GNUC__ >= 8 -+#if __GNUC__ >= 8 || __clang_major__ >= 19 - #pragma GCC diagnostic ignored "-Wcast-function-type" - #endif -+#if __clang_major__ >= 19 -+#pragma GCC diagnostic ignored "-Wcast-function-type-mismatch" -+#endif - void - msort (void *b, size_t n, size_t s, __compar_fn_t cmp) - { diff --git a/0018-Update-NEWS.md-for-0.10.1.patch b/0018-Update-NEWS.md-for-0.10.1.patch deleted file mode 100644 index 601b6e5..0000000 --- a/0018-Update-NEWS.md-for-0.10.1.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 17:59:14 +0100 -Subject: [PATCH] Update NEWS.md for 0.10.1 - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - NEWS.md | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/NEWS.md b/NEWS.md -index 69acda47..b740efb1 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -1,5 +1,28 @@ - # multipath-tools Release Notes - -+## multipath-tools 0.10.1, 2024/11 -+ -+This is the first bug fix release on the `stable-0.10.y` branch. It contains -+bug fixes from 0.11.0, and some CI-related fixes. -+ -+### Bug fixes -+ -+* Fixed the problem that multipathd wouldn't start on systems with certain types -+ of device mapper devices, in particular devices with multiple DM targets. -+ The problem was introduced in 0.10.0. -+ Fixes [#102](https://github.com/opensvc/multipath-tools/issues/102). -+* Fixed a corner case in the udev rules which could cause a device not to be -+ activated during boot if a cold plug uevent is processed for a previously -+ not configured multipath map while this map was suspended. This problem existed -+ since 0.9.8. -+* Fixed the problem that devices with `no_path_retry fail` and no setting -+ for `dev_loss_tmo` might get the `dev_loss_tmo` set to 0, causing the -+ device to be deleted immediately in the event of a transport disruption. -+ This bug was introduced in 0.9.6. -+* Fixed the problem that, if there were multiple maps with deferred failback -+ (`failback` value > 0 in `multipath.conf`), some maps might fail back later -+ than configured. The problem existed since 0.9.6. -+ - ## multipath-tools 0.10.0, 2024/08 - - ### User-Visible Changes diff --git a/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch b/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch deleted file mode 100644 index 18fb614..0000000 --- a/0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 14 Nov 2024 15:20:24 +0100 -Subject: [PATCH] libmultipath: don't print error message if WATCHDOG_USEC is 0 - -WATCHDOG_USEC may be set to 0, which means that the watchdog -is disabled in systemd. - -Fixes: 9366cfb ("multipathd: Implement systemd watchdog integration") -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 0e3a5cc1..226ddecb 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -865,6 +865,9 @@ static void set_max_checkint_from_watchdog(struct config *conf) - unsigned long checkint; - - if (envp && sscanf(envp, "%lu", &checkint) == 1) { -+ if (checkint == 0) -+ /* watchdog disabled */ -+ return; - /* Value is in microseconds */ - checkint /= 1000000; - if (checkint < 1 || checkint > UINT_MAX) { diff --git a/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch b/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch deleted file mode 100644 index 7467627..0000000 --- a/0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 25 Nov 2024 18:01:32 +0100 -Subject: [PATCH] libmultipath: reduce log level of "map X has multiple - targets" - -On systems with LVM volumes, "multipath -ll" will spit out lots of messages -like - - libmp_mapinfo: map vg-lv0 has multiple targets - -which is irritating. Reduce the log level of these messages to 3, as they -are harmless most of the time. - -This is a backport of e8949c2 ("libmultipath: reduce log level of -libmp_mapinfo() messages") from the master branch. We can't apply exactly -the same fix because the stable branch is missing 8c772d3 ("libmultipath: -check DM UUID earlier in libmp_mapinfo__"). - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 52bfe9ce..fe5637b3 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -718,7 +718,7 @@ static int libmp_mapinfo__(int flags, mapid_t id, mapinfo_t info, const char *ma - if (info.target || info.status || info.size || flags & MAPINFO_TGT_TYPE__) { - if (dm_get_next_target(dmt, NULL, &start, &length, - &target_type, ¶ms) != NULL) { -- condlog(2, "%s: map %s has multiple targets", fname__, map_id); -+ condlog(3, "%s: map %s has multiple targets", fname__, map_id); - return DMP_NOT_FOUND; - } - if (!params) { diff --git a/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch b/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch deleted file mode 100644 index 2610c6d..0000000 --- a/0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 8 Jan 2025 19:06:53 -0500 -Subject: [PATCH] libmultipath/foreign: fix memory leak in nvme foreign handler - -_find_controllers() needs to free the udev device if it doesn't get -added to a path. Otherwise it can leak memory whenever check_foreign() -is called, causing multipathd's memory usage to continually grow. - -Fixes: 7b47762 ("libmultipath: nvme: fix path detection for kernel 4.16") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit 5a3d334e416a4a35ee88d7b8f1433ff7f57923ad) ---- - libmultipath/foreign/nvme.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c -index 0b7f4eab..cde660ce 100644 ---- a/libmultipath/foreign/nvme.c -+++ b/libmultipath/foreign/nvme.c -@@ -675,7 +675,8 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - pthread_cleanup_push_cast(free_scandir_result, &sr); - for (i = 0; i < r; i++) { - char *fn = di[i]->d_name; -- struct udev_device *ctrl, *udev; -+ struct udev_device *ctrl; -+ struct udev_device *udev __attribute__((cleanup(cleanup_udev_device))) = NULL; - - if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, "/%s", fn)) - continue; -@@ -719,11 +720,11 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - continue; - - path->gen.ops = &nvme_path_ops; -- path->udev = udev; -+ path->udev = steal_ptr(udev); - path->seen = true; - path->map = map; - path->ctl = udev_device_get_parent_with_subsystem_devtype -- (udev, "nvme", NULL); -+ (path->udev, "nvme", NULL); - if (path->ctl == NULL) { - condlog(1, "%s: %s: failed to get controller for %s", - __func__, THIS, fn); -@@ -744,7 +745,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) - } - vector_set_slot(&map->pgvec, &path->pg); - condlog(3, "%s: %s: new path %s added to %s", -- __func__, THIS, udev_device_get_sysname(udev), -+ __func__, THIS, udev_device_get_sysname(path->udev), - udev_device_get_sysname(map->udev)); - } - pthread_cleanup_pop(1); diff --git a/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch b/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch deleted file mode 100644 index cf8d80a..0000000 --- a/0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: chenrenhui -Date: Fri, 10 Jan 2025 14:38:16 +0800 -Subject: [PATCH] libmultipath: add condition for enqueueing path to io error - check - -In function io_err_stat_handle_pathfail(), path->io_err_dis_reinstate_time -is set to 0 to enqueue path to io error check as soon as possible. But -multipathd can not do it within marginal_path_err_recheck_gap_time seconds -after power-on, because curr_time is less than -marginal_path_err_recheck_gap_time. - -To handle the early marginal path, we can enqueue path when -io_err_dis_reinstate_time is 0. - -Signed-off-by: chenrenhui -Reviewed-by: Benjamin Marzinski -Reviewed-by: Martin Wilck - -> - -(cherry picked from commit a1e3cf2d42cc4bab10753e466c8adb7efa83c99e) -Signed-off-by: Benjamin Marzinski ---- - libmultipath/io_err_stat.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 4996c0b0..879c310a 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -367,7 +367,8 @@ int need_io_err_check(struct path *pp) - return 1; - get_monotonic_time(&curr_time); - if ((curr_time.tv_sec - pp->io_err_dis_reinstate_time) > -- pp->mpp->marginal_path_err_recheck_gap_time) { -+ pp->mpp->marginal_path_err_recheck_gap_time || -+ pp->io_err_dis_reinstate_time == 0) { - io_err_stat_log(4, "%s: reschedule checking after %d seconds", - pp->dev, - pp->mpp->marginal_path_err_recheck_gap_time); diff --git a/0023-Additional-NEWS.md-updates-for-0.10.1.patch b/0023-Additional-NEWS.md-updates-for-0.10.1.patch deleted file mode 100644 index 1093bd0..0000000 --- a/0023-Additional-NEWS.md-updates-for-0.10.1.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 17 Jan 2025 22:38:26 +0100 -Subject: [PATCH] Additional NEWS.md updates for 0.10.1 - -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 4 ++-- - NEWS.md | 8 ++++++++ - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 934f582e..000d5ebb 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -184,7 +184,6 @@ sas - sbp - scsi - sda --sdc - setmarginal - setprkey - setprstatus -@@ -205,11 +204,11 @@ suse - svg - switchgroup - sys -+SYSDIR - sysfs - sysinit - tcp - terabytes --SYSDIR - TESTDEPS - testname - tgill -@@ -231,6 +230,7 @@ unsetprkey - unsetprstatus - unspec - usb -+USEC - userdata - userspace - usr -diff --git a/NEWS.md b/NEWS.md -index b740efb1..3c51553e 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -22,6 +22,14 @@ bug fixes from 0.11.0, and some CI-related fixes. - * Fixed the problem that, if there were multiple maps with deferred failback - (`failback` value > 0 in `multipath.conf`), some maps might fail back later - than configured. The problem existed since 0.9.6. -+* Removed a warning message that multipathd would print if systemd's -+ `WATCHDOG_USEC` environment variable had the value "0", which means that the -+ watchdog is simply disabled. This (minor) problem existed since 0.4.9. -+* Fixed a memory leak in the nvme foreign library. The bug existed since -+ 0.7.8. -+* Fixed a problem in the marginal path detection algorithm that could cause -+ the io error check for a recently failed path to be delayed. This bug -+ existed since 0.7.4. - - ## multipath-tools 0.10.0, 2024/08 - diff --git a/0024-libmultipath-fix-handling-of-pp-pgindex.patch b/0024-libmultipath-fix-handling-of-pp-pgindex.patch deleted file mode 100644 index a9da346..0000000 --- a/0024-libmultipath-fix-handling-of-pp-pgindex.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 25 Nov 2024 13:11:07 +0100 -Subject: [PATCH] libmultipath: fix handling of pp->pgindex - -pp->pgindex is set in disassemble_map() when a map is parsed. -There are various possiblities for this index to become invalid. -pp->pgindex is only used in enable_group() and followover_should_fallback(), -and both callers take no action if it is 0, which is the right -thing to do if we don't know the path's pathgroup. - -Make sure pp->pgindex is reset to 0 in various places: -- when it's orphaned, -- before (re)grouping paths, -- when we detect a bad mpp assignment in update_pathvec_from_dm(). -- when a pathgroup is deleted in update_pathvec_from_dm(). In this - case, pgindex needs to be invalidated for all paths in all pathgroups - after the one that was deleted. - -The hunk in group_paths is mostly redundant with the hunk in free_pgvec(), but -because we're looping over pg->paths in the former and over pg->pgp in -the latter, I think it's better too play safe. - -Fixes: 99db1bd ("[multipathd] re-enable disabled PG when at least one path is up") -Fixes: https://github.com/opensvc/multipath-tools/issues/105 -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -(cherry picked from commit cd912cffa2797a18c47426c816afa8eb2eae5b22) -(cherry picked from commit 714c20bebba6911255a527d937e7a62764ffe338) -Signed-off-by: Benjamin Marzinski ---- - libmultipath/pgpolicies.c | 6 ++++++ - libmultipath/structs.c | 12 +++++++++++- - libmultipath/structs_vec.c | 15 +++++++++++++++ - 3 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c -index edc3c611..23ef2bdc 100644 ---- a/libmultipath/pgpolicies.c -+++ b/libmultipath/pgpolicies.c -@@ -127,6 +127,8 @@ fail: - int group_paths(struct multipath *mp, int marginal_pathgroups) - { - vector normal, marginal; -+ struct path *pp; -+ int i; - - if (!mp->pg) - mp->pg = vector_alloc(); -@@ -138,6 +140,10 @@ int group_paths(struct multipath *mp, int marginal_pathgroups) - if (!mp->pgpolicyfn) - goto fail; - -+ /* Reset pgindex, we're going to invalidate it */ -+ vector_foreach_slot(mp->paths, pp, i) -+ pp->pgindex = 0; -+ - if (!marginal_pathgroups || - split_marginal_paths(mp->paths, &normal, &marginal) != 0) { - if (mp->pgpolicyfn(mp, mp->paths) != 0) -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 61c8f32c..48517252 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -239,8 +239,18 @@ free_pgvec (vector pgvec, enum free_path_mode free_paths) - if (!pgvec) - return; - -- vector_foreach_slot(pgvec, pgp, i) -+ vector_foreach_slot(pgvec, pgp, i) { -+ -+ /* paths are going to be re-grouped, reset pgindex */ -+ if (free_paths != FREE_PATHS) { -+ struct path *pp; -+ int j; -+ -+ vector_foreach_slot(pgp->paths, pp, j) -+ pp->pgindex = 0; -+ } - free_pathgroup(pgp, free_paths); -+ } - - vector_free(pgvec); - } -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 5df495b3..9dc5a5ca 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -108,6 +108,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - struct config *conf; - bool mpp_has_wwid; - bool must_reload = false; -+ bool pg_deleted = false; - - if (!mpp->pg) - return false; -@@ -125,6 +126,10 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - - vector_foreach_slot(pgp->paths, pp, j) { - -+ /* A pathgroup has been deleted before. Invalidate pgindex */ -+ if (pg_deleted) -+ pp->pgindex = 0; -+ - if (pp->mpp && pp->mpp != mpp) { - condlog(0, "BUG: %s: found path %s which is already in %s", - mpp->alias, pp->dev, pp->mpp->alias); -@@ -139,6 +144,13 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - must_reload = true; - dm_fail_path(mpp->alias, pp->dev_t); - vector_del_slot(pgp->paths, j--); -+ /* -+ * pp->pgindex has been set in disassemble_map(), -+ * which has probably been called just before for -+ * mpp. So he pgindex relates to mpp and may be -+ * wrong for pp->mpp. Invalidate it. -+ */ -+ pp->pgindex = 0; - continue; - } - pp->mpp = mpp; -@@ -237,6 +249,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - vector_del_slot(mpp->pg, i--); - free_pathgroup(pgp, KEEP_PATHS); - must_reload = true; -+ /* Invalidate pgindex for all other pathgroups */ -+ pg_deleted = true; - } - mpp->need_reload = mpp->need_reload || must_reload; - return must_reload; -@@ -354,6 +368,7 @@ void orphan_path(struct path *pp, const char *reason) - { - condlog(3, "%s: orphan path, %s", pp->dev, reason); - pp->mpp = NULL; -+ pp->pgindex = 0; - uninitialize_path(pp); - } - diff --git a/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch b/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch deleted file mode 100644 index b2b9e48..0000000 --- a/0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 25 Nov 2024 15:18:15 +0100 -Subject: [PATCH] libmultipath: make pgcmp detect if map is missing a path - group - -The previous algorithm didn't detect the case case where cpgp -contained a path that was not contained in pgp. Fix this. - -Cherry-picked from d4b35f61cb75c6e9b289e56c98457fc04ce4835e -Fixes: 90773ba ("libmultipath: resolve hash collisions in pgcmp()") -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index a7257981..e86c1fd5 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -426,6 +426,11 @@ compute_pgid(struct pathgroup * pgp) - pgp->id ^= (long)pp; - } - -+static void cleanup_bitfield(struct bitfield **p) -+{ -+ free(*p); -+} -+ - static int - pgcmp (struct multipath * mpp, struct multipath * cmpp) - { -@@ -433,16 +438,25 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) - struct pathgroup * pgp; - struct pathgroup * cpgp; - int r = 0; -+ struct bitfield *bf __attribute__((cleanup(cleanup_bitfield))) = NULL; - - if (!mpp) - return 0; - -+ if (VECTOR_SIZE(mpp->pg) != VECTOR_SIZE(cmpp->pg)) -+ return 1; -+ -+ bf = alloc_bitfield(VECTOR_SIZE(cmpp->pg)); -+ if (!bf) -+ return 1; -+ - vector_foreach_slot (mpp->pg, pgp, i) { - compute_pgid(pgp); - - vector_foreach_slot (cmpp->pg, cpgp, j) { - if (pgp->id == cpgp->id && - !pathcmp(pgp, cpgp)) { -+ set_bit_in_bitfield(j, bf); - r = 0; - break; - } -@@ -451,6 +465,10 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp) - if (r) - return r; - } -+ vector_foreach_slot (cmpp->pg, cpgp, j) { -+ if (!is_bit_set_in_bitfield(j, bf)) -+ return 1; -+ } - return r; - } - diff --git a/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch b/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch deleted file mode 100644 index bd3a7a4..0000000 --- a/0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 26 Nov 2024 22:37:20 +0100 -Subject: [PATCH] libmultipath: trigger uevents upon map creation in domap() - -If map creation succeeds, previously not multipathed devices are -now multipathed. udev may not have noticed this yet, thus trigger -path uevents to make it aware of the situation. Likewise, if -creating a map fails, the paths in question were likely considered -multipath members by udev, too. They will now be marked as failed, -so trigger an event in this situation as well. - -Fixes: https://github.com/opensvc/multipath-tools/issues/103 -Suggested-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -(cherry picked from commit 98b3a7bd9ed2a89f068fe40c253843cf78261905) -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 11 ++++------- - libmultipath/devmapper.c | 9 +++------ - 2 files changed, 7 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index e86c1fd5..d9fac384 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -581,8 +581,6 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) - vector_foreach_slot(pgp->paths, pp, j) - trigger_path_udev_change(pp, is_mpath); - } -- -- mpp->needs_paths_uevent = 0; - } - - static int sysfs_set_max_sectors_kb(struct multipath *mpp) -@@ -954,10 +952,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - * succeeded - */ - mpp->force_udev_reload = 0; -- if (mpp->action == ACT_CREATE && -- (remember_wwid(mpp->wwid) == 1 || -- mpp->needs_paths_uevent)) -+ if (mpp->action == ACT_CREATE) { -+ remember_wwid(mpp->wwid); - trigger_paths_udev_change(mpp, true); -+ } - if (!is_daemon) { - /* multipath client mode */ - dm_switchgroup(mpp->alias, mpp->bestpg); -@@ -982,8 +980,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - } - dm_setgeometry(mpp); - return DOMAP_OK; -- } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE && -- mpp->needs_paths_uevent) -+ } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE) - trigger_paths_udev_change(mpp, false); - - return DOMAP_FAIL; -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index fe5637b3..a0070c56 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -536,7 +536,7 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) - MPATH_UDEV_RELOAD_FLAG : 0); - } - --int dm_addmap_create (struct multipath *mpp, char * params) -+int dm_addmap_create (struct multipath *mpp, char *params) - { - int ro; - uint16_t udev_flags = build_udev_flags(mpp, 0); -@@ -546,9 +546,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) - - if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro, - udev_flags)) { -- if (unmark_failed_wwid(mpp->wwid) == -- WWID_FAILED_CHANGED) -- mpp->needs_paths_uevent = 1; -+ unmark_failed_wwid(mpp->wwid); - return 1; - } - /* -@@ -566,8 +564,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) - break; - } - } -- if (mark_failed_wwid(mpp->wwid) == WWID_FAILED_CHANGED) -- mpp->needs_paths_uevent = 1; -+ mark_failed_wwid(mpp->wwid); - return 0; - } - diff --git a/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch b/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch deleted file mode 100644 index f43ca0c..0000000 --- a/0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 27 Nov 2024 20:39:50 +0100 -Subject: [PATCH] multipathd: trigger uevents upon map removal in - coalesce_maps() - -... if a map has been flushed. In this case, we know that the -the paths haven't been multipathed by coalesce_paths() because of the current -configuration (failure to create the map can't be the reason if the map -exists in coalesce_maps()). Make sure udev sees the paths which have -been released from the map as non-multipath. - -Note that this is the only case where maps are flushed where it is correct -to trigger paths uevents. In other cases, e.g. after a "remove map" CLI -command, the configuration is unchanged and if we triggered an uevent, -the map would be re-created by multipathd when the uevent arrived. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -(cherry picked from commit ad3ea472b587c0c20d2100331b5c66f8602f8414) -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 3fb623fd..4b089c0e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -794,8 +794,10 @@ coalesce_maps(struct vectors *vecs, vector nmpv) - vector_del_slot(ompv, i); - i--; - } -- else -+ else { - condlog(2, "%s devmap removed", ompp->alias); -+ trigger_paths_udev_change(ompp, false); -+ } - } else if (reassign_maps) { - condlog(3, "%s: Reassign existing device-mapper" - " devices", ompp->alias); diff --git a/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch b/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch deleted file mode 100644 index 6c001f5..0000000 --- a/0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 4 Dec 2024 22:56:36 -0500 -Subject: [PATCH] libmultipath: Don't skip set_path_max_sectors_kb() - -If a multipath device already has need_reload set when a path is -adopted, it won't call set_path_max_sectors_kb() because of -short-circuit evaluation. This isn't what's intended. - -Fixes: e5e20c7b ("libmultipath: set max_sectors_kb in adopt_paths()") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit f5c0c4b25c5eaac87b78e6e0c8d52b0828c29893) ---- - libmultipath/structs_vec.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 9dc5a5ca..683ab473 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -349,8 +349,7 @@ int adopt_paths(vector pathvec, struct multipath *mpp, - */ - if (!current_mpp || - !mp_find_path_by_devt(current_mpp, pp->dev_t)) -- mpp->need_reload = mpp->need_reload || -- set_path_max_sectors_kb(pp, mpp->max_sectors_kb); -+ mpp->need_reload = set_path_max_sectors_kb(pp, mpp->max_sectors_kb) || mpp->need_reload; - } - - pp->mpp = mpp; diff --git a/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch b/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch deleted file mode 100644 index e293a0e..0000000 --- a/0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 22 Jan 2025 22:16:42 -0500 -Subject: [PATCH] libmultipath: stop static analyzer complaint in init_foreign - -This change doesn't actually fix anything. The code was already safe. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit 85ec51e7930b4cadfbc12718afa91ce3a4adf4b5) ---- - libmultipath/foreign.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c -index 28d1b115..af5b0ed3 100644 ---- a/libmultipath/foreign.c -+++ b/libmultipath/foreign.c -@@ -129,7 +129,7 @@ static void free_pre(void *arg) - static int _init_foreign(const char *enable) - { - char pathbuf[PATH_MAX]; -- struct dirent **di; -+ struct dirent **di = NULL; - struct scandir_result sr; - int r, i; - regex_t *enable_re = NULL; diff --git a/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch b/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch deleted file mode 100644 index 06a1b0f..0000000 --- a/0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 22 Jan 2025 22:16:43 -0500 -Subject: [PATCH] libmultipath: be lenient in allowing the alua-based - pgpolicies - -multipath wouldn't autodetect the GROUP_BY_PRIO path grouping policy or -allow the GROUP_BY_TPG policy if there was a path that didn't have its -prioritizer selected (for instance because multipathd was reconfigured -while it was offline). To avoid this, make verify_alua_prio() assume an -alua multipath device if all the paths with a prioritizer selected -(there must be at least one) use an alua-based prioritizer. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck -(cherry picked from commit b47a577998eaff203018a00b57ba5e3674645848) ---- - libmultipath/propsel.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index a3fce203..c09a0619 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -255,14 +255,18 @@ verify_alua_prio(struct multipath *mp) - { - int i; - struct path *pp; -+ bool assume_alua = false; - - vector_foreach_slot(mp->paths, pp, i) { - const char *name = prio_name(&pp->prio); -+ if (!prio_selected(&pp->prio)) -+ continue; - if (strncmp(name, PRIO_ALUA, PRIO_NAME_LEN) && - strncmp(name, PRIO_SYSFS, PRIO_NAME_LEN)) - return false; -+ assume_alua = true; - } -- return true; -+ return assume_alua; - } - - int select_detect_pgpolicy(struct config *conf, struct multipath *mp) diff --git a/0031-Update-NEWS.md-for-0.10.2.patch b/0031-Update-NEWS.md-for-0.10.2.patch deleted file mode 100644 index fd31420..0000000 --- a/0031-Update-NEWS.md-for-0.10.2.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 24 Jan 2025 20:03:15 +0100 -Subject: [PATCH] Update NEWS.md for 0.10.2 - -Signed-off-by: Benjamin Marzinski ---- - .github/actions/spelling/expect.txt | 2 ++ - NEWS.md | 23 ++++++++++++++++++++++- - 2 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 000d5ebb..4ac57510 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -11,6 +11,7 @@ ata - autoconfig - autodetected - autoresize -+backported - barbie - BINDIR - blkid -@@ -122,6 +123,7 @@ Lun - lvm - lvmteam - Marzinski -+misdetection - mpath - mpathb - mpathpersist -diff --git a/NEWS.md b/NEWS.md -index 3c51553e..1b239ffa 100644 ---- a/NEWS.md -+++ b/NEWS.md -@@ -1,6 +1,27 @@ - # multipath-tools Release Notes - --## multipath-tools 0.10.1, 2024/11 -+## multipath-tools 0.10.2, 2025/02 -+ -+This release contains backported bug fixes from the stable-0.11.y branch. -+ -+### Bug fixes -+ -+* Fix multipathd crash because of invalid path group index value, for example -+ if an invalid path device was removed from a map. -+ Fixes [#105](https://github.com/opensvc/multipath-tools/issues/105). -+* Make sure maps are reloaded in the path checker loop after detecting an -+ inconsistent or wrong kernel state (e.g. missing or falsely mapped path -+ device). Wrongly mapped paths will be unmapped and released to the system. -+ Fixes another issue reported in -+ [#105](https://github.com/opensvc/multipath-tools/issues/105). -+* Fix the problem that `group_by_tpg` might be disabled if one or more -+ paths were offline during initial configuration. -+* Fix possible misdetection of changed pathgroups in a map. -+* Fix the problem that if a map was scheduled to be reloaded already, -+ `max_sectors_kb` might not be set on a path device that -+ was being added to a multipath map. This problem was introduced in 0.9.9. -+ -+## multipath-tools 0.10.1, 2025/01 - - This is the first bug fix release on the `stable-0.10.y` branch. It contains - bug fixes from 0.11.0, and some CI-related fixes. diff --git a/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch b/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch deleted file mode 100644 index 3ddab39..0000000 --- a/0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Sat, 25 Jan 2025 00:49:19 +0100 -Subject: [PATCH] GitHub Workflows: fix abi-stable.yaml for pull request - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .github/workflows/abi-stable.yaml | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/.github/workflows/abi-stable.yaml b/.github/workflows/abi-stable.yaml -index a6746f23..472914ce 100644 ---- a/.github/workflows/abi-stable.yaml -+++ b/.github/workflows/abi-stable.yaml -@@ -15,12 +15,16 @@ on: - - jobs: - reference-abi: -- runs-on: ubuntu-20.04 -+ runs-on: ubuntu-22.04 - steps: - - name: get parent tag - run: > - echo ${{ github.ref }} | - sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ if: ${{ github.event_name == 'push' }} -+ - name: get parent tag -+ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV -+ if: ${{ github.event_name == 'pull_request' }} - - name: assert parent tag - run: /bin/false - if: ${{ env.PARENT_TAG == '' }} -@@ -45,20 +49,24 @@ jobs: - path: abi - - check-abi: -- runs-on: ubuntu-20.04 -+ runs-on: ubuntu-22.04 - needs: reference-abi - steps: - - name: get parent tag - run: > - echo ${{ github.ref }} | - sed -E 's,refs/heads/stable-([0-9]\.[0-9]*)\.y,PARENT_TAG=\1.0,' >> $GITHUB_ENV -+ if: ${{ github.event_name == 'push' }} -+ - name: get parent tag -+ run: echo PARENT_TAG=${{ github.base_ref }} >> $GITHUB_ENV -+ if: ${{ github.event_name == 'pull_request' }} - - name: assert parent tag - run: /bin/false - if: ${{ env.PARENT_TAG == '' }} -- - name: checkout ${{ env.PARENT_TAG }} -+ - name: checkout ${{ github.base_ref }} - uses: actions/checkout@v4 - with: -- ref: ${{ env.PARENT_TAG }} -+ ref: ${{ github.base_ref }} - - name: download ABI for ${{ env.PARENT_TAG }} - id: download_abi - uses: actions/download-artifact@v4 diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 8e469ab..2de9457 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath -Version: 0.10.0 -Release: 5%{?dist} +Version: 0.11.1 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -8,54 +8,26 @@ URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.10.0.tar.gz -o multipath-tools-0.10.0.tgz -Source0: multipath-tools-0.10.0.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.11.1.tar.gz -o multipath-tools-0.11.1.tgz +Source0: multipath-tools-0.11.1.tgz Source1: multipath.conf -Patch0001: 0001-GitHub-workflows-use-upload-download-artifact-v4.patch -Patch0002: 0002-GitHub-workflows-update-dawidd6-action-download-arti.patch -Patch0003: 0003-Github-workflows-native.yml-use-mosteo-actions-docke.patch -Patch0004: 0004-GitHub-workflows-native.yml-use-extra-job-for-clang.patch -Patch0005: 0005-GitHub-workflows-native.yaml-make-test-and-archive-s.patch -Patch0006: 0006-GitHub-workflows-enable-unit-tests-for-stable-branch.patch -Patch0007: 0007-GitHub-Workflows-add-abi-check-for-stable-branches.patch -Patch0008: 0008-libmultipath-dm_get_maps-don-t-bail-out-for-single-m.patch -Patch0009: 0009-11-dm-mpath.rules.in-import-DM_COLDPLUG_SUSPENDED-on.patch -Patch0010: 0010-11-dm-mpath.rules.in-handle-inactive-suspended-devic.patch -Patch0011: 0011-11-dm-mpath.rules.in-clarify-DM_ACTIVATION-logic.patch -Patch0012: 0012-11-dm-mpath-rules.in-skip-one-.DM_NOSCAN-check.patch -Patch0013: 0013-11-dm-mpath.rules.in-set-.DM_NOSCAN-if-MPATH_UNCHANG.patch -Patch0014: 0014-libmultipath-don-t-set-dev_loss_tmo-to-0-for-NO_PATH.patch -Patch0015: 0015-multipathd-fix-deferred_failback_tick-for-reload-rem.patch -Patch0016: 0016-multipathd-fix-an-unsigned-int-ovwerflow.patch -Patch0017: 0017-libmpathutil-avoid-Wcast-function-type-mismatch-erro.patch -Patch0018: 0018-Update-NEWS.md-for-0.10.1.patch -Patch0019: 0019-libmultipath-don-t-print-error-message-if-WATCHDOG_U.patch -Patch0020: 0020-libmultipath-reduce-log-level-of-map-X-has-multiple-.patch -Patch0021: 0021-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch -Patch0022: 0022-libmultipath-add-condition-for-enqueueing-path-to-io.patch -Patch0023: 0023-Additional-NEWS.md-updates-for-0.10.1.patch -Patch0024: 0024-libmultipath-fix-handling-of-pp-pgindex.patch -Patch0025: 0025-libmultipath-make-pgcmp-detect-if-map-is-missing-a-p.patch -Patch0026: 0026-libmultipath-trigger-uevents-upon-map-creation-in-do.patch -Patch0027: 0027-multipathd-trigger-uevents-upon-map-removal-in-coale.patch -Patch0028: 0028-libmultipath-Don-t-skip-set_path_max_sectors_kb.patch -Patch0029: 0029-libmultipath-stop-static-analyzer-complaint-in-init_.patch -Patch0030: 0030-libmultipath-be-lenient-in-allowing-the-alua-based-p.patch -Patch0031: 0031-Update-NEWS.md-for-0.10.2.patch -Patch0032: 0032-GitHub-Workflows-fix-abi-stable.yaml-for-pull-reques.patch -Patch0033: 0033-RH-fixup-udev-rules-for-redhat.patch -Patch0034: 0034-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0035: 0035-RH-don-t-start-without-a-config-file.patch -Patch0036: 0036-RH-Fix-nvme-function-missing-argument.patch -Patch0037: 0037-RH-use-rpm-optflags-if-present.patch -Patch0038: 0038-RH-add-mpathconf.patch -Patch0039: 0039-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0040: 0040-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0041: 0041-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0042: 0042-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0043: 0043-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0044: 0044-RH-compile-with-libreadline-support.patch -Patch0045: 0045-RH-Add-mpathcleanup.patch +Patch0001: 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch +Patch0002: 0002-multipath-tools-fix-compilation-with-latest-userspac.patch +Patch0003: 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch +Patch0004: 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch +Patch0005: 0005-RH-fixup-udev-rules-for-redhat.patch +Patch0006: 0006-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0007: 0007-RH-don-t-start-without-a-config-file.patch +Patch0008: 0008-RH-Fix-nvme-function-missing-argument.patch +Patch0009: 0009-RH-use-rpm-optflags-if-present.patch +Patch0010: 0010-RH-add-mpathconf.patch +Patch0011: 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0012: 0012-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0013: 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0014: 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0015: 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0016: 0016-RH-compile-with-libreadline-support.patch +Patch0017: 0017-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -143,7 +115,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.10.0 -p1 +%autosetup -n multipath-tools-0.11.1 -p1 cp %{SOURCE1} . %build @@ -265,6 +237,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Feb 27 2025 Benjamin Marzinski - 0.11.1-1 +- Update source to upstream staging branch for 0.11.1 plus additional + stable branch patches. + * Previous patches 0001-0032 are included in the tarball +- Rename redhat patches + * Previous patches 0033-0045 are now patches 0005-0017 + * Sat Feb 1 2025 Benjamin Marzinski - 0.10.0-5 - Update source to upstream staging branch for 0.10.y (will be 0.10.2 when merged). diff --git a/sources b/sources index da06e16..5eea94e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.10.0.tgz) = 8f545609fa20df7547428f2929571dc0df87c17d9f61f11aad3559446c2e94755e18b1c4b3780b3de92ec2cbc450939ca15a9d6c95551eee4084064d83874b2d +SHA512 (multipath-tools-0.11.1.tgz) = ac6bacd725bc831a140b75a72c81296eb1ed4080fb6350caf6178914d1bdce743705f3bd4e31f318068f6272dc98e12d63ee38228a3521a3d1c7bc8eb30812f9 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From 9f48ebd2e22ad64a101f59f06a9e8306f6e3b317 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 19:12:54 +0000 Subject: [PATCH 31/33] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- device-mapper-multipath.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 2de9457..232daba 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.11.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -237,6 +237,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 0.11.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Thu Feb 27 2025 Benjamin Marzinski - 0.11.1-1 - Update source to upstream staging branch for 0.11.1 plus additional stable branch patches. From 3c9f48504bb89ec2a2c84cfffbeaf2f2811fcefd Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 4 Nov 2025 18:02:43 -0500 Subject: [PATCH 32/33] device-mapper-multipath-0.13.0-1 Update source to upstream release 0.13.0 * Previous patches 0001-0004 are included in the tarball Install /lib/systemd/system/multipathd-queueing.service Rename redhat patches * Previous patches 0005-0017 are now patches 0001-0013 --- .gitignore | 1 + ... 0001-RH-fixup-udev-rules-for-redhat.patch | 4 +- ...er-uevents-for-blacklisted-paths-in-.patch | 101 ------------------ ...property-blacklist-exception-builtin.patch | 14 +-- ...fix-compilation-with-latest-userspac.patch | 63 ----------- ...RH-don-t-start-without-a-config-file.patch | 24 ++--- ...-include-urcu.h-before-urcu-atomic.h.patch | 40 ------- ...H-Fix-nvme-function-missing-argument.patch | 6 +- ...uxsock.c-Include-string.h-for-memcpy.patch | 29 ----- ... 0005-RH-use-rpm-optflags-if-present.patch | 12 ++- ...hconf.patch => 0006-RH-add-mpathconf.patch | 8 +- ...om-kernel-cmdline-mpath.wwids-with-A.patch | 16 +-- ...-default-find_mutipaths-value-to-off.patch | 8 +- ...empt-to-get-ANA-info-via-sysfs-first.patch | 14 +-- ...-parse_vpd_pg83-match-scsi_id-output.patch | 8 +- ...si-device-handlers-to-modules-load.d.patch | 4 +- ...-RH-compile-with-libreadline-support.patch | 4 +- ...up.patch => 0013-RH-Add-mpathcleanup.patch | 2 +- device-mapper-multipath.spec | 48 +++++---- sources | 2 +- 20 files changed, 91 insertions(+), 317 deletions(-) rename 0005-RH-fixup-udev-rules-for-redhat.patch => 0001-RH-fixup-udev-rules-for-redhat.patch (96%) delete mode 100644 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch rename 0006-RH-Remove-the-property-blacklist-exception-builtin.patch => 0002-RH-Remove-the-property-blacklist-exception-builtin.patch (91%) delete mode 100644 0002-multipath-tools-fix-compilation-with-latest-userspac.patch rename 0007-RH-don-t-start-without-a-config-file.patch => 0003-RH-don-t-start-without-a-config-file.patch (88%) delete mode 100644 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch rename 0008-RH-Fix-nvme-function-missing-argument.patch => 0004-RH-Fix-nvme-function-missing-argument.patch (84%) delete mode 100644 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch rename 0009-RH-use-rpm-optflags-if-present.patch => 0005-RH-use-rpm-optflags-if-present.patch (85%) rename 0010-RH-add-mpathconf.patch => 0006-RH-add-mpathconf.patch (99%) rename 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (92%) rename 0012-RH-reset-default-find_mutipaths-value-to-off.patch => 0008-RH-reset-default-find_mutipaths-value-to-off.patch (87%) rename 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch (86%) rename 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch => 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch (91%) rename 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch => 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch (89%) rename 0016-RH-compile-with-libreadline-support.patch => 0012-RH-compile-with-libreadline-support.patch (89%) rename 0017-RH-Add-mpathcleanup.patch => 0013-RH-Add-mpathcleanup.patch (98%) diff --git a/.gitignore b/.gitignore index 8cd21df..c297b30 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ multipath-tools-091027.tar.gz /multipath-tools-0.9.9.tgz /multipath-tools-0.10.0.tgz /multipath-tools-0.11.1.tgz +/multipath-tools-0.13.0.tgz diff --git a/0005-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch similarity index 96% rename from 0005-RH-fixup-udev-rules-for-redhat.patch rename to 0001-RH-fixup-udev-rules-for-redhat.patch index 0135f49..ed5b7e9 100644 --- a/0005-RH-fixup-udev-rules-for-redhat.patch +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 64a07df23affd21842fdc604887276e62e5b41de Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Apr 2017 07:22:23 -0500 Subject: [PATCH] RH: fixup udev rules for redhat @@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 65f6efc8..c225a1ed 100644 +index 9e3dc466..ead89030 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -34,7 +34,7 @@ endif diff --git a/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch b/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch deleted file mode 100644 index 72bcf69..0000000 --- a/0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 23 Jan 2025 22:19:39 +0100 -Subject: [PATCH] multipathd: trigger uevents for blacklisted paths in - reconfigure - -If multipathd has already configured maps, and the user changes the -blacklist or other parameters that cause currently multipathed -devices to be skipped, and then runs "multipathd reconfigure" -or restarts multipathd, multipathd flushes the maps in question, -but doesn't trigger uevents for the now-blacklisted paths. - -This is because the blacklisted paths are removed from the discovered -maps internally when update_pathvec_from_dm() is called through -map_discovery() and update_multipath_table(); when later -trigger_paths_udev_change() is called from coalesce_maps(), the -map contains no paths for which an uevent could be triggered. - -The map_discovery() code flow is special, because we will call -coalesce_paths() afterwards anyway and reconstruct the mpvec. Unlike the -regular code flow, we don't want the maps to be "corrected" in this -case, because the maps discovered here aren't going to be reloaded. -We just want update_pathvec_from_dm() to populate the pathvec. - -Therefore add a new flag DI_DISCOVERY, which is only set when -update_multipath_table() is called from map_discovery(), and if -this flag is set, keep PATHINFO_SKIPPED paths in the map's table in -update_pathvec_from_dm(). Later on, the paths will still be visible -in the old mpp (ompp) in coalesce_maps(), and uevents will be -triggered for them to release them to systemd. - -We can't always do this for PATHINFO_SKIPPED, because in some cases -paths may be accepted in a map first and SKIPPED later (for example if -the WWID wasn't yet available at startup). Therefore the special -case for DI_DISCOVERY is necessary. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.h | 2 ++ - libmultipath/structs_vec.c | 6 +++++- - multipathd/main.c | 2 +- - 3 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 7d42eae5..9824a8d3 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -72,6 +72,7 @@ enum discovery_mode { - DI_BLACKLIST__, - DI_NOIO__, - DI_NOFALLBACK__, -+ DI_DISCOVERY__, - }; - - #define DI_SYSFS (1 << DI_SYSFS__) -@@ -82,6 +83,7 @@ enum discovery_mode { - #define DI_BLACKLIST (1 << DI_BLACKLIST__) - #define DI_NOIO (1 << DI_NOIO__) /* Avoid IO on the device */ - #define DI_NOFALLBACK (1 << DI_NOFALLBACK__) /* do not allow wwid fallback */ -+#define DI_DISCOVERY (1 << DI_DISCOVERY__) /* set only during map discovery */ - - #define DI_ALL (DI_SYSFS | DI_SERIAL | DI_CHECKER | DI_PRIO | \ - DI_WWID) -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 7a4e3eb0..5ccdaea0 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -109,6 +109,9 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - bool mpp_has_wwid; - bool must_reload = false; - bool pg_deleted = false; -+ bool map_discovery = !!(pathinfo_flags & DI_DISCOVERY); -+ -+ pathinfo_flags &= ~DI_DISCOVERY; - - if (!mpp->pg) - return false; -@@ -195,7 +198,8 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, - rc = pathinfo(pp, conf, - DI_SYSFS|DI_WWID|DI_BLACKLIST|DI_NOFALLBACK|pathinfo_flags); - pthread_cleanup_pop(1); -- if (rc != PATHINFO_OK) { -+ if (rc == PATHINFO_FAILED || -+ (rc == PATHINFO_SKIPPED && !map_discovery)) { - condlog(1, "%s: error %d in pathinfo, discarding path", - pp->dev, rc); - vector_del_slot(pgp->paths, j--); -diff --git a/multipathd/main.c b/multipathd/main.c -index 9ed27da0..fb3e44a8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1763,7 +1763,7 @@ map_discovery (struct vectors * vecs) - return 1; - - vector_foreach_slot (vecs->mpvec, mpp, i) -- if (update_multipath_table(mpp, vecs->pathvec, 0) != DMP_OK) { -+ if (update_multipath_table(mpp, vecs->pathvec, DI_DISCOVERY) != DMP_OK) { - remove_map(mpp, vecs->pathvec, vecs->mpvec); - i--; - } diff --git a/0006-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 91% rename from 0006-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch index a74e6c2..b8e580a 100644 --- a/0006-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f7be16ac9fce97585a4552d49f3d3c54a93c9c17 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 2 Jul 2014 12:49:53 -0500 Subject: [PATCH] RH: Remove the property blacklist exception builtin @@ -42,10 +42,10 @@ index 17e1b54a..10d13e98 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 4388baad..af9fbb96 100644 +index 3c9ae097..ba291e11 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1469,9 +1469,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1470,9 +1470,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,7 +61,7 @@ index 4388baad..af9fbb96 100644 . .RS .PP -@@ -1482,10 +1487,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1483,10 +1488,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -73,10 +73,10 @@ index 4388baad..af9fbb96 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index ba8dfd07..693db3fa 100644 +index ab3da619..52ae03e0 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -384,9 +384,8 @@ static void test_property_missing(void **state) +@@ -371,9 +371,8 @@ static void test_property_missing(void **state) { static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; conf.blist_property = blist_property_wwn; @@ -87,7 +87,7 @@ index ba8dfd07..693db3fa 100644 assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -478,9 +477,7 @@ static void test_filter_path_missing1(void **state) +@@ -465,9 +464,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0002-multipath-tools-fix-compilation-with-latest-userspac.patch b/0002-multipath-tools-fix-compilation-with-latest-userspac.patch deleted file mode 100644 index 03d7d9d..0000000 --- a/0002-multipath-tools-fix-compilation-with-latest-userspac.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 3 Feb 2025 16:43:42 -0500 -Subject: [PATCH] multipath-tools: fix compilation with latest userspace-rcu - code - -starting with version 0.15, userspace-rcu can be compiled with -CONFIG_RCU_USE_ATOMIC_BUILTINS. If it is, then any programs using it -must be compiled with at least the C11 standard. See: -https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f - -To deal with this, check if compiling with gnu99 fails, and if so, -switch to using gnu11. - -Based-on-patch-by: Yaakov Selkowitz -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - Makefile.inc | 2 +- - create-config.mk | 13 +++++++++++++ - 2 files changed, 14 insertions(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 729618bd..65f6efc8 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -115,7 +115,7 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ - -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP --CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -+CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions - BIN_CFLAGS := -fPIE -DPIE - LIB_CFLAGS := -fPIC -diff --git a/create-config.mk b/create-config.mk -index 8bd2c20c..ab163ed1 100644 ---- a/create-config.mk -+++ b/create-config.mk -@@ -157,6 +157,18 @@ FORTIFY_OPT := $(shell \ - echo "-D_FORTIFY_SOURCE=2"; \ - fi) - -+# Check is you can compile with the urcu.h header, using the C99 standard. -+# If urcu/config-.h defines CONFIG_RCU_USE_ATOMIC_BUILTINS, then anything -+# including urcu.h must be compiled with at least the C11 standard. See: -+# https://github.com/urcu/userspace-rcu/commit/89280d020bf064d1055c360fb9974f128051043f -+C_STD := $(shell \ -+ if printf '$(__HASH__)include \nint main(void) { return 0; }\n' | $(CC) -o /dev/null -c -xc --std=gnu99 - 2>/dev/null; \ -+ then \ -+ echo "gnu99"; \ -+ else \ -+ echo "gnu11"; \ -+ fi) -+ - STACKPROT := - - all: $(TOPDIR)/config.mk -@@ -182,3 +194,4 @@ $(TOPDIR)/config.mk: $(multipathdir)/autoconfig.h - @echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@ - @echo "W_URCU_TYPE_LIMITS := $(call TEST_URCU_TYPE_LIMITS)" >>$@ - @echo "ENABLE_LIBDMMP := $(ENABLE_LIBDMMP)" >>$@ -+ @echo "C_STD := $(C_STD)" >>$@ diff --git a/0007-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch similarity index 88% rename from 0007-RH-don-t-start-without-a-config-file.patch rename to 0003-RH-don-t-start-without-a-config-file.patch index edbc647..05d4e7a 100644 --- a/0007-RH-don-t-start-without-a-config-file.patch +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 5613e07ce9cabf2fdc402f6f102cc54bd1059800 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 15 Oct 2014 10:39:30 -0500 Subject: [PATCH] RH: don't start without a config file @@ -18,7 +18,7 @@ Signed-off-by: Benjamin Marzinski multipath/multipath.rules.in | 1 + multipathd/multipathd.8.in | 2 ++ multipathd/multipathd.service.in | 1 + - multipathd/multipathd.socket | 1 + + multipathd/multipathd.socket.in | 1 + 7 files changed, 25 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c @@ -58,10 +58,10 @@ index 5b4ebf8c..2302eacc 100644 enum devtypes { DEV_NONE, diff --git a/multipath/main.c b/multipath/main.c -index 28e3a055..346acb61 100644 +index f2adcdeb..31012874 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -843,11 +843,14 @@ main (int argc, char *argv[]) +@@ -834,11 +834,14 @@ main (int argc, char *argv[]) char *dev = NULL; struct config *conf; bool enable_foreign = false; @@ -76,7 +76,7 @@ index 28e3a055..346acb61 100644 if (init_config(DEFAULT_CONFIGFILE)) exit(RTVL_FAIL); if (atexit(uninit_config)) -@@ -1101,6 +1104,9 @@ main (int argc, char *argv[]) +@@ -1092,6 +1095,9 @@ main (int argc, char *argv[]) while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) condlog(3, "restart multipath configuration process"); @@ -99,7 +99,7 @@ index 2ac1972f..cc248231 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -index 7bc8806e..315884eb 100644 +index 8815e099..342e363e 100644 --- a/multipathd/multipathd.8.in +++ b/multipathd/multipathd.8.in @@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. @@ -112,10 +112,10 @@ index 7bc8806e..315884eb 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index b6a25b31..3d957733 100644 +index eb58943c..ab166435 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in -@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket multipathd-queueing.service @MODPROBE_UNIT@ After=systemd-udevd-kernel.socket @MODPROBE_UNIT@ After=multipathd.socket systemd-remount-fs.service Before=initrd-cleanup.service @@ -123,10 +123,10 @@ index b6a25b31..3d957733 100644 DefaultDependencies=no Conflicts=shutdown.target Conflicts=initrd-cleanup.service -diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket -index 6a62f5fd..263b6b0c 100644 ---- a/multipathd/multipathd.socket -+++ b/multipathd/multipathd.socket +diff --git a/multipathd/multipathd.socket.in b/multipathd/multipathd.socket.in +index 11002fce..5ed24757 100644 +--- a/multipathd/multipathd.socket.in ++++ b/multipathd/multipathd.socket.in @@ -1,6 +1,7 @@ [Unit] Description=multipathd control socket diff --git a/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch b/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch deleted file mode 100644 index 8da3ce7..0000000 --- a/0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 Feb 2025 13:11:03 -0500 -Subject: [PATCH] libmultipath: include urcu.h before urcu/atomic.h - -urcu/atomic.h requires some header files included by urcu.h. Make sure -to include it first. - -Fixes: https://github.com/opensvc/multipath-tools/issues/112 -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/checkers/tur.c | 1 + - libmultipath/lock.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c -index e70a2e11..0010acf8 100644 ---- a/libmultipath/checkers/tur.c -+++ b/libmultipath/checkers/tur.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - - #include "checkers.h" -diff --git a/libmultipath/lock.h b/libmultipath/lock.h -index 38473a8c..5f323055 100644 ---- a/libmultipath/lock.h -+++ b/libmultipath/lock.h -@@ -2,6 +2,7 @@ - #define LOCK_H_INCLUDED - - #include -+#include - #include - #include - diff --git a/0008-RH-Fix-nvme-function-missing-argument.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 84% rename from 0008-RH-Fix-nvme-function-missing-argument.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch index 74b7b53..33a8d5f 100644 --- a/0008-RH-Fix-nvme-function-missing-argument.patch +++ b/0004-RH-Fix-nvme-function-missing-argument.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 283b5dd645663a2cf16f2813581772d7a84db6ad Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Jan 2019 14:54:56 -0600 Subject: [PATCH] RH: Fix nvme function missing argument @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h -index e6c54453..0c6c9439 100644 +index b3caa7be..f91504c9 100644 --- a/libmultipath/nvme/argconfig.h +++ b/libmultipath/nvme/argconfig.h -@@ -76,7 +76,7 @@ struct argconfig_commandline_options { +@@ -63,7 +63,7 @@ struct argconfig_commandline_options { extern "C" { #endif diff --git a/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch b/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch deleted file mode 100644 index 8fc3211..0000000 --- a/0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Mon, 17 Feb 2025 12:05:03 -0800 -Subject: [PATCH] libmpathutils/uxsock.c: Include string.h for memcpy - -Fixes -uxsock.c:72:2: error: call to undeclared library function 'memcpy' with type 'void *(void *, const void *, unsigned long)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] - -Signed-off-by: Khem Raj -Cc: Benjamin Marzinski -Cc: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathutil/uxsock.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmpathutil/uxsock.c b/libmpathutil/uxsock.c -index 2135476d..a474874e 100644 ---- a/libmpathutil/uxsock.c -+++ b/libmpathutil/uxsock.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/0009-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch similarity index 85% rename from 0009-RH-use-rpm-optflags-if-present.patch rename to 0005-RH-use-rpm-optflags-if-present.patch index 1b96a3a..7a6f57f 100644 --- a/0009-RH-use-rpm-optflags-if-present.patch +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From bf46f8029998498045bb055415ba3ff515c79eaa Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 19 Apr 2017 06:10:01 -0500 Subject: [PATCH] RH: use rpm optflags if present @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index c225a1ed..7774f1f4 100644 +index ead89030..03aee175 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -99,28 +99,39 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo +@@ -102,17 +102,29 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ echo "modprobe@dm_multipath.service") @@ -50,8 +50,10 @@ index c225a1ed..7774f1f4 100644 -D_FILE_OFFSET_BITS=64 \ -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ - -DDEFAULT_CONFIGFILE=\"$(TGTDIR)$(configfile)\" -DSTATE_DIR=\"$(TGTDIR)$(statedir)\" \ - -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP +@@ -121,12 +133,11 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -DABSTRACT_SOCKET=\"$(abstract_socket)\" -DPATHNAME_SOCKET=\"$(pathname_socket)\" \ + -DWSTRINGOP_TRUNCATION=$(if $(WSTRINGOP_TRUNCATION),1,0) \ + -MMD -MP -CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -fexceptions +CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe diff --git a/0010-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 99% rename from 0010-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch index c587841..46f1126 100644 --- a/0010-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 29e5c6d6e2177e73d1be2ed2af66c1007487bf60 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 16 Oct 2014 15:49:01 -0500 Subject: [PATCH] RH: add mpathconf @@ -23,10 +23,10 @@ Signed-off-by: Benjamin Marzinski create mode 100644 multipath/mpathconf.8 diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index 7843c380..ab5259cf 100644 +index a5856bcc..5c9113ba 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt -@@ -127,9 +127,11 @@ Marzinski +@@ -131,9 +131,11 @@ Marzinski misdetection mpath mpathb @@ -38,7 +38,7 @@ index 7843c380..ab5259cf 100644 multipathc multipathd multipathed -@@ -147,6 +149,7 @@ ontap +@@ -154,6 +156,7 @@ ontap OOM opensvc OPTFLAGS diff --git a/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 92% rename from 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 612d876..cef8b56 100644 --- a/0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From d6ad888bad3850bb0a342ebcdc9fd78773eb3b2a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 17 Oct 2014 11:20:34 -0500 Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A @@ -20,10 +20,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 346acb61..adc50d69 100644 +index 31012874..a667c2ee 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -120,7 +120,7 @@ usage (char * progname) +@@ -111,7 +111,7 @@ usage (char * progname) fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); @@ -32,7 +32,7 @@ index 346acb61..adc50d69 100644 fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); fprintf (stderr, " %s [-h|-t|-T]\n", progname); -@@ -134,6 +134,8 @@ usage (char * progname) +@@ -125,6 +125,8 @@ usage (char * progname) " -f flush a multipath device map\n" " -F flush all multipath device maps\n" " -a add a device wwid to the wwids file\n" @@ -41,7 +41,7 @@ index 346acb61..adc50d69 100644 " -c check if a device should be a path in a multipath device\n" " -C check if a multipath device has usable paths\n" " -q allow queue_if_no_path when multipathd is not running\n" -@@ -449,6 +451,50 @@ static void cleanup_vecs(void) +@@ -440,6 +442,50 @@ static void cleanup_vecs(void) free_pathvec(vecs.pathvec, FREE_PATHS); } @@ -92,7 +92,7 @@ index 346acb61..adc50d69 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -860,7 +906,7 @@ main (int argc, char *argv[]) +@@ -851,7 +897,7 @@ main (int argc, char *argv[]) condlog(1, "failed to register cleanup handler for vecs: %m"); if (atexit(cleanup_bindings)) condlog(1, "failed to register cleanup handler for bindings: %m"); @@ -101,7 +101,7 @@ index 346acb61..adc50d69 100644 switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -931,6 +977,10 @@ main (int argc, char *argv[]) +@@ -922,6 +968,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -138,7 +138,7 @@ index b88e9a4c..edd742aa 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index 3d957733..7ef6e99e 100644 +index ab166435..1ec08c6e 100644 --- a/multipathd/multipathd.service.in +++ b/multipathd/multipathd.service.in @@ -19,6 +19,7 @@ StartLimitBurst=3 diff --git a/0012-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 87% rename from 0012-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch index 5789916..fdc90d4 100644 --- a/0012-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 064d761121e7e2c7b63ab280e341d8010a413119 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 7 Jun 2018 17:43:52 -0500 Subject: [PATCH] RH: reset default find_mutipaths value to off @@ -14,7 +14,7 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 02f7e57c..cd03fd1a 100644 +index 134b690a..e2fe7ac4 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h @@ -24,7 +24,7 @@ @@ -27,10 +27,10 @@ index 02f7e57c..cd03fd1a 100644 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index af9fbb96..0c1eff40 100644 +index ba291e11..b8389db3 100644 --- a/multipath/multipath.conf.5.in +++ b/multipath/multipath.conf.5.in -@@ -1226,7 +1226,7 @@ as non-multipath and passed on to upper layers. +@@ -1227,7 +1227,7 @@ as non-multipath and passed on to upper layers. \fBNote:\fR this may cause delays during device detection if there are single-path devices which aren\'t blacklisted. .TP diff --git a/0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 86% rename from 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 1f94eb3..8065e9f 100644 --- a/0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 335b8eb2773b07a602e84e14c1f3e289a9b25b5a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 11 Apr 2019 13:25:42 -0500 Subject: [PATCH] RH: attempt to get ANA info via sysfs first @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index e9827dca..80a32aa3 100644 +index 34527b22..4eaa3cc3 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c -@@ -24,6 +24,7 @@ +@@ -23,6 +23,7 @@ #include "prio.h" #include "util.h" #include "structs.h" @@ -24,7 +24,7 @@ index e9827dca..80a32aa3 100644 enum { ANA_ERR_GETCTRL_FAILED = 1, -@@ -36,6 +37,7 @@ enum { +@@ -35,6 +36,7 @@ enum { ANA_ERR_GETNS_FAILED, ANA_ERR_NO_MEMORY, ANA_ERR_NO_INFORMATION, @@ -32,7 +32,7 @@ index e9827dca..80a32aa3 100644 }; static const char *ana_errmsg[] = { -@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { +@@ -48,6 +50,7 @@ static const char *ana_errmsg[] = { [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", [ANA_ERR_NO_MEMORY] = "out of memory", [ANA_ERR_NO_INFORMATION] = "invalid fd", @@ -40,7 +40,7 @@ index e9827dca..80a32aa3 100644 }; static const char *anas_string[] = { -@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, +@@ -106,6 +109,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, return -ANA_ERR_GETANAS_NOTFOUND; } @@ -68,7 +68,7 @@ index e9827dca..80a32aa3 100644 static int get_ana_info(struct path * pp) { int rc; -@@ -209,8 +233,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) +@@ -208,8 +232,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) if (pp->fd < 0) rc = -ANA_ERR_NO_INFORMATION; diff --git a/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 91% rename from 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index 3243375..f7bca92 100644 --- a/0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 137c96d16b6bb03d8a52854e152db4ee36b7d9e4 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 25 Mar 2021 13:05:10 -0500 Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Marzinski 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index b5851561..a3cc6e83 100644 +index 31db8758..21cfcc73 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1219,13 +1219,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1225,13 +1225,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index b5851561..a3cc6e83 100644 good_len = 8; break; default: -@@ -1243,10 +1239,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1249,10 +1245,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ diff --git a/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 89% rename from 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch index 97fb4df..3fe7c25 100644 --- a/0015-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 374755791536be4870ab2e93ae36549cbaaeb800 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Mar 2022 18:12:06 -0500 Subject: [PATCH] RH: add scsi device handlers to modules-load.d @@ -11,7 +11,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 7774f1f4..0e836f0a 100644 +index 03aee175..936a622f 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -16,7 +16,7 @@ READLINE := diff --git a/0016-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch similarity index 89% rename from 0016-RH-compile-with-libreadline-support.patch rename to 0012-RH-compile-with-libreadline-support.patch index e7579b0..0964c42 100644 --- a/0016-RH-compile-with-libreadline-support.patch +++ b/0012-RH-compile-with-libreadline-support.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From cc15379130e8aa068e97c64afd46be212b456d4f Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 15 Nov 2022 18:03:33 -0600 Subject: [PATCH] RH: compile with libreadline support @@ -12,7 +12,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc -index 0e836f0a..e1d3fcd1 100644 +index 936a622f..f475f70f 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -12,7 +12,7 @@ diff --git a/0017-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch similarity index 98% rename from 0017-RH-Add-mpathcleanup.patch rename to 0013-RH-Add-mpathcleanup.patch index bd2dcd6..d1a8e84 100644 --- a/0017-RH-Add-mpathcleanup.patch +++ b/0013-RH-Add-mpathcleanup.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 2ef5bd86052ba0b22f4d3a16e69cdf268d90a53a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 7 Jul 2023 15:25:59 -0500 Subject: [PATCH] RH: Add mpathcleanup diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 232daba..24b00bd 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath -Version: 0.11.1 -Release: 2%{?dist} +Version: 0.13.0 +Release: 1%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -8,26 +8,22 @@ URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl -L https://github.com/opensvc/multipath-tools/archive/0.11.1.tar.gz -o multipath-tools-0.11.1.tgz -Source0: multipath-tools-0.11.1.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.13.0.tar.gz -o multipath-tools-0.13.0.tgz +Source0: multipath-tools-0.13.0.tgz Source1: multipath.conf -Patch0001: 0001-multipathd-trigger-uevents-for-blacklisted-paths-in-.patch -Patch0002: 0002-multipath-tools-fix-compilation-with-latest-userspac.patch -Patch0003: 0003-libmultipath-include-urcu.h-before-urcu-atomic.h.patch -Patch0004: 0004-libmpathutils-uxsock.c-Include-string.h-for-memcpy.patch -Patch0005: 0005-RH-fixup-udev-rules-for-redhat.patch -Patch0006: 0006-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0007: 0007-RH-don-t-start-without-a-config-file.patch -Patch0008: 0008-RH-Fix-nvme-function-missing-argument.patch -Patch0009: 0009-RH-use-rpm-optflags-if-present.patch -Patch0010: 0010-RH-add-mpathconf.patch -Patch0011: 0011-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0012: 0012-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0013: 0013-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0014: 0014-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0015: 0015-RH-add-scsi-device-handlers-to-modules-load.d.patch -Patch0016: 0016-RH-compile-with-libreadline-support.patch -Patch0017: 0017-RH-Add-mpathcleanup.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0013: 0013-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -115,7 +111,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.11.1 -p1 +%autosetup -n multipath-tools-0.13.0 -p1 cp %{SOURCE1} . %build @@ -167,6 +163,7 @@ fi %{_sbindir}/mpathcleanup %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service +%{_unitdir}/multipathd-queueing.service %{_unitdir}/multipathd.socket %{_mandir}/man5/multipath.conf.5* %{_mandir}/man8/multipath.8* @@ -237,6 +234,13 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 4 2025 Benjamin Marzinski - 0.13.0-1 +- Update source to upstream release 0.13.0 + * Previous patches 0001-0004 are included in the tarball +- Install /lib/systemd/system/multipathd-queueing.service +- Rename redhat patches + * Previous patches 0005-0017 are now patches 0001-0013 + * Wed Jul 23 2025 Fedora Release Engineering - 0.11.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index 5eea94e..233c4ea 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.11.1.tgz) = ac6bacd725bc831a140b75a72c81296eb1ed4080fb6350caf6178914d1bdce743705f3bd4e31f318068f6272dc98e12d63ee38228a3521a3d1c7bc8eb30812f9 +SHA512 (multipath-tools-0.13.0.tgz) = 75c84524ee27590b8b751ea500898a44e5ac3d58d55be6bcab919d0d423049db3a4466fcb9135705cf63ba074416973bb651255063269e9f682f11d21ba57e59 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 From d6f2be9e59baa23b2d610a68d3635da3d5b6b991 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 13 Nov 2025 19:23:18 -0500 Subject: [PATCH 33/33] device-mapper-multipath-0.13.0-2 Move STI tests to TMT --- {tests/.fmf => .fmf}/version | 0 device-mapper-multipath.spec | 5 +++- plans/multipath.fmf | 58 ++++++++++++++++++++++++++++++++++++ tests/provision.fmf | 5 ---- tests/tests.yml | 44 --------------------------- 5 files changed, 62 insertions(+), 50 deletions(-) rename {tests/.fmf => .fmf}/version (100%) create mode 100644 plans/multipath.fmf delete mode 100644 tests/provision.fmf delete mode 100644 tests/tests.yml diff --git a/tests/.fmf/version b/.fmf/version similarity index 100% rename from tests/.fmf/version rename to .fmf/version diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 24b00bd..5d80d4e 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.13.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper # readline uses GPL-3.0-only License: GPL-2.0-only AND GPL-3.0-only @@ -234,6 +234,9 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Nov 13 2025 Benjamin Marzinski - 0.13.0-2 +- Move STI tests to TMT + * Tue Nov 4 2025 Benjamin Marzinski - 0.13.0-1 - Update source to upstream release 0.13.0 * Previous patches 0001-0004 are included in the tarball diff --git a/plans/multipath.fmf b/plans/multipath.fmf new file mode 100644 index 0000000..876c77a --- /dev/null +++ b/plans/multipath.fmf @@ -0,0 +1,58 @@ +summary: basic functionality tests + +provision: + hardware: + memory: ">= 2 GB" + +prepare: + how: install + package: + - device-mapper-multipath + - perl + +discover: + how: shell + tests: + - name: medium_error_scsi_debug + path: /tests/medium_error_scsi_debug + test: ./main.sh + duration: 15m + - name: squelch_scsi_id + path: /tests/squelch_scsi_id + test: ./main.sh + duration: 15m + - name: multipathd_oom + path: /tests/multipathd_oom + test: ./main.sh + duration: 15m + - name: user_friendly_names + path: /tests/user_friendly_names + test: ./main.sh + duration: 15m + - name: kpartx_4k_aligned + path: /tests/kpartx_4k_aligned + test: ./main.sh + duration: 15m + - name: bindings + path: /tests/bindings + test: ./main.sh + duration: 15m + - name: restate_module + path: /tests/restate_module + test: ./main.sh + duration: 15m + - name: find_multipaths + path: /tests/find_multipaths + test: ./main.sh + duration: 15m + - name: multipath_conf_syntax + path: /tests/multipath_conf_syntax + test: ./main.sh + duration: 15m + - name: alias_clash + path: /tests/alias_clash + test: ./main.sh + duration: 15m + +execute: + how: tmt diff --git a/tests/provision.fmf b/tests/provision.fmf deleted file mode 100644 index 62a6eba..0000000 --- a/tests/provision.fmf +++ /dev/null @@ -1,5 +0,0 @@ ---- - -standard-inventory-qcow2: - qemu: - m: 2G diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 15f26d2..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,44 +0,0 @@ ---- -# No tests suitable for atomic environment -# No tests suitable for container environment - -# Tests suitable for classic environment -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - tests: - - medium_error_scsi_debug: - run: ./main.sh - timeout: 15m - - squelch_scsi_id: - run: ./main.sh - timeout: 15m - - multipathd_oom: - run: ./main.sh - timeout: 15m - - user_friendly_names: - run: ./main.sh - timeout: 15m - - kpartx_4k_aligned: - run: ./main.sh - timeout: 15m - - bindings: - run: ./main.sh - timeout: 15m - - restate_module: - run: ./main.sh - timeout: 15m - - find_multipaths: - run: ./main.sh - timeout: 15m - - multipath_conf_syntax: - run: ./main.sh - timeout: 15m - - alias_clash: - run: ./main.sh - timeout: 15m - required_packages: - - device-mapper-multipath - - perl