diff --git a/.gitignore b/.gitignore index c297b30..7a13460 100644 --- a/.gitignore +++ b/.gitignore @@ -25,13 +25,3 @@ 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 -/multipath-tools-0.9.4.tgz -/multipath-tools-0.9.5.tgz -/multipath-tools-0.9.6.tgz -/multipath-tools-0.9.7.tgz -/multipath-tools-0.9.8.tgz -/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/0001-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index ed5b7e9..0000000 --- a/0001-RH-fixup-udev-rules-for-redhat.patch +++ /dev/null @@ -1,63 +0,0 @@ -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 - -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.in | 2 +- - multipath/Makefile | 4 ++-- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 9e3dc466..ead89030 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -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 := $(if $(prefix),$(prefix),/usr) - # Prefix for configuration files (multipath.conf) -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+="@BINDIR@/kpartx -un -p -part /dev/$name" -+RUN+="@BINDIR@/kpartx -un /dev/$name" - - LABEL="kpartx_end" -diff --git a/multipath/Makefile b/multipath/Makefile -index 67fb5e62..2ea9e528 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -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 -@@ -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 -+ $(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/0001-github-workflows-switch-to-fedora-36.patch b/0001-github-workflows-switch-to-fedora-36.patch new file mode 100644 index 0000000..1583fd8 --- /dev/null +++ b/0001-github-workflows-switch-to-fedora-36.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 10 Jun 2022 22:44:11 +0200 +Subject: [PATCH] github workflows: switch to fedora 36 + +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index 19c9e297..ddfd4a09 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -12,12 +12,10 @@ jobs: + runs-on: ubuntu-20.04 + strategy: + matrix: +- os: [buster, jessie, bullseye, fedora-35] ++ os: [buster, jessie, bullseye, fedora-36] + arch: ['', '-i386'] + exclude: +- - os: fedora-34 +- arch: '-i386' +- - os: fedora-35 ++ - os: fedora-36 + arch: '-i386' + container: mwilck/multipath-build-${{ matrix.os }}${{ matrix.arch }} + steps: diff --git a/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch b/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch new file mode 100644 index 0000000..c54b4cd --- /dev/null +++ b/0002-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: chengjike +Date: Fri, 8 Oct 2021 20:24:49 +0800 +Subject: [PATCH] multipath-tools: fix "multipath -ll" bug for Native NVME + Multipath devices + +After "Native NVME Multipath" is configured, +the content displayed is incorrect when you run "multipath -ll" command. +Each NVME devices have the same path name. For example: + +[root@localhost home]# multipath -ll +eui.710032e8fb22a86c24a52c1000000db8 [nvme]:nvme1n1 NVMe,Huawei-XSG1,1000001 +size=10485760 features='n/a' hwhandler='ANA' wp=rw +|-+- policy='n/a' prio=50 status=optimized +| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live +`-+- policy='n/a' prio=50 status=optimized + `- 1:9:1 nvme1c9n1 0:0 n/a optimized live +eui.710032e8fb22a86b24a52c7c00000db7 [nvme]:nvme1n2 NVMe,Huawei-XSG1,1000001 +size=10485760 features='n/a' hwhandler='ANA' wp=rw +|-+- policy='n/a' prio=50 status=optimized +| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live +`-+- policy='n/a' prio=50 status=optimized + `- 1:9:1 nvme1c9n1 0:0 n/a optimized live +[root@localhost home]# + +The logical paths of "nvme1n1" and "nvme1n2" are both "nvme1c4n1" and "nvme1c9n1". +So when multipath-tools aggregates disks, use "nvme_ns_head->instance" for matching. +such as ,Use "b" in "nvmeanb" string to match "z" in "nvmexcynz"(a,b,x,y,z can be any number), +and if "b" and "z" are the same, they are related. + +Signed-off-by: chengjike +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/foreign/nvme.c | 26 ++++++++++++++++++++------ + 1 file changed, 20 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c +index 52ca56d8..9a05b333 100644 +--- a/libmultipath/foreign/nvme.c ++++ b/libmultipath/foreign/nvme.c +@@ -531,14 +531,18 @@ static int _dirent_controller(const struct dirent *di) + + /* Find the block device for a given nvme controller */ + struct udev_device *get_ctrl_blkdev(const struct context *ctx, +- struct udev_device *ctrl) ++ struct udev_device *ctrl, const char *ctrl_name) + { ++ int ctrl_num, ns_num; + struct udev_list_entry *item; + struct udev_device *blkdev = NULL; + struct udev_enumerate *enm = udev_enumerate_new(ctx->udev); + const char *devtype; + +- if (enm == NULL) ++ if (enm == NULL || ctrl_name == NULL) ++ return NULL; ++ ++ if (sscanf(ctrl_name, "nvme%dn%d", &ctrl_num, &ns_num) != 2) + return NULL; + + pthread_cleanup_push(_udev_enumerate_unref, enm); +@@ -556,6 +560,8 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, + item != NULL; + item = udev_list_entry_get_next(item)) { + struct udev_device *tmp; ++ const char *name = NULL ; ++ int m, n, l; + + tmp = udev_device_new_from_syspath(ctx->udev, + udev_list_entry_get_name(item)); +@@ -563,11 +569,19 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, + continue; + + devtype = udev_device_get_devtype(tmp); +- if (devtype && !strcmp(devtype, "disk")) { ++ if (devtype == NULL || strcmp(devtype, "disk")) { ++ udev_device_unref(tmp); ++ continue; ++ } ++ ++ name = udev_device_get_sysname(tmp); ++ if (name != NULL && ++ sscanf(name, "nvme%dc%dn%d", &m, &n, &l) == 3 && ++ l == ns_num) { + blkdev = tmp; + break; +- } else +- udev_device_unref(tmp); ++ } ++ udev_device_unref(tmp); + } + + if (blkdev == NULL) +@@ -680,7 +694,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) + } + + pthread_cleanup_push(_udev_device_unref, ctrl); +- udev = get_ctrl_blkdev(ctx, ctrl); ++ udev = get_ctrl_blkdev(ctx, ctrl, udev_device_get_sysname(map->udev)); + /* + * We give up the reference to the nvme device here and get + * it back from the child below. diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch deleted file mode 100644 index 05d4e7a..0000000 --- a/0003-RH-don-t-start-without-a-config-file.patch +++ /dev/null @@ -1,137 +0,0 @@ -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 - -If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist -all devices when running multipath. A completely blank configuration file -is almost never what users want. Also, people may have the multipath -packages installed but don't want to use them. This patch provides a -simple way to disable multipath. Simply removing or renaming -/etc/multipath.conf will keep multipath from doing anything. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 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.in | 1 + - 7 files changed, 25 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 8b424d18..b8317f4d 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -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); -+ } else { -+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); -+ if (conf->blist_devnode == NULL) { -+ conf->blist_devnode = vector_alloc(); -+ if (!conf->blist_devnode) { -+ condlog(0, "cannot allocate blacklist\n"); -+ goto out; -+ } -+ } -+ if (store_ble(conf->blist_devnode, ".*", ORIGIN_NO_CONFIG)) { -+ condlog(0, "cannot store default no-config blacklist\n"); -+ goto out; -+ } - } - - conf->processed_main_config = 1; -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 5b4ebf8c..2302eacc 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -10,6 +10,7 @@ - - #define ORIGIN_DEFAULT 0 - #define ORIGIN_CONFIG 1 -+#define ORIGIN_NO_CONFIG 2 - - enum devtypes { - DEV_NONE, -diff --git a/multipath/main.c b/multipath/main.c -index f2adcdeb..31012874 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -834,11 +834,14 @@ main (int argc, char *argv[]) - char *dev = NULL; - struct config *conf; - 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)) -@@ -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"); - -+ 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 2ac1972f..cc248231 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" - ENV{multipath}=="off", GOTO="end_mpath" -+TEST!="/etc/multipath.conf", GOTO="end_mpath" - - ENV{DEVTYPE}!="partition", GOTO="test_dev" - IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" -diff --git a/multipathd/multipathd.8.in b/multipathd/multipathd.8.in -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. - 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/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index eb58943c..ab166435 100644 ---- a/multipathd/multipathd.service.in -+++ b/multipathd/multipathd.service.in -@@ -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 -+ConditionPathExists=/etc/multipath.conf - DefaultDependencies=no - Conflicts=shutdown.target - Conflicts=initrd-cleanup.service -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 - DefaultDependencies=no -+ConditionPathExists=/etc/multipath.conf - ConditionKernelCommandLine=!nompath - ConditionKernelCommandLine=!multipath=off - ConditionVirtualization=!container diff --git a/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch new file mode 100644 index 0000000..9643721 --- /dev/null +++ b/0003-multipath-tools-update-Huawei-OceanStor-NVMe-vendor-.patch @@ -0,0 +1,40 @@ +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-update-Generic-NVMe-vendor-regex-in-.patch b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch new file mode 100644 index 0000000..4ef193d --- /dev/null +++ b/0004-multipath-tools-update-Generic-NVMe-vendor-regex-in-.patch @@ -0,0 +1,33 @@ +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-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch deleted file mode 100644 index 7a6f57f..0000000 --- a/0005-RH-use-rpm-optflags-if-present.patch +++ /dev/null @@ -1,67 +0,0 @@ -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 - -Use the passed in optflags when compiling as an RPM, and keep the -default flags as close as possible to the current fedora flags, while -still being generic. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 25 ++++++++++++++++++------- - 1 file changed, 18 insertions(+), 7 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index ead89030..03aee175 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -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") - --OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -+ifndef RPM_OPT_FLAGS -+ 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 -+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) -+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -+ endif -+else -+ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 -+endif - - # 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) \ -+CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ - -D_FILE_OFFSET_BITS=64 \ - -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ - -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ -@@ -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 - 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 - - # Source code directories. Don't modify. diff --git a/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch b/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch new file mode 100644 index 0000000..c2abfaa --- /dev/null +++ b/0005-libmultipath-fix-find_multipaths_timeout-for-unknown.patch @@ -0,0 +1,29 @@ +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/0006-multipath-tools-update-devel-repo-info-in-README.md.patch b/0006-multipath-tools-update-devel-repo-info-in-README.md.patch new file mode 100644 index 0000000..3eaf2c0 --- /dev/null +++ b/0006-multipath-tools-update-devel-repo-info-in-README.md.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 14 Jul 2022 21:05:39 +0200 +Subject: [PATCH] multipath-tools: update devel repo info in README.md + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/README.md b/README.md +index f06f8cea..dcf51f20 100644 +--- a/README.md ++++ b/README.md +@@ -3,7 +3,6 @@ + multipath-tools for Linux + ========================= + +- + https://github.com/opensvc/multipath-tools + + This package provides the following binaries to drive the Device Mapper multipathing driver: +@@ -42,14 +41,12 @@ Go to: https://github.com/opensvc/multipath-tools/tags + Select a release-tag and then click on "zip" or "tar.gz". + + +-Source code +-=========== ++Devel code ++========== + + To get latest devel code: + +- git clone https://github.com/opensvc/multipath-tools.git +- +-Github page: https://github.com/opensvc/multipath-tools ++ git clone -b queue https://github.com/openSUSE/multipath-tools + + + Building multipath-tools +@@ -149,4 +146,3 @@ The multipath-tools source code is covered by several different licences. + Refer to the individual source files for details. + Source files which do not specify a licence are shipped under LGPL-2.0 + (see `LICENSES/LGPL-2.0`). +- diff --git a/0007-multipath-tools-delete-README.alua.patch b/0007-multipath-tools-delete-README.alua.patch new file mode 100644 index 0000000..8682745 --- /dev/null +++ b/0007-multipath-tools-delete-README.alua.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 14 Jul 2022 21:05:40 +0200 +Subject: [PATCH] multipath-tools: delete README.alua + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.alua | 24 ------------------------ + 1 file changed, 24 deletions(-) + delete mode 100644 README.alua + +diff --git a/README.alua b/README.alua +deleted file mode 100644 +index 5d2b1c64..00000000 +--- a/README.alua ++++ /dev/null +@@ -1,24 +0,0 @@ +-This is a rough guide, consult your storage device manufacturer documentation. +- +-ALUA is supported in some devices, but usually it's disabled by default. +-To enable ALUA, the following options should be changed: +- +-- EMC CLARiiON/VNX: +- "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" +- +-- HPE 3PAR, Primera, and Alletra 9000: +- "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". +- +-- Promise VTrak/Vess: +- "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" +- must be "Active-Active". +- +-- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: +- "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". +- +-- NetApp ONTAP: +- To check ALUA state: "igroup show -v ", and to enable ALUA: +- "igroup set alua yes". +- +-- Huawei OceanStor: +- "Host Access Mode" should be changed to "Asymmetric". diff --git a/0008-multipath-tools-add-ALUA-info-to-README.md.patch b/0008-multipath-tools-add-ALUA-info-to-README.md.patch new file mode 100644 index 0000000..2a11fce --- /dev/null +++ b/0008-multipath-tools-add-ALUA-info-to-README.md.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 14 Jul 2022 23:14:31 +0200 +Subject: [PATCH] multipath-tools: add ALUA info to README.md + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/README.md b/README.md +index dcf51f20..2322082c 100644 +--- a/README.md ++++ b/README.md +@@ -146,3 +146,31 @@ The multipath-tools source code is covered by several different licences. + Refer to the individual source files for details. + Source files which do not specify a licence are shipped under LGPL-2.0 + (see `LICENSES/LGPL-2.0`). ++ ++ ++ALUA ++==== ++This is a rough guide, consult your storage device manufacturer documentation. ++ ++ALUA is supported in some devices, but usually it's disabled by default. ++To enable ALUA, the following options should be changed: ++ ++- EMC CLARiiON/VNX: ++ "Failover Mode" should be changed to "4" or "Active-Active mode(ALUA)-failover mode 4" ++ ++- HPE 3PAR, Primera, and Alletra 9000: ++ "Host:" should be changed to "Generic-ALUA Persona 2 (UARepLun, SESLun, ALUA)". ++ ++- Promise VTrak/Vess: ++ "LUN Affinity" and "ALUA" should be changed to "Enable", "Redundancy Type" ++ must be "Active-Active". ++ ++- LSI/Engenio/NetApp RDAC class, as NetApp SANtricity E/EF Series and OEM arrays: ++ "Select operating system:" should be changed to "Linux DM-MP (Kernel 3.10 or later)". ++ ++- NetApp ONTAP: ++ To check ALUA state: "igroup show -v ", and to enable ALUA: ++ "igroup set alua yes". ++ ++- Huawei OceanStor: ++ "Host Access Mode" should be changed to "Asymmetric". diff --git a/0009-libmultipath-alua-remove-get_sysfs_pg83.patch b/0009-libmultipath-alua-remove-get_sysfs_pg83.patch new file mode 100644 index 0000000..4aa92fc --- /dev/null +++ b/0009-libmultipath-alua-remove-get_sysfs_pg83.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Jul 2022 15:57:21 +0200 +Subject: [PATCH] libmultipath: alua: remove get_sysfs_pg83() + +Since b72e753 ("libmultipath: alua: try to retrieve inquiry data from sysfs"), +we fetch inquiry and VPD data from sysfs anyway. No need to do this twice. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/alua_rtpg.c | 57 ++++++++------------------- + 1 file changed, 16 insertions(+), 41 deletions(-) + +diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c +index 3f9c0e73..4db13c20 100644 +--- a/libmultipath/prioritizers/alua_rtpg.c ++++ b/libmultipath/prioritizers/alua_rtpg.c +@@ -228,25 +228,6 @@ get_target_port_group_support(const struct path *pp, unsigned int timeout) + return rc; + } + +-static int +-get_sysfs_pg83(const struct path *pp, unsigned char *buff, int buflen) +-{ +- struct udev_device *parent = pp->udev; +- +- while (parent) { +- const char *subsys = udev_device_get_subsystem(parent); +- if (subsys && !strncmp(subsys, "scsi", 4)) +- break; +- parent = udev_device_get_parent(parent); +- } +- +- if (!parent || sysfs_get_vpd(parent, 0x83, buff, buflen) <= 0) { +- PRINT_DEBUG("failed to read sysfs vpd pg83"); +- return -1; +- } +- return 0; +-} +- + int + get_target_port_group(const struct path * pp, unsigned int timeout) + { +@@ -265,32 +246,26 @@ get_target_port_group(const struct path * pp, unsigned int timeout) + } + + memset(buf, 0, buflen); ++ rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); ++ if (rc < 0) ++ goto out; + +- rc = get_sysfs_pg83(pp, buf, buflen); +- +- if (rc < 0) { ++ scsi_buflen = get_unaligned_be16(&buf[2]) + 4; ++ if (scsi_buflen >= USHRT_MAX) ++ scsi_buflen = USHRT_MAX; ++ if (buflen < scsi_buflen) { ++ free(buf); ++ buf = (unsigned char *)malloc(scsi_buflen); ++ if (!buf) { ++ PRINT_DEBUG("malloc failed: could not allocate" ++ "%u bytes", scsi_buflen); ++ return -RTPG_RTPG_FAILED; ++ } ++ buflen = scsi_buflen; ++ memset(buf, 0, buflen); + rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); + if (rc < 0) + goto out; +- +- scsi_buflen = get_unaligned_be16(&buf[2]) + 4; +- /* Paranoia */ +- if (scsi_buflen >= USHRT_MAX) +- scsi_buflen = USHRT_MAX; +- if (buflen < scsi_buflen) { +- free(buf); +- buf = (unsigned char *)malloc(scsi_buflen); +- if (!buf) { +- PRINT_DEBUG("malloc failed: could not allocate" +- "%u bytes", scsi_buflen); +- return -RTPG_RTPG_FAILED; +- } +- buflen = scsi_buflen; +- memset(buf, 0, buflen); +- rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); +- if (rc < 0) +- goto out; +- } + } + + vpd83 = (struct vpd83_data *) buf; diff --git a/0010-libmultipath-remove-sysfs_get_binary.patch b/0010-libmultipath-remove-sysfs_get_binary.patch new file mode 100644 index 0000000..c2661ed --- /dev/null +++ b/0010-libmultipath-remove-sysfs_get_binary.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 10:54:02 +0200 +Subject: [PATCH] libmultipath: remove sysfs_get_binary() + +This function adds no value on top of sysfs_bin_attr_get_value(). +Remove it. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 26 ++------------------------ + tests/test-lib.c | 1 - + 2 files changed, 2 insertions(+), 25 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 0d8a558c..7e09e4e2 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -263,41 +263,19 @@ declare_sysfs_get_str(vendor); + declare_sysfs_get_str(model); + declare_sysfs_get_str(rev); + +-static ssize_t +-sysfs_get_binary (struct udev_device * udev, const char *attrname, +- unsigned char *buff, size_t len) +-{ +- ssize_t attr_len; +- const char * devname; +- +- if (!udev) { +- condlog(3, "No udev device given\n"); +- return -ENOSYS; +- } +- +- devname = udev_device_get_sysname(udev); +- attr_len = sysfs_bin_attr_get_value(udev, attrname, buff, len); +- if (attr_len < 0) { +- condlog(3, "%s: attribute %s not found in sysfs", +- devname, attrname); +- return attr_len; +- } +- return attr_len; +-} +- + ssize_t sysfs_get_vpd(struct udev_device * udev, unsigned char pg, + unsigned char *buff, size_t len) + { + char attrname[9]; + + snprintf(attrname, sizeof(attrname), "vpd_pg%02x", pg); +- return sysfs_get_binary(udev, attrname, buff, len); ++ return sysfs_bin_attr_get_value(udev, attrname, buff, len); + } + + ssize_t sysfs_get_inquiry(struct udev_device * udev, + unsigned char *buff, size_t len) + { +- return sysfs_get_binary(udev, "inquiry", buff, len); ++ return sysfs_bin_attr_get_value(udev, "inquiry", buff, len); + } + + int +diff --git a/tests/test-lib.c b/tests/test-lib.c +index 6dd3ee88..0bc49d53 100644 +--- a/tests/test-lib.c ++++ b/tests/test-lib.c +@@ -334,7 +334,6 @@ void mock_pathinfo(int mask, const struct mocked_path *mp) + if (mask & DI_SERIAL) { + will_return(__wrap_udev_device_get_subsystem, "scsi"); + will_return(__wrap_udev_device_get_sysname, hbtl); +- will_return(__wrap_udev_device_get_sysname, hbtl); + } + + if (mask & DI_WWID) { diff --git a/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch b/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch new file mode 100644 index 0000000..787d230 --- /dev/null +++ b/0011-libmultipath-sysfs_bin_attr_get_value-no-error-if-bu.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 10:47:51 +0200 +Subject: [PATCH] libmultipath: sysfs_bin_attr_get_value(): no error if buffer + is filled + +sysfs_bin_attr_get_value() sets the length of bytes read to 0 +when the provided buffer was too small, truncating potentially +useful data. This is harmful e.g. in do_inquiry(), if the "inquiry" +sysfs attribute contains more than 96 bytes (which is possible). + +Actually, binary attributes don't need to be 0-terminated. Thus, +unlike for string attributes, it's not an error if the requested number of +bytes is exactly equal to the number of bytes read. We expect that +the caller knows how many bytes it needs to read. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 10 ++++++---- + libmultipath/sysfs.c | 5 +---- + 2 files changed, 7 insertions(+), 8 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 7e09e4e2..f5b8401c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1341,13 +1341,15 @@ static int + get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) + { + int len; +- size_t buff_len; ++ ssize_t buff_len; + unsigned char buff[VPD_BUFLEN]; + + memset(buff, 0x0, VPD_BUFLEN); +- if (!parent || sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN) <= 0) { +- condlog(3, "failed to read sysfs vpd pg%02x", pg); +- return -EINVAL; ++ buff_len = sysfs_get_vpd(parent, pg, buff, VPD_BUFLEN); ++ if (buff_len < 0) { ++ condlog(3, "failed to read sysfs vpd pg%02x: %s", ++ pg, strerror(-buff_len)); ++ return buff_len; + } + + if (buff[1] != pg) { +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index f45dbee1..3ec92512 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -146,10 +146,7 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + if (size < 0) { + condlog(4, "read from %s failed: %s", devpath, strerror(errno)); + size = -errno; +- } else if (size == (ssize_t)value_len) { +- condlog(4, "overflow while reading from %s", devpath); +- size = 0; +- } ++ }; + + close(fd); + return size; diff --git a/0012-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch deleted file mode 100644 index 0964c42..0000000 --- a/0012-RH-compile-with-libreadline-support.patch +++ /dev/null @@ -1,26 +0,0 @@ -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 - -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 936a622f..f475f70f 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/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch b/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch new file mode 100644 index 0000000..d09cd8a --- /dev/null +++ b/0012-libmultipath-common-code-path-for-sysfs_attr_get_val.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 11:14:30 +0200 +Subject: [PATCH] libmultipath: common code path for sysfs_attr_get_value() + +The code for sysfs_attr_get_value and sysfs_bin_attr_get_value() was +almost identical. Use a common code path. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 70 +++++++++++--------------------------------- + 1 file changed, 17 insertions(+), 53 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 3ec92512..4db911cc 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -44,8 +44,8 @@ + * as libudev lacks the capability to update an attribute value. + * So for modified attributes we need to implement our own function. + */ +-ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, +- char * value, size_t value_len) ++static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, ++ char *value, size_t value_len, bool binary) + { + char devpath[PATH_SIZE]; + struct stat statbuf; +@@ -87,12 +87,14 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + if (size < 0) { + condlog(4, "read from %s failed: %s", devpath, strerror(errno)); + size = -errno; +- value[0] = '\0'; +- } else if (size == (ssize_t)value_len) { ++ if (!binary) ++ value[0] = '\0'; ++ } else if (!binary && size == (ssize_t)value_len) { ++ condlog(3, "%s: overflow reading from %s (required len: %zu)", ++ __func__, devpath, size); + value[size - 1] = '\0'; +- condlog(4, "overflow while reading from %s", devpath); + size = 0; +- } else { ++ } else if (!binary) { + value[size] = '\0'; + size = strchop(value); + } +@@ -101,55 +103,17 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + return size; + } + +-ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, +- unsigned char * value, size_t value_len) ++ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, ++ char *value, size_t value_len) + { +- char devpath[PATH_SIZE]; +- struct stat statbuf; +- int fd; +- ssize_t size = -1; +- +- if (!dev || !attr_name || !value) +- return 0; +- +- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), +- attr_name); +- condlog(4, "open '%s'", devpath); +- /* read attribute value */ +- fd = open(devpath, O_RDONLY); +- if (fd < 0) { +- condlog(4, "attribute '%s' can not be opened: %s", +- devpath, strerror(errno)); +- return -errno; +- } +- if (fstat(fd, &statbuf) != 0) { +- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); +- close(fd); +- return -ENXIO; +- } +- +- /* skip directories */ +- if (S_ISDIR(statbuf.st_mode)) { +- condlog(4, "%s is a directory", devpath); +- close(fd); +- return -EISDIR; +- } +- +- /* skip non-writeable files */ +- if ((statbuf.st_mode & S_IRUSR) == 0) { +- condlog(4, "%s is not readable", devpath); +- close(fd); +- return -EPERM; +- } +- +- size = read(fd, value, value_len); +- if (size < 0) { +- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); +- size = -errno; +- }; ++ return __sysfs_attr_get_value(dev, attr_name, value, value_len, false); ++} + +- close(fd); +- return size; ++ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, ++ unsigned char *value, size_t value_len) ++{ ++ return __sysfs_attr_get_value(dev, attr_name, (char *)value, ++ value_len, true); + } + + ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, diff --git a/0013-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch deleted file mode 100644 index d1a8e84..0000000 --- a/0013-RH-Add-mpathcleanup.patch +++ /dev/null @@ -1,186 +0,0 @@ -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 - -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 3dc241cc..47e82234 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 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 -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/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch b/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch new file mode 100644 index 0000000..9dc3dc5 --- /dev/null +++ b/0013-libmultipath-sanitize-error-checking-in-sysfs-access.patch @@ -0,0 +1,165 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 11:41:40 +0200 +Subject: [PATCH] libmultipath: sanitize error checking in sysfs accessors + +udev_device_get_syspath() may return NULL; check for it, and check +for pathname overflow. Disallow a zero buffer length. The fstat() +calls were superfluous, as a read() or write() on the fd would +return the respective error codes depending on file type or permissions, +the extra system call and code complexity adds no value. + +Log levels should be moderate in sysfs.c, because it depends +on the caller whether errors getting/setting certain attributes are +fatal. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 94 ++++++++++++++++++-------------------------- + 1 file changed, 39 insertions(+), 55 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 4db911cc..1f0f2074 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -47,46 +47,38 @@ + static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + char *value, size_t value_len, bool binary) + { ++ const char *syspath; + char devpath[PATH_SIZE]; +- struct stat statbuf; + int fd; + ssize_t size = -1; + +- if (!dev || !attr_name || !value) +- return 0; ++ if (!dev || !attr_name || !value || !value_len) { ++ condlog(1, "%s: invalid parameters", __func__); ++ return -EINVAL; ++ } + +- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), +- attr_name); ++ syspath = udev_device_get_syspath(dev); ++ if (!syspath) { ++ condlog(3, "%s: invalid udevice", __func__); ++ return -EINVAL; ++ } ++ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { ++ condlog(3, "%s: devpath overflow", __func__); ++ return -EOVERFLOW; ++ } + condlog(4, "open '%s'", devpath); + /* read attribute value */ + fd = open(devpath, O_RDONLY); + if (fd < 0) { +- condlog(4, "attribute '%s' can not be opened: %s", +- devpath, strerror(errno)); ++ condlog(3, "%s: attribute '%s' can not be opened: %s", ++ __func__, devpath, strerror(errno)); + return -errno; + } +- if (fstat(fd, &statbuf) < 0) { +- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); +- close(fd); +- return -ENXIO; +- } +- /* skip directories */ +- if (S_ISDIR(statbuf.st_mode)) { +- condlog(4, "%s is a directory", devpath); +- close(fd); +- return -EISDIR; +- } +- /* skip non-writeable files */ +- if ((statbuf.st_mode & S_IRUSR) == 0) { +- condlog(4, "%s is not readable", devpath); +- close(fd); +- return -EPERM; +- } +- + size = read(fd, value, value_len); + if (size < 0) { +- condlog(4, "read from %s failed: %s", devpath, strerror(errno)); + size = -errno; ++ condlog(3, "%s: read from %s failed: %s", __func__, devpath, ++ strerror(errno)); + if (!binary) + value[0] = '\0'; + } else if (!binary && size == (ssize_t)value_len) { +@@ -119,51 +111,43 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + const char * value, size_t value_len) + { ++ const char *syspath; + char devpath[PATH_SIZE]; +- struct stat statbuf; + int fd; + ssize_t size = -1; + +- if (!dev || !attr_name || !value || !value_len) +- return 0; ++ if (!dev || !attr_name || !value || !value_len) { ++ condlog(1, "%s: invalid parameters", __func__); ++ return -EINVAL; ++ } ++ ++ syspath = udev_device_get_syspath(dev); ++ if (!syspath) { ++ condlog(3, "%s: invalid udevice", __func__); ++ return -EINVAL; ++ } ++ if (safe_sprintf(devpath, "%s/%s", syspath, attr_name)) { ++ condlog(3, "%s: devpath overflow", __func__); ++ return -EOVERFLOW; ++ } + +- snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev), +- attr_name); + condlog(4, "open '%s'", devpath); + /* write attribute value */ + fd = open(devpath, O_WRONLY); + if (fd < 0) { +- condlog(4, "attribute '%s' can not be opened: %s", +- devpath, strerror(errno)); +- return -errno; +- } +- if (fstat(fd, &statbuf) != 0) { +- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno)); +- close(fd); ++ condlog(2, "%s: attribute '%s' can not be opened: %s", ++ __func__, devpath, strerror(errno)); + return -errno; + } + +- /* skip directories */ +- if (S_ISDIR(statbuf.st_mode)) { +- condlog(4, "%s is a directory", devpath); +- close(fd); +- return -EISDIR; +- } +- +- /* skip non-writeable files */ +- if ((statbuf.st_mode & S_IWUSR) == 0) { +- condlog(4, "%s is not writeable", devpath); +- close(fd); +- return -EPERM; +- } +- + size = write(fd, value, value_len); + if (size < 0) { +- condlog(4, "write to %s failed: %s", devpath, strerror(errno)); + size = -errno; ++ condlog(3, "%s: write to %s failed: %s", __func__, ++ devpath, strerror(errno)); + } else if (size < (ssize_t)value_len) { +- condlog(4, "tried to write %ld to %s. Wrote %ld", +- (long)value_len, devpath, (long)size); ++ condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", ++ __func__, value_len, devpath, size); + size = 0; + } + diff --git a/0014-libmultipath-get-rid-of-PATH_SIZE.patch b/0014-libmultipath-get-rid-of-PATH_SIZE.patch new file mode 100644 index 0000000..a080792 --- /dev/null +++ b/0014-libmultipath-get-rid-of-PATH_SIZE.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 11:52:42 +0200 +Subject: [PATCH] libmultipath: get rid of PATH_SIZE + +replace PATH_SIZE with the system limit PATH_MAX. In some places, +PATH_SIZE was used for file names. Use FILE_NAME_SIZE in these cases. +Also, use a constant for "multipathd.service" in systemd_service_enabled_in(). + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs.h | 3 --- + libmultipath/sysfs.c | 8 ++++---- + libmultipath/util.c | 8 +++++--- + multipathd/cli_handlers.c | 2 +- + 4 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index a6a09441..dfa12ff9 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -17,7 +17,6 @@ + #define FILE_NAME_SIZE 256 + #define CALLOUT_MAX_SIZE 256 + #define BLK_DEV_SIZE 33 +-#define PATH_SIZE 512 + #define NAME_SIZE 512 + #define HOST_NAME_LEN 16 + #define SLOT_NAME_SIZE 40 +@@ -519,6 +518,4 @@ int pathcmp (const struct pathgroup *, const struct pathgroup *); + int add_feature (char **, const char *); + int remove_feature (char **, const char *); + +-extern char sysfs_path[PATH_SIZE]; +- + #endif /* _STRUCTS_H */ +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 1f0f2074..e48b05ec 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -48,7 +48,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + char *value, size_t value_len, bool binary) + { + const char *syspath; +- char devpath[PATH_SIZE]; ++ char devpath[PATH_MAX]; + int fd; + ssize_t size = -1; + +@@ -112,7 +112,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + const char * value, size_t value_len) + { + const char *syspath; +- char devpath[PATH_SIZE]; ++ char devpath[PATH_MAX]; + int fd; + ssize_t size = -1; + +@@ -184,7 +184,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) + int sysfs_check_holders(char * check_devt, char * new_devt) + { + unsigned int major, new_minor, table_minor; +- char path[PATH_MAX], check_dev[PATH_SIZE]; ++ char path[PATH_MAX], check_dev[FILE_NAME_SIZE]; + char * table_name; + DIR *dirfd; + struct dirent *holder; +@@ -194,7 +194,7 @@ int sysfs_check_holders(char * check_devt, char * new_devt) + return 0; + } + +- if (devt2devname(check_dev, PATH_SIZE, check_devt)) { ++ if (devt2devname(check_dev, sizeof(check_dev), check_devt)) { + condlog(1, "can't get devname for %s", check_devt); + return 0; + } +diff --git a/libmultipath/util.c b/libmultipath/util.c +index ce5ea73e..e7e7d4c1 100644 +--- a/libmultipath/util.c ++++ b/libmultipath/util.c +@@ -242,13 +242,15 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached) + + int systemd_service_enabled_in(const char *dev, const char *prefix) + { +- char path[PATH_SIZE], file[PATH_MAX], service[PATH_SIZE]; ++ static const char service[] = "multipathd.service"; ++ char path[PATH_MAX], file[PATH_MAX]; + DIR *dirfd; + struct dirent *d; + int found = 0; + +- snprintf(service, PATH_SIZE, "multipathd.service"); +- snprintf(path, PATH_SIZE, "%s/systemd/system", prefix); ++ if (safe_sprintf(path, "%s/systemd/system", prefix)) ++ return 0; ++ + condlog(3, "%s: checking for %s in %s", dev, service, path); + + dirfd = opendir(path); +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index d79cdd7c..db4d4412 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -688,7 +688,7 @@ cli_add_map (void * v, struct strbuf *reply, void * data) + struct vectors * vecs = (struct vectors *)data; + char * param = get_keyparam(v, MAP); + int major = -1, minor = -1; +- char dev_path[PATH_SIZE]; ++ char dev_path[FILE_NAME_SIZE]; + char *refwwid, *alias = NULL; + int rc, count = 0; + struct config *conf; diff --git a/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch b/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch new file mode 100644 index 0000000..d58b785 --- /dev/null +++ b/0015-libmultipath-sysfs_attr_get_value-don-t-return-0-if-.patch @@ -0,0 +1,172 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 13:33:51 +0200 +Subject: [PATCH] libmultipath: sysfs_attr_get_value(): don't return 0 if + buffer too small + +If the passed read buffer is too small to hold the value read plus +terminating 0 byte, return the given size value rather than 0. + +This way we get similar semantics as for sysfs_bin_attr_get_get_value(), +except that sysfs_attr_get_value() must always 0-terminate the value; +thus a return value equal to the length parameter is an error for +the non-binary case. + +Provide a helper macro to test this "overflow" condition. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 2 +- + libmultipath/discovery.c | 14 +++++++------- + libmultipath/propsel.c | 6 +++++- + libmultipath/sysfs.c | 3 +-- + libmultipath/sysfs.h | 13 +++++++++++++ + multipathd/main.c | 2 +- + 6 files changed, 28 insertions(+), 12 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 09ae708d..467bbaa6 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -589,7 +589,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff, + sizeof(buff)); + udev_device_unref(udd); +- if (ret <= 0) { ++ if (!sysfs_attr_value_ok(ret, sizeof(buff))) { + condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias); + return 1; + } +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f5b8401c..54b1caf0 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -560,10 +560,10 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) + if (!parent) + return -1; + +- if (sysfs_attr_get_value(parent, "access_state", buff, buflen) <= 0) ++ if (!sysfs_attr_get_value_ok(parent, "access_state", buff, buflen)) + return -1; + +- if (sysfs_attr_get_value(parent, "preferred_path", value, 16) <= 0) ++ if (!sysfs_attr_get_value_ok(parent, "preferred_path", value, sizeof(value))) + return 0; + + preferred = strtoul(value, &eptr, 0); +@@ -638,8 +638,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + /* + * read the current dev_loss_tmo value from sysfs + */ +- ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, 16); +- if (ret <= 0) { ++ ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, sizeof(value)); ++ if (!sysfs_attr_value_ok(ret, sizeof(value))) { + condlog(0, "%s: failed to read dev_loss_tmo value, " + "error %d", rport_id, -ret); + goto out; +@@ -1737,8 +1737,8 @@ path_offline (struct path * pp) + } + + memset(buff, 0x0, SCSI_STATE_SIZE); +- err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE); +- if (err <= 0) { ++ err = sysfs_attr_get_value(parent, "state", buff, sizeof(buff)); ++ if (!sysfs_attr_value_ok(err, sizeof(buff))) { + if (err == -ENXIO) + return PATH_REMOVED; + else +@@ -2142,7 +2142,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, + return -1; + len = sysfs_attr_get_value(pp->udev, "wwid", value, + sizeof(value)); +- if (len <= 0) ++ if (!sysfs_attr_value_ok(len, sizeof(value))) + return -1; + len = strlcpy(pp->wwid, value, WWID_SIZE); + if (len >= WWID_SIZE) { +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index f782f251..98e3aad1 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -435,6 +435,7 @@ out: + static int get_dh_state(struct path *pp, char *value, size_t value_len) + { + struct udev_device *ud; ++ ssize_t rc; + + if (pp->udev == NULL) + return -1; +@@ -444,7 +445,10 @@ static int get_dh_state(struct path *pp, char *value, size_t value_len) + if (ud == NULL) + return -1; + +- return sysfs_attr_get_value(ud, "dh_state", value, value_len); ++ rc = sysfs_attr_get_value(ud, "dh_state", value, value_len); ++ if (!sysfs_attr_value_ok(rc, value_len)) ++ return -1; ++ return rc; + } + + int select_hwhandler(struct config *conf, struct multipath *mp) +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index e48b05ec..125f1c2b 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -85,7 +85,6 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + condlog(3, "%s: overflow reading from %s (required len: %zu)", + __func__, devpath, size); + value[size - 1] = '\0'; +- size = 0; + } else if (!binary) { + value[size] = '\0'; + size = strchop(value); +@@ -165,7 +164,7 @@ sysfs_get_size (struct path *pp, unsigned long long * size) + return 1; + + attr[0] = '\0'; +- if (sysfs_attr_get_value(pp->udev, "size", attr, 255) <= 0) { ++ if (!sysfs_attr_get_value_ok(pp->udev, "size", attr, sizeof(attr))) { + condlog(3, "%s: No size attribute in sysfs", pp->dev); + return 1; + } +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 72b39ab2..cdc84e40 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -12,6 +12,19 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + char * value, size_t value_len); + ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + unsigned char * value, size_t value_len); ++#define sysfs_attr_value_ok(rc, value_len) \ ++ ({ \ ++ ssize_t __r = rc; \ ++ __r >= 0 && (size_t)__r < (size_t)value_len; \ ++ }) ++ ++#define sysfs_attr_get_value_ok(dev, attr, val, len) \ ++ ({ \ ++ size_t __l = (len); \ ++ ssize_t __rc = sysfs_attr_get_value(dev, attr, val, __l); \ ++ sysfs_attr_value_ok(__rc, __l); \ ++ }) ++ + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); +diff --git a/multipathd/main.c b/multipathd/main.c +index 2f2b9d4c..68eca925 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1126,7 +1126,7 @@ sysfs_get_ro (struct path *pp) + if (!pp->udev) + return -1; + +- if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { ++ if (!sysfs_attr_get_value_ok(pp->udev, "ro", buff, sizeof(buff))) { + condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); + return -1; + } diff --git a/0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch b/0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch new file mode 100644 index 0000000..e9bc0c8 --- /dev/null +++ b/0016-libmultipath-sysfs_attr_set_value-don-t-return-0-on-.patch @@ -0,0 +1,251 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 17:51:41 +0200 +Subject: [PATCH] libmultipath: sysfs_attr_set_value(): don't return 0 on + partial write + +sysfs_attr_set_value() returned 0 if not all requested bytes were written. +Change this to return the number of bytes written. Error checking is now +somewhat more involved; provide a helper macro for it. + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 10 ++++-- + libmultipath/discovery.c | 74 +++++++++++++++++++++++++--------------- + libmultipath/sysfs.c | 6 ++-- + libmultipath/sysfs.h | 10 ++++++ + 4 files changed, 66 insertions(+), 34 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 467bbaa6..0607dbac 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -568,6 +568,7 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + struct pathgroup * pgp; + struct path *pp; + char buff[11]; ++ ssize_t len; + int i, j, ret, err = 0; + struct udev_device *udd; + int max_sectors_kb; +@@ -600,14 +601,17 @@ sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload) + } + } + snprintf(buff, 11, "%d", max_sectors_kb); ++ len = strlen(buff); + + vector_foreach_slot (mpp->pg, pgp, i) { + vector_foreach_slot(pgp->paths, pp, j) { + ret = sysfs_attr_set_value(pp->udev, + "queue/max_sectors_kb", +- buff, strlen(buff)); +- if (ret < 0) { +- condlog(1, "failed setting max_sectors_kb on %s : %s", pp->dev, strerror(-ret)); ++ buff, len); ++ if (ret != len) { ++ log_sysfs_attr_set_value(1, ret, ++ "failed setting max_sectors_kb on %s", ++ pp->dev); + err = 1; + } + } +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 54b1caf0..ee290093 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -598,13 +598,15 @@ sysfs_set_eh_deadline(struct path *pp) + len = sprintf(value, "%d", pp->eh_deadline); + + ret = sysfs_attr_set_value(hostdev, "eh_deadline", +- value, len + 1); ++ value, len); + /* + * not all scsi drivers support setting eh_deadline, so failing + * is totally reasonable + */ +- if (ret <= 0) +- condlog(3, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "%s: failed to set eh_deadline to %s", ++ udev_device_get_sysname(hostdev), value); + + udev_device_unref(hostdev); + return (ret <= 0); +@@ -667,19 +669,22 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + pp->fast_io_fail != MP_FAST_IO_FAIL_OFF) { + /* Check if we need to temporarily increase dev_loss_tmo */ + if ((unsigned int)pp->fast_io_fail >= tmo) { ++ ssize_t len; ++ + /* Increase dev_loss_tmo temporarily */ + snprintf(value, sizeof(value), "%u", + (unsigned int)pp->fast_io_fail + 1); ++ len = strlen(value); + ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", +- value, strlen(value)); +- if (ret <= 0) { ++ value, len); ++ if (ret != len) { + if (ret == -EBUSY) + condlog(3, "%s: rport blocked", + rport_id); + else +- condlog(0, "%s: failed to set " +- "dev_loss_tmo to %s, error %d", +- rport_id, value, -ret); ++ log_sysfs_attr_set_value(0, ret, ++ "%s: failed to set dev_loss_tmo to %s", ++ rport_id, value); + goto out; + } + } +@@ -691,32 +696,39 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) + pp->dev_loss = DEFAULT_DEV_LOSS_TMO; + } + if (pp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { ++ ssize_t len; ++ + if (pp->fast_io_fail == MP_FAST_IO_FAIL_OFF) + sprintf(value, "off"); + else if (pp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) + sprintf(value, "0"); + else + snprintf(value, 16, "%u", pp->fast_io_fail); ++ len = strlen(value); + ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo", +- value, strlen(value)); +- if (ret <= 0) { ++ value, len); ++ if (ret != len) { + if (ret == -EBUSY) + condlog(3, "%s: rport blocked", rport_id); + else +- condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d", +- rport_id, value, -ret); ++ log_sysfs_attr_set_value(0, ret, ++ "%s: failed to set fast_io_fail_tmo to %s", ++ rport_id, value); + } + } + if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { ++ ssize_t len; ++ + snprintf(value, 16, "%u", pp->dev_loss); +- ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", +- value, strlen(value)); +- if (ret <= 0) { ++ len = strlen(value); ++ ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, len); ++ if (ret != len) { + if (ret == -EBUSY) + condlog(3, "%s: rport blocked", rport_id); + else +- condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d", +- rport_id, value, -ret); ++ log_sysfs_attr_set_value(0, ret, ++ "%s: failed to set dev_loss_tmo to %s", ++ rport_id, value); + } + } + out: +@@ -754,12 +766,16 @@ sysfs_set_session_tmo(struct path *pp) + condlog(3, "%s: can't set fast_io_fail_tmo to '0'" + "on iSCSI", pp->dev); + } else { ++ ssize_t len, ret; ++ + snprintf(value, 11, "%u", pp->fast_io_fail); +- if (sysfs_attr_set_value(session_dev, "recovery_tmo", +- value, strlen(value)) <= 0) { +- condlog(3, "%s: Failed to set recovery_tmo, " +- " error %d", pp->dev, errno); +- } ++ len = strlen(value); ++ ret = sysfs_attr_set_value(session_dev, "recovery_tmo", ++ value, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "%s: Failed to set recovery_tmo to %s", ++ pp->dev, value); + } + } + udev_device_unref(session_dev); +@@ -802,12 +818,16 @@ sysfs_set_nexus_loss_tmo(struct path *pp) + pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id); + + if (pp->dev_loss != DEV_LOSS_TMO_UNSET) { ++ ssize_t len, ret; ++ + snprintf(value, 11, "%u", pp->dev_loss); +- if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", +- value, strlen(value)) <= 0) +- condlog(3, "%s: failed to update " +- "I_T Nexus loss timeout, error %d", +- pp->dev, errno); ++ len = strlen(value); ++ ret = sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", ++ value, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(3, ret, ++ "%s: failed to update I_T Nexus loss timeout", ++ pp->dev); + } + udev_device_unref(sas_dev); + return; +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 125f1c2b..9c84af70 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -134,7 +134,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + /* write attribute value */ + fd = open(devpath, O_WRONLY); + if (fd < 0) { +- condlog(2, "%s: attribute '%s' can not be opened: %s", ++ condlog(3, "%s: attribute '%s' can not be opened: %s", + __func__, devpath, strerror(errno)); + return -errno; + } +@@ -144,11 +144,9 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + size = -errno; + condlog(3, "%s: write to %s failed: %s", __func__, + devpath, strerror(errno)); +- } else if (size < (ssize_t)value_len) { ++ } else if (size < (ssize_t)value_len) + condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", + __func__, value_len, devpath, size); +- size = 0; +- } + + close(fd); + return size; +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index cdc84e40..799f68e9 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -5,6 +5,7 @@ + #ifndef _LIBMULTIPATH_SYSFS_H + #define _LIBMULTIPATH_SYSFS_H + #include ++#include "strbuf.h" + + ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + const char * value, size_t value_len); +@@ -25,6 +26,15 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + sysfs_attr_value_ok(__rc, __l); \ + }) + ++#define log_sysfs_attr_set_value(prio, rc, fmt, __args...) \ ++do { \ ++ STRBUF_ON_STACK(__buf); \ ++ if (print_strbuf(&__buf, fmt, ##__args) >= 0 && \ ++ print_strbuf(&__buf, ": %s", rc < 0 ? strerror(-rc) : \ ++ "write underflow") >= 0) \ ++ condlog(prio, "%s", get_strbuf_str(&__buf)); \ ++} while(0) ++ + int sysfs_get_size (struct path *pp, unsigned long long * size); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); diff --git a/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch b/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch new file mode 100644 index 0000000..90fbfdf --- /dev/null +++ b/0017-libmultipath-sysfs-cleanup-file-descriptors-on-pthre.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 18:07:57 +0200 +Subject: [PATCH] libmultipath: sysfs: cleanup file descriptors on + pthread_cancel() + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/sysfs.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 9c84af70..64946385 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -49,7 +49,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + { + const char *syspath; + char devpath[PATH_MAX]; +- int fd; ++ long fd; + ssize_t size = -1; + + if (!dev || !attr_name || !value || !value_len) { +@@ -74,6 +74,8 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + __func__, devpath, strerror(errno)); + return -errno; + } ++ pthread_cleanup_push(close_fd, (void *)fd); ++ + size = read(fd, value, value_len); + if (size < 0) { + size = -errno; +@@ -90,7 +92,7 @@ static ssize_t __sysfs_attr_get_value(struct udev_device *dev, const char *attr_ + size = strchop(value); + } + +- close(fd); ++ pthread_cleanup_pop(1); + return size; + } + +@@ -112,7 +114,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + { + const char *syspath; + char devpath[PATH_MAX]; +- int fd; ++ long fd; + ssize_t size = -1; + + if (!dev || !attr_name || !value || !value_len) { +@@ -138,6 +140,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + __func__, devpath, strerror(errno)); + return -errno; + } ++ pthread_cleanup_push(close_fd, (void *)fd); + + size = write(fd, value, value_len); + if (size < 0) { +@@ -148,7 +151,7 @@ ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name, + condlog(3, "%s: underflow writing %zu bytes to %s. Wrote %zd bytes", + __func__, value_len, devpath, size); + +- close(fd); ++ pthread_cleanup_pop(1); + return size; + } + diff --git a/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch b/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch new file mode 100644 index 0000000..710f633 --- /dev/null +++ b/0018-libmultipath-multipathd-log-failure-setting-sysfs-at.patch @@ -0,0 +1,168 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 18:45:11 +0200 +Subject: [PATCH] libmultipath, multipathd: log failure setting sysfs + attributes + +Failure to set a sysfs attribute is worth noting, normally. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 18 ++++++++++++++--- + multipathd/fpin_handlers.c | 11 +++++++++-- + multipathd/main.c | 40 ++++++++++++++++++++++++++++++-------- + 3 files changed, 56 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 0607dbac..4427f910 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -489,9 +489,15 @@ void trigger_partitions_udev_change(struct udev_device *dev, + + devtype = udev_device_get_devtype(part); + if (devtype && !strcmp("partition", devtype)) { ++ ssize_t ret; ++ + condlog(4, "%s: triggering %s event for %s", __func__, + action, syspath); +- sysfs_attr_set_value(part, "uevent", action, len); ++ ret = sysfs_attr_set_value(part, "uevent", action, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to trigger %s uevent", ++ syspath, action); + } + udev_device_unref(part); + } +@@ -510,6 +516,7 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) + */ + const char *action = is_mpath ? "change" : "add"; + const char *env; ++ ssize_t len, ret; + + if (!pp->udev) + return; +@@ -536,8 +543,13 @@ trigger_path_udev_change(struct path *pp, bool is_mpath) + + condlog(3, "triggering %s uevent for %s (is %smultipath member)", + action, pp->dev, is_mpath ? "" : "no "); +- sysfs_attr_set_value(pp->udev, "uevent", +- action, strlen(action)); ++ ++ len = strlen(action); ++ ret = sysfs_attr_set_value(pp->udev, "uevent", action, len); ++ if (ret != len) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to trigger %s uevent", ++ pp->dev, action); + trigger_partitions_udev_change(pp->udev, action, + strlen(action)); + } +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +index 384ae318..00195721 100644 +--- a/multipathd/fpin_handlers.c ++++ b/multipathd/fpin_handlers.c +@@ -172,8 +172,15 @@ fpin_els_add_li_frame(struct fc_nl_event *fc_event) + /*Sets the rport port_state to marginal*/ + static void fpin_set_rport_marginal(struct udev_device *rport_dev) + { +- sysfs_attr_set_value(rport_dev, "port_state", +- "Marginal", strlen("Marginal")); ++ static const char marginal[] = "Marginal"; ++ ssize_t ret; ++ ++ ret = sysfs_attr_set_value(rport_dev, "port_state", ++ marginal, sizeof(marginal) - 1); ++ if (ret != sizeof(marginal) - 1) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to set port_state to marginal", ++ udev_device_get_syspath(rport_dev)); + } + + /*Add the marginal devices info into the list*/ +diff --git a/multipathd/main.c b/multipathd/main.c +index 68eca925..a160c824 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -911,14 +911,22 @@ rescan_path(struct udev_device *ud) + { + ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi", + "scsi_device"); +- if (ud) +- sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); ++ if (ud) { ++ ssize_t ret = ++ sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); ++ if (ret != strlen("1")) ++ log_sysfs_attr_set_value(1, ret, ++ "%s: failed to trigger rescan", ++ udev_device_get_syspath(ud)); ++ } + } + + void + handle_path_wwid_change(struct path *pp, struct vectors *vecs) + { + struct udev_device *udd; ++ static const char add[] = "add"; ++ ssize_t ret; + + if (!pp || !pp->udev) + return; +@@ -929,8 +937,12 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) + dm_fail_path(pp->mpp->alias, pp->dev_t); + } + rescan_path(udd); +- sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); ++ ret = sysfs_attr_set_value(udd, "uevent", add, sizeof(add) - 1); + udev_device_unref(udd); ++ if (ret != sizeof(add) - 1) ++ log_sysfs_attr_set_value(1, ret, ++ "%s: failed to trigger add event", ++ pp->dev); + } + + bool +@@ -2003,9 +2015,14 @@ partial_retrigger_tick(vector pathvec) + --pp->partial_retrigger_delay == 0) { + const char *msg = udev_device_get_is_initialized(pp->udev) ? + "change" : "add"; +- +- sysfs_attr_set_value(pp->udev, "uevent", msg, +- strlen(msg)); ++ ssize_t len = strlen(msg); ++ ssize_t ret = sysfs_attr_set_value(pp->udev, "uevent", msg, ++ len); ++ ++ if (len != ret) ++ log_sysfs_attr_set_value(2, ret, ++ "%s: failed to trigger %s event", ++ pp->dev, msg); + } + } + } +@@ -2245,12 +2262,19 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) + + if (!pp->mpp && pp->initialized == INIT_MISSING_UDEV) { + if (pp->retriggers < retrigger_tries) { ++ static const char change[] = "change"; ++ ssize_t ret; ++ + condlog(2, "%s: triggering change event to reinitialize", + pp->dev); + pp->initialized = INIT_REQUESTED_UDEV; + pp->retriggers++; +- sysfs_attr_set_value(pp->udev, "uevent", "change", +- strlen("change")); ++ ret = sysfs_attr_set_value(pp->udev, "uevent", change, ++ sizeof(change) - 1); ++ if (ret != sizeof(change) - 1) ++ log_sysfs_attr_set_value(1, ret, ++ "%s: failed to trigger change event", ++ pp->dev); + return 0; + } else { + condlog(1, "%s: not initialized after %d udev retriggers", diff --git a/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch b/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch new file mode 100644 index 0000000..6b7c06b --- /dev/null +++ b/0019-multipath-tests-expect_condlog-skip-depending-on-ver.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 23:18:07 +0200 +Subject: [PATCH] multipath tests: expect_condlog: skip depending on verbosity + +otherwise we'll get failures if verbosity level is low. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/test-log.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tests/test-log.c b/tests/test-log.c +index 14f25b9b..0c17cd96 100644 +--- a/tests/test-log.c ++++ b/tests/test-log.c +@@ -6,6 +6,8 @@ + #include + #include "log.h" + #include "test-log.h" ++#include "debug.h" ++ + + __attribute__((format(printf, 2, 0))) + void __wrap_dlog (int prio, const char * fmt, ...) +@@ -24,6 +26,8 @@ void __wrap_dlog (int prio, const char * fmt, ...) + + void expect_condlog(int prio, char *string) + { ++ if (prio > MAX_VERBOSITY || prio > libmp_verbosity) ++ return; + expect_value(__wrap_dlog, prio, prio); + will_return(__wrap_dlog, string); + } diff --git a/0020-multipath-tests-__wrap_dlog-print-log-message.patch b/0020-multipath-tests-__wrap_dlog-print-log-message.patch new file mode 100644 index 0000000..216e5a2 --- /dev/null +++ b/0020-multipath-tests-__wrap_dlog-print-log-message.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Jul 2022 11:15:27 +0200 +Subject: [PATCH] multipath tests: __wrap_dlog: print log message + +This makes it easier to analyze errors from __wrap_dlog(). + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/test-log.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/test-log.c b/tests/test-log.c +index 0c17cd96..c1745872 100644 +--- a/tests/test-log.c ++++ b/tests/test-log.c +@@ -20,6 +20,7 @@ void __wrap_dlog (int prio, const char * fmt, ...) + va_start(ap, fmt); + vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); + va_end(ap); ++ fprintf(stderr, "%s(%d): %s", __func__, prio, buff); + expected = mock_ptr_type(char *); + assert_memory_equal(buff, expected, strlen(expected)); + } diff --git a/0021-multipath-tests-add-sysfs-test.patch b/0021-multipath-tests-add-sysfs-test.patch new file mode 100644 index 0000000..b02a055 --- /dev/null +++ b/0021-multipath-tests-add-sysfs-test.patch @@ -0,0 +1,538 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 5 Jul 2022 23:19:30 +0200 +Subject: [PATCH] multipath tests: add sysfs test + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + tests/Makefile | 5 +- + tests/sysfs.c | 494 +++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 498 insertions(+), 1 deletion(-) + create mode 100644 tests/sysfs.c + +diff --git a/tests/Makefile b/tests/Makefile +index d20ef236..95a99908 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -16,7 +16,7 @@ CFLAGS += $(BIN_CFLAGS) -Wno-unused-parameter $(W_MISSING_INITIALIZERS) + LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka + + TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ +- alias directio valid devt mpathvalid strbuf ++ alias directio valid devt mpathvalid strbuf sysfs + HELPERS := test-lib.o test-log.o + + .SILENT: $(TESTS:%=%.o) +@@ -70,6 +70,9 @@ ifneq ($(DIO_TEST_DEV),) + directio-test_LIBDEPS := -laio + endif + strbuf-test_OBJDEPS := ../libmultipath/strbuf.o ++sysfs-test_TESTDEPS := test-log.o ++sysfs-test_OBJDEPS := ../libmultipath/sysfs.o ../libmultipath/util.o ++sysfs-test_LIBDEPS := -ludev -lpthread -ldl + + %.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< +diff --git a/tests/sysfs.c b/tests/sysfs.c +new file mode 100644 +index 00000000..0ec135bf +--- /dev/null ++++ b/tests/sysfs.c +@@ -0,0 +1,494 @@ ++/* ++ * Copyright (c) 2021 SUSE LLC ++ * SPDX-License-Identifier: GPL-2.0-only ++ */ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "debug.h" ++#include "globals.c" ++#include "test-log.h" ++#include "sysfs.h" ++#include "util.h" ++ ++#define TEST_FD 123 ++ ++char *__wrap_udev_device_get_syspath(struct udev_device *ud) ++{ ++ char *val = mock_ptr_type(char *); ++ ++ return val; ++} ++ ++int __wrap_open(const char *pathname, int flags) ++{ ++ int ret; ++ ++ check_expected(pathname); ++ check_expected(flags); ++ ret = mock_type(int); ++ return ret; ++} ++ ++ssize_t __wrap_read(int fd, void *buf, size_t count) ++{ ++ ssize_t ret; ++ char *val; ++ ++ check_expected(fd); ++ check_expected(count); ++ ret = mock_type(int); ++ val = mock_ptr_type(char *); ++ if (ret >= (ssize_t)count) ++ ret = count; ++ if (ret >= 0 && val) { ++ fprintf(stderr, "%s: '%s' -> %zd\n", __func__, val, ret); ++ memcpy(buf, val, ret); ++ } ++ return ret; ++} ++ ++ssize_t __wrap_write(int fd, void *buf, size_t count) ++{ ++ ssize_t ret; ++ ++ check_expected(fd); ++ check_expected(count); ++ ret = mock_type(int); ++ if (ret >= (ssize_t)count) ++ ret = count; ++ return ret; ++} ++ ++int __real_close(int fd); ++int __wrap_close(int fd) { ++ if (fd != TEST_FD) ++ return __real_close(fd); ++ return mock_type(int); ++} ++ ++static int setup(void **state) ++{ ++ udev = udev_new(); ++ return 0; ++} ++ ++static int teardown(void **state) ++{ ++ udev_unref(udev); ++ return 0; ++} ++ ++static void expect_sagv_invalid(void) ++{ ++ expect_condlog(1, "__sysfs_attr_get_value: invalid parameters"); ++} ++ ++static void test_sagv_invalid(void **state) ++{ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value(NULL, NULL, NULL, 0), -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value(NULL, (void *)state, (void *)state, 1), ++ -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value(NULL, (void *)state, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value((void *)state, NULL, (void *)state, 1), ++ -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, NULL, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, NULL, 1), ++ -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, NULL, 1), ++ -EINVAL); ++ ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, ++ (void *)state, 0), -EINVAL); ++ expect_sagv_invalid(); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, ++ (void *)state, 0), -EINVAL); ++} ++ ++static void test_sagv_bad_udev(void **state) ++{ ++ will_return(__wrap_udev_device_get_syspath, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); ++ assert_int_equal(sysfs_attr_get_value((void *)state, (void *)state, ++ (void *)state, 1), -EINVAL); ++ ++ will_return(__wrap_udev_device_get_syspath, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: invalid udevice"); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, (void *)state, ++ (void *)state, 1), -EINVAL); ++} ++ ++static void test_sagv_bad_snprintf(void **state) ++{ ++ char longstr[PATH_MAX + 1]; ++ char buf[1]; ++ ++ memset(longstr, 'a', sizeof(longstr) - 1); ++ longstr[sizeof(longstr) - 1] = '\0'; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); ++ assert_int_equal(sysfs_attr_get_value((void *)state, longstr, ++ buf, sizeof(buf)), -EOVERFLOW); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(3, "__sysfs_attr_get_value: devpath overflow"); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, longstr, ++ (unsigned char *)buf, sizeof(buf)), ++ -EOVERFLOW); ++} ++ ++static void test_sagv_open_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ errno = ENOENT; ++ will_return(__wrap_open, -1); ++ expect_condlog(3, "__sysfs_attr_get_value: attribute '/foo/bar' can not be opened"); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, sizeof(buf)), -ENOENT); ++} ++ ++static void test_sagv_read_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, sizeof(buf)); ++ errno = EISDIR; ++ will_return(__wrap_read, -1); ++ will_return(__wrap_read, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/bar failed:"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, sizeof(buf)), -EISDIR); ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/baz'"); ++ expect_string(__wrap_open, pathname, "/foo/baz"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, sizeof(buf)); ++ errno = EPERM; ++ will_return(__wrap_read, -1); ++ will_return(__wrap_read, NULL); ++ expect_condlog(3, "__sysfs_attr_get_value: read from /foo/baz failed:"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", ++ (unsigned char *)buf, sizeof(buf)), ++ -EPERM); ++ ++} ++ ++static void _test_sagv_read(void **state, unsigned int bufsz) ++{ ++ char buf[16]; ++ char input[] = "01234567"; ++ unsigned int n, trunc; ++ ++ assert_in_range(bufsz, 1, sizeof(buf)); ++ memset(buf, '.', sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, bufsz); ++ will_return(__wrap_read, sizeof(input) - 1); ++ will_return(__wrap_read, input); ++ ++ /* If the buffer is too small, input will be truncated by a 0 byte */ ++ if (bufsz <= sizeof(input) - 1) { ++ n = bufsz; ++ trunc = 1; ++ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); ++ } else { ++ n = sizeof(input) - 1; ++ trunc = 0; ++ } ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, bufsz), n); ++ assert_memory_equal(buf, input, n - trunc); ++ assert_int_equal(buf[n - trunc], '\0'); ++ ++ /* Binary input is not truncated */ ++ memset(buf, '.', sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/baz'"); ++ expect_string(__wrap_open, pathname, "/foo/baz"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, bufsz); ++ will_return(__wrap_read, sizeof(input) - 1); ++ will_return(__wrap_read, input); ++ will_return(__wrap_close, 0); ++ n = bufsz < sizeof(input) - 1 ? bufsz : sizeof(input) - 1; ++ assert_int_equal(sysfs_bin_attr_get_value((void *)state, "baz", ++ (unsigned char *)buf, ++ bufsz), ++ n); ++ assert_memory_equal(buf, input, n); ++} ++ ++static void test_sagv_read_overflow_8(void **state) ++{ ++ _test_sagv_read(state, 8); ++} ++ ++static void test_sagv_read_overflow_4(void **state) ++{ ++ _test_sagv_read(state, 4); ++} ++ ++static void test_sagv_read_overflow_1(void **state) ++{ ++ _test_sagv_read(state, 1); ++} ++ ++static void test_sagv_read_good_9(void **state) ++{ ++ _test_sagv_read(state, 9); ++} ++ ++static void test_sagv_read_good_15(void **state) ++{ ++ _test_sagv_read(state, 15); ++} ++ ++static void _test_sagv_read_zeroes(void **state, unsigned int bufsz) ++{ ++ char buf[16]; ++ char input[] = { '\0','\0','\0','\0','\0','\0','\0','\0' }; ++ unsigned int n; ++ ++ assert_in_range(bufsz, 1, sizeof(buf)); ++ memset(buf, '.', sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_RDONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_read, fd, TEST_FD); ++ expect_value(__wrap_read, count, bufsz); ++ will_return(__wrap_read, sizeof(input) - 1); ++ will_return(__wrap_read, input); ++ ++ if (bufsz <= sizeof(input) - 1) { ++ n = bufsz; ++ expect_condlog(3, "__sysfs_attr_get_value: overflow reading from /foo/bar"); ++ } else ++ n = 0; ++ ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_get_value((void *)state, "bar", ++ buf, bufsz), n); ++ ++ /* ++ * The return value of sysfs_attr_get_value ignores zero bytes, ++ * but the read data should have been copied to the buffer ++ */ ++ assert_memory_equal(buf, input, n == 0 ? bufsz : n); ++} ++ ++static void test_sagv_read_zeroes_4(void **state) ++{ ++ _test_sagv_read_zeroes(state, 4); ++} ++ ++static void expect_sasv_invalid(void) ++{ ++ expect_condlog(1, "sysfs_attr_set_value: invalid parameters"); ++} ++ ++static void test_sasv_invalid(void **state) ++{ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value(NULL, NULL, NULL, 0), -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value(NULL, (void *)state, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value((void *)state, NULL, (void *)state, 1), ++ -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, NULL, 1), ++ -EINVAL); ++ ++ expect_sasv_invalid(); ++ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, ++ (void *)state, 0), -EINVAL); ++} ++ ++static void test_sasv_bad_udev(void **state) ++{ ++ will_return(__wrap_udev_device_get_syspath, NULL); ++ expect_condlog(3, "sysfs_attr_set_value: invalid udevice"); ++ assert_int_equal(sysfs_attr_set_value((void *)state, (void *)state, ++ (void *)state, 1), -EINVAL); ++} ++ ++static void test_sasv_bad_snprintf(void **state) ++{ ++ char longstr[PATH_MAX + 1]; ++ char buf[1]; ++ ++ memset(longstr, 'a', sizeof(longstr) - 1); ++ longstr[sizeof(longstr) - 1] = '\0'; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(3, "sysfs_attr_set_value: devpath overflow"); ++ assert_int_equal(sysfs_attr_set_value((void *)state, longstr, ++ buf, sizeof(buf)), -EOVERFLOW); ++} ++ ++static void test_sasv_open_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_WRONLY); ++ errno = EPERM; ++ will_return(__wrap_open, -1); ++ expect_condlog(3, "sysfs_attr_set_value: attribute '/foo/bar' can not be opened"); ++ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", ++ buf, sizeof(buf)), -EPERM); ++} ++ ++static void test_sasv_write_fail(void **state) ++{ ++ char buf[1]; ++ ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_WRONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_write, fd, TEST_FD); ++ expect_value(__wrap_write, count, sizeof(buf)); ++ errno = EISDIR; ++ will_return(__wrap_write, -1); ++ expect_condlog(3, "sysfs_attr_set_value: write to /foo/bar failed:"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", ++ buf, sizeof(buf)), -EISDIR); ++ ++} ++ ++static void _test_sasv_write(void **state, unsigned int n_written) ++{ ++ char buf[8]; ++ ++ assert_in_range(n_written, 0, sizeof(buf)); ++ will_return(__wrap_udev_device_get_syspath, "/foo"); ++ expect_condlog(4, "open '/foo/bar'"); ++ expect_string(__wrap_open, pathname, "/foo/bar"); ++ expect_value(__wrap_open, flags, O_WRONLY); ++ will_return(__wrap_open, TEST_FD); ++ expect_value(__wrap_write, fd, TEST_FD); ++ expect_value(__wrap_write, count, sizeof(buf)); ++ will_return(__wrap_write, n_written); ++ ++ if (n_written < sizeof(buf)) ++ expect_condlog(3, "sysfs_attr_set_value: underflow writing"); ++ will_return(__wrap_close, 0); ++ assert_int_equal(sysfs_attr_set_value((void *)state, "bar", ++ buf, sizeof(buf)), ++ n_written); ++} ++ ++static void test_sasv_write_0(void **state) ++{ ++ _test_sasv_write(state, 0); ++} ++ ++static void test_sasv_write_4(void **state) ++{ ++ _test_sasv_write(state, 4); ++} ++ ++static void test_sasv_write_7(void **state) ++{ ++ _test_sasv_write(state, 7); ++} ++ ++static void test_sasv_write_8(void **state) ++{ ++ _test_sasv_write(state, 8); ++} ++ ++static int test_sysfs(void) ++{ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(test_sagv_invalid), ++ cmocka_unit_test(test_sagv_bad_udev), ++ cmocka_unit_test(test_sagv_bad_snprintf), ++ cmocka_unit_test(test_sagv_open_fail), ++ cmocka_unit_test(test_sagv_read_fail), ++ cmocka_unit_test(test_sagv_read_overflow_1), ++ cmocka_unit_test(test_sagv_read_overflow_4), ++ cmocka_unit_test(test_sagv_read_overflow_8), ++ cmocka_unit_test(test_sagv_read_good_9), ++ cmocka_unit_test(test_sagv_read_good_15), ++ cmocka_unit_test(test_sagv_read_zeroes_4), ++ cmocka_unit_test(test_sasv_invalid), ++ cmocka_unit_test(test_sasv_bad_udev), ++ cmocka_unit_test(test_sasv_bad_snprintf), ++ cmocka_unit_test(test_sasv_open_fail), ++ cmocka_unit_test(test_sasv_write_fail), ++ cmocka_unit_test(test_sasv_write_0), ++ cmocka_unit_test(test_sasv_write_4), ++ cmocka_unit_test(test_sasv_write_7), ++ cmocka_unit_test(test_sasv_write_8), ++ }; ++ ++ return cmocka_run_group_tests(tests, setup, teardown); ++} ++ ++int main(void) ++{ ++ int ret = 0; ++ ++ init_test_verbosity(4); ++ ret += test_sysfs(); ++ return ret; ++} diff --git a/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch b/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch new file mode 100644 index 0000000..fdbb113 --- /dev/null +++ b/0022-libmultipath.version-bump-version-for-sysfs-accessor.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 6 Jul 2022 12:45:33 +0200 +Subject: [PATCH] libmultipath.version: bump version for sysfs accessors + +Formally, the ABI is still the same, but the semantics of the +return value have changed. + +Signed-off-by: Martin Wilck + +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index b3690ac0..c1d9b156 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -207,7 +207,6 @@ global: + strchop; + strlcpy; + sync_map_state; +- sysfs_attr_set_value; + sysfs_get_size; + sysfs_is_multipathed; + timespeccmp; +@@ -264,8 +263,13 @@ global: + + /* foreign */ + free_scandir_result; +- sysfs_attr_get_value; + + local: + *; + }; ++ ++LIBMULTIPATH_16.0.0 { ++global: ++ sysfs_attr_set_value; ++ sysfs_attr_get_value; ++}; diff --git a/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch b/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch new file mode 100644 index 0000000..b69f395 --- /dev/null +++ b/0023-libmultipath-unset-detect_checker-for-clariion-Unity.patch @@ -0,0 +1,31 @@ +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-libmultipath-spelling-cplusplus.patch b/0024-libmultipath-spelling-cplusplus.patch new file mode 100644 index 0000000..bf21a11 --- /dev/null +++ b/0024-libmultipath-spelling-cplusplus.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:11:15 -0400 +Subject: [PATCH] libmultipath: spelling: cplusplus + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmpathvalid/mpath_valid.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h +index ed06196e..ec2f9392 100644 +--- a/libmpathvalid/mpath_valid.h ++++ b/libmpathvalid/mpath_valid.h +@@ -20,7 +20,7 @@ + #ifndef LIB_MPATH_VALID_H + #define LIB_MPATH_VALID_H + +-#ifdef __cpluscplus ++#ifdef __cplusplus + extern "C" { + #endif + diff --git a/0025-libmultipath-spelling-ascii.patch b/0025-libmultipath-spelling-ascii.patch new file mode 100644 index 0000000..01e22e4 --- /dev/null +++ b/0025-libmultipath-spelling-ascii.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:11:12 -0400 +Subject: [PATCH] libmultipath: spelling: ascii + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/alua_spc3.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h +index 08e992bd..e1a6c071 100644 +--- a/libmultipath/prioritizers/alua_spc3.h ++++ b/libmultipath/prioritizers/alua_spc3.h +@@ -143,7 +143,7 @@ inquiry_data_get_tpgs(struct inquiry_data *id) + *----------------------------------------------------------------------------- + */ + #define CODESET_BINARY 0x1 +-#define CODESET_ACSII 0x2 ++#define CODESET_ASCII 0x2 + #define CODESET_UTF8 0x3 + + #define ASSOCIATION_UNIT 0x0 diff --git a/0026-libmultipath-spelling-progress.patch b/0026-libmultipath-spelling-progress.patch new file mode 100644 index 0000000..2984f31 --- /dev/null +++ b/0026-libmultipath-spelling-progress.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:11:22 -0400 +Subject: [PATCH] libmultipath: spelling: progress + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/nvme/linux/nvme.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/nvme/linux/nvme.h b/libmultipath/nvme/linux/nvme.h +index a6975549..9fc2ae7f 100644 +--- a/libmultipath/nvme/linux/nvme.h ++++ b/libmultipath/nvme/linux/nvme.h +@@ -1035,7 +1035,7 @@ enum { + NVME_SANITIZE_LOG_STATUS_MASK = 0x0007, + NVME_SANITIZE_LOG_NEVER_SANITIZED = 0x0000, + NVME_SANITIZE_LOG_COMPLETED_SUCCESS = 0x0001, +- NVME_SANITIZE_LOG_IN_PROGESS = 0x0002, ++ NVME_SANITIZE_LOG_IN_PROGRESS = 0x0002, + NVME_SANITIZE_LOG_COMPLETED_FAILED = 0x0003, + NVME_SANITIZE_LOG_ND_COMPLETED_SUCCESS = 0x0004, + }; diff --git a/0027-multipath-tools-spelling-fixes.patch b/0027-multipath-tools-spelling-fixes.patch new file mode 100644 index 0000000..c1e9468 --- /dev/null +++ b/0027-multipath-tools-spelling-fixes.patch @@ -0,0 +1,599 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Josh Soref <2119212+jsoref@users.noreply.github.com> +Date: Sun, 31 Jul 2022 13:17:53 -0400 +Subject: [PATCH] multipath-tools: spelling fixes + +Spelling errors detected by the GitHub check-spelling action: +https://github.com/marketplace/actions/check-spelling + +Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/foreign.yaml | 2 +- + kpartx/crc32.c | 2 +- + kpartx/gpt.c | 2 +- + libdmmp/libdmmp_path.c | 2 +- + libmpathcmd/mpath_cmd.h | 2 +- + libmpathpersist/mpath_persist_int.c | 2 +- + libmpathvalid/mpath_valid.h | 4 ++-- + libmultipath/checkers/directio.c | 2 +- + libmultipath/config.h | 2 +- + libmultipath/configure.c | 2 +- + libmultipath/discovery.c | 2 +- + libmultipath/nvme/nvme.h | 2 +- + libmultipath/prioritizers/datacore.c | 4 ++-- + libmultipath/prioritizers/hds.c | 2 +- + libmultipath/prioritizers/path_latency.c | 4 ++-- + libmultipath/strbuf.h | 4 ++-- + libmultipath/structs_vec.c | 2 +- + libmultipath/uevent.c | 2 +- + libmultipath/valid.h | 2 +- + mpathpersist/main.c | 2 +- + multipath/multipath.conf.5 | 14 +++++++------- + multipathd/main.c | 10 +++++----- + tests/directio.c | 2 +- + tests/hwtable.c | 10 +++++----- + tests/mpathvalid.c | 2 +- + tests/pgpolicy.c | 2 +- + tests/valid.c | 4 ++-- + third-party/valgrind/valgrind.h | 8 ++++---- + 28 files changed, 50 insertions(+), 50 deletions(-) + +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index e9ffd3d8..32915186 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -56,7 +56,7 @@ jobs: + - name: enable foreign arch + run: sudo docker run --rm --privileged multiarch/qemu-user-static:register --reset + - name: run tests +- # Github actions doesn't support referencing docker images with ++ # GitHub actions doesn't support referencing docker images with + # context variables. Workaround: use mosteo-actions/docker-run action + # See https://github.community/t/expressions-in-docker-uri/16271 + uses: mosteo-actions/docker-run@v1 +diff --git a/kpartx/crc32.c b/kpartx/crc32.c +index e688f8e9..df6c6878 100644 +--- a/kpartx/crc32.c ++++ b/kpartx/crc32.c +@@ -290,7 +290,7 @@ uint32_t attribute((pure)) crc32_be(uint32_t crc, unsigned char const *p, size_t + * the end, so we have to add 32 extra cycles shifting in zeros at the + * end of every message, + * +- * So the standard trick is to rearrage merging in the next_input_bit() ++ * So the standard trick is to rearrange merging in the next_input_bit() + * until the moment it's needed. Then the first 32 cycles can be precomputed, + * and merging in the final 32 zero bits to make room for the CRC can be + * skipped entirely. +diff --git a/kpartx/gpt.c b/kpartx/gpt.c +index 34a910cf..47d8743e 100644 +--- a/kpartx/gpt.c ++++ b/kpartx/gpt.c +@@ -357,7 +357,7 @@ is_gpt_valid(int fd, uint64_t lba, + __le32_to_cpu((*gpt)->num_partition_entries) * + __le32_to_cpu((*gpt)->sizeof_partition_entry)); + if (crc != __le32_to_cpu((*gpt)->partition_entry_array_crc32)) { +- // printf("GUID Partitition Entry Array CRC check failed.\n"); ++ // printf("GUID Partition Entry Array CRC check failed.\n"); + free(*gpt); + *gpt = NULL; + free(*ptes); +diff --git a/libdmmp/libdmmp_path.c b/libdmmp/libdmmp_path.c +index 47a2162c..21714b15 100644 +--- a/libdmmp/libdmmp_path.c ++++ b/libdmmp/libdmmp_path.c +@@ -28,7 +28,7 @@ + #include "libdmmp_private.h" + + #define _DMMP_SHOW_PS_INDEX_BLK_NAME 0 +-#define _DMMP_SHOW_PS_INDEX_SATAUS 1 ++#define _DMMP_SHOW_PS_INDEX_STATUS 1 + #define _DMMP_SHOW_PS_INDEX_WWID 2 + #define _DMMP_SHOW_PS_INDEX_PGID 3 + +diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h +index 30838b02..0c293c71 100644 +--- a/libmpathcmd/mpath_cmd.h ++++ b/libmpathcmd/mpath_cmd.h +@@ -65,7 +65,7 @@ int mpath_connect(void); + /* + * DESCRIPTION: + * Disconnect from the multipathd daemon. This function must be +- * run after after processing all the multipath commands. ++ * run after processing all the multipath commands. + * + * RETURNS: + * 0 on success. -1 on failure (with errno set). +diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c +index e34fc32d..6924b379 100644 +--- a/libmpathpersist/mpath_persist_int.c ++++ b/libmpathpersist/mpath_persist_int.c +@@ -601,7 +601,7 @@ static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, + if (get_be64(mpp->reservation_key) && + memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, + &mpp->reservation_key, 8)){ +- /*register with tarnsport id*/ ++ /*register with transport id*/ + memset(pamp, 0, length); + pamp->trnptid_list[0] = pptr; + memset (pamp->trnptid_list[0], 0, sizeof (struct transportid)); +diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h +index ec2f9392..3e34b1fd 100644 +--- a/libmpathvalid/mpath_valid.h ++++ b/libmpathvalid/mpath_valid.h +@@ -112,7 +112,7 @@ int mpathvalid_exit(void); + * RETURNS: + * MPATH_STRICT, MPATH_SMART, MPATH_GREEDY, or MPATH_MODE_ERROR + * +- * MPATH_STRICT = find_multiapths (yes|on|no|off) ++ * MPATH_STRICT = find_multipaths (yes|on|no|off) + * MPATH_SMART = find_multipaths smart + * MPATH_GREEDY = find_multipaths greedy + * MPATH_MODE_ERROR = multipath configuration not initialized +@@ -126,7 +126,7 @@ unsigned int mpathvalid_get_mode(void); + * potentially claimed (MPATH_IS_VALID, MPATH_IS_VALID_NO_CHECK, + * or MPATH_IS_MAYBE_VALID) and wwid is not NULL, then *wiid will + * be set to point to the wwid of device. If set, *wwid must be +- * freed by the caller. path_wwids is an obptional parameter that ++ * freed by the caller. path_wwids is an optional parameter that + * points to an array of wwids, that were returned from previous + * calls to mpathvalid_is_path(). These are wwids of existing + * devices that are or potentially are claimed by device-mapper +diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c +index bc7b7be5..a326e37b 100644 +--- a/libmultipath/checkers/directio.c ++++ b/libmultipath/checkers/directio.c +@@ -124,7 +124,7 @@ remove_aio_group(struct aio_group *aio_grp) + + /* If an aio_group is completely full of orphans, then no checkers can + * use it, which means that no checkers can clear out the orphans. To +- * avoid keeping the useless group around, simply remove remove the ++ * avoid keeping the useless group around, simply remove the + * group */ + static void + check_orphaned_group(struct aio_group *aio_grp) +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 36d40157..fdcdff0a 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -248,7 +248,7 @@ struct config { + * libmultipath calls. If an application wants to keep using the + * udev variable after calling libmultipath_exit(), it should have taken + * an additional reference on it beforehand. This is the case e.g. +- * after initiazing udev with udev_new(). ++ * after initializing udev with udev_new(). + */ + extern struct udev *udev; + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 4427f910..8af7cd79 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -397,7 +397,7 @@ int setup_map(struct multipath *mpp, char **params, struct vectors *vecs) + * into a mp->params strings to feed the device-mapper + */ + if (assemble_map(mpp, params)) { +- condlog(0, "%s: problem assembing map", mpp->alias); ++ condlog(0, "%s: problem assembling map", mpp->alias); + return 1; + } + return 0; +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index ee290093..15560f8c 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1344,7 +1344,7 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, + condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); + return -EINVAL; + } +- if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ ++ if (in[4] <= 3) /* revision must be > 3 to have Volume Name */ + return -ENODATA; + len = get_unaligned_be32(&in[40]); + if (len > out_len || len + 44 > in_len) { +diff --git a/libmultipath/nvme/nvme.h b/libmultipath/nvme/nvme.h +index 7e0278b5..57f82a31 100644 +--- a/libmultipath/nvme/nvme.h ++++ b/libmultipath/nvme/nvme.h +@@ -224,7 +224,7 @@ char *nvme_char_from_block(char *block); + * Notes: This function does not care about transport so that the offset is + * not going to be checked inside of this function for the unsupported fields + * in a specific transport. For example, BPMBL(Boot Partition Memory Buffer +- * Location) register is not supported by fabrics, but it can be chcked here. ++ * Location) register is not supported by fabrics, but it can be checked here. + */ + static inline bool is_64bit_reg(__u32 offset) + { +diff --git a/libmultipath/prioritizers/datacore.c b/libmultipath/prioritizers/datacore.c +index 02dc2e27..d1d473d4 100644 +--- a/libmultipath/prioritizers/datacore.c ++++ b/libmultipath/prioritizers/datacore.c +@@ -1,6 +1,6 @@ + /* + * (C) 2010 Christophe Varoqui +- * (C) 2009 Dembach Goo Infromatik GmbH & Co KG ++ * (C) 2009 Dembach Goo Informatik GmbH & Co KG + * Manon Goo + * + * datacore.c +@@ -10,7 +10,7 @@ + * Matthias Rudolph + * + * This work is made available on the basis of the +- * GPLv2 for detials see . ++ * GPLv2 for details see . + * + * Manon Goo 2009 + * +diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c +index 88cac5f0..d569f2d7 100644 +--- a/libmultipath/prioritizers/hds.c ++++ b/libmultipath/prioritizers/hds.c +@@ -32,7 +32,7 @@ + * Half of the LUNs are accessed via one HBA/storage controller and the other + * half via the other HBA/storage controller. + * +- * In cluster environmemnts (RAC) it also guarantees that all cluster nodes have ++ * In cluster environments (RAC) it also guarantees that all cluster nodes have + * access to the LDEVs via the same controller. + * + * You can run the prioritizer manually in verbose mode: +diff --git a/libmultipath/prioritizers/path_latency.c b/libmultipath/prioritizers/path_latency.c +index e155f6dc..2f5be9b9 100644 +--- a/libmultipath/prioritizers/path_latency.c ++++ b/libmultipath/prioritizers/path_latency.c +@@ -64,7 +64,7 @@ static int prepare_directio_read(int fd, int *blksz, char **pbuf, + long flags; + + if (ioctl(fd, BLKBSZGET, blksz) < 0) { +- pp_pl_log(3,"catnnot get blocksize, set default"); ++ pp_pl_log(3,"cannot get blocksize, set default"); + *blksz = DEF_BLK_SIZE; + } + if (posix_memalign((void **)pbuf, pgsize, *blksz)) +@@ -193,7 +193,7 @@ out: + } + + /* +- * Do not scale the prioriy in a certain range such as [0, 1024] ++ * Do not scale the priority in a certain range such as [0, 1024] + * because scaling will eliminate the effect of base_num. + */ + int calcPrio(double lg_avglatency, double lg_maxavglatency, +diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h +index 41d7d54f..31ab519a 100644 +--- a/libmultipath/strbuf.h ++++ b/libmultipath/strbuf.h +@@ -159,7 +159,7 @@ int fill_strbuf(struct strbuf *buf, char c, int slen); + * + * Appends the given string to @strbuf, with leading and trailing double + * quotes (") added, expanding @strbuf's size as necessary. Any double quote +- * characters (") in the string are transformed to double double quotes (""). ++ * characters (") in the string are transformed to a pair of double quotes (""). + * If the function returns an error, @strbuf is unchanged. + */ + int append_strbuf_quoted(struct strbuf *buf, const char *str); +@@ -171,7 +171,7 @@ int append_strbuf_quoted(struct strbuf *buf, const char *str); + * @returns: number of appended characters if successful, (excluding + * terminating '\0'); negative error code otherwise + * +- * Appends the the arguments following @fmt, formatted as in printf(), to ++ * Appends the arguments following @fmt, formatted as in printf(), to + * @strbuf, expanding @strbuf's size as necessary. The function makes sure that + * the output @strbuf is always 0-terminated. + * If the function returns an error, @strbuf is unchanged. +diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c +index a69f0643..645896c6 100644 +--- a/libmultipath/structs_vec.c ++++ b/libmultipath/structs_vec.c +@@ -205,7 +205,7 @@ static bool update_pathvec_from_dm(vector pathvec, struct multipath *mpp, + continue; + + /* +- * At this point, pp->udev is valid and and pp->wwid ++ * At this point, pp->udev is valid and pp->wwid + * is the best we could get + */ + if (*pp->wwid && strcmp(mpp->wwid, pp->wwid)) { +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index 5793af94..57447ca0 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -373,7 +373,7 @@ uevent_filter(struct uevent *later, struct uevent_filter_state *st) + + list_for_some_entry_reverse_safe(earlier, tmp, &later->node, &st->uevq, node) { + /* +- * filter unnessary earlier uevents ++ * filter unnecessary earlier uevents + * by the later uevent + */ + if (!list_empty(&earlier->merge_node)) { +diff --git a/libmultipath/valid.h b/libmultipath/valid.h +index ce1c7cbf..731e6eff 100644 +--- a/libmultipath/valid.h ++++ b/libmultipath/valid.h +@@ -23,7 +23,7 @@ + * already. + * PATH_IS_VALID is returned by is_path_valid, when the path is + * valid only if it hasn't been released to systemd already. +- * PATH_IS_MAYBE_VALID is returned when the the path would be valid ++ * PATH_IS_MAYBE_VALID is returned when the path would be valid + * if other paths with the same wwid existed. It is up to the caller + * to check for these other paths. + */ +diff --git a/mpathpersist/main.c b/mpathpersist/main.c +index 4bdd55c2..894e8c94 100644 +--- a/mpathpersist/main.c ++++ b/mpathpersist/main.c +@@ -480,7 +480,7 @@ static int handle_args(int argc, char * argv[], int nline) + } + if ((verbose > 2) && num_transportids) + { +- fprintf (stderr, "number of tranport-ids decoded from " ++ fprintf (stderr, "number of transport-ids decoded from " + "command line : %d\n", num_transportids); + } + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index c2d34f18..853e0feb 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -455,7 +455,7 @@ precedence. See KNOWN ISSUES. + (Since kernel 2.6.38) Number of msecs before pg_init retry, it must be between 0 and 60000. + .TP + .I queue_mode +-(Since kernel 4.8) Select the the queueing mode per multipath device. ++(Since kernel 4.8) Select the queueing mode per multipath device. + can be \fIbio\fR, \fIrq\fR or \fImq\fR, which corresponds to + bio-based, request-based, and block-multiqueue (blk-mq) request-based, + respectively. +@@ -935,7 +935,7 @@ This option is not supported any more. The value is ignored. + .B san_path_err_threshold + If set to a value greater than 0, multipathd will watch paths and check how many + times a path has been failed due to errors.If the number of failures on a particular +-path is greater then the san_path_err_threshold, then the path will not reinstate ++path is greater than the san_path_err_threshold, then the path will not reinstate + till san_path_err_recovery_time. These path failures should occur within a + san_path_err_forget_rate checks, if not we will consider the path is good enough + to reinstantate. See "Shaky paths detection" below. +@@ -949,7 +949,7 @@ The default is: \fBno\fR + .B san_path_err_forget_rate + If set to a value greater than 0, multipathd will check whether the path failures + has exceeded the san_path_err_threshold within this many checks i.e +-san_path_err_forget_rate . If so we will not reinstante the path till ++san_path_err_forget_rate . If so we will not reinstate the path till + san_path_err_recovery_time. See "Shaky paths detection" below. + .RS + .TP +@@ -962,7 +962,7 @@ The default is: \fBno\fR + If set to a value greater than 0, multipathd will make sure that when path failures + has exceeded the san_path_err_threshold within san_path_err_forget_rate then the path + will be placed in failed state for san_path_err_recovery_time duration.Once san_path_err_recovery_time +-has timeout we will reinstante the failed path . ++has timeout we will reinstate the failed path . + san_path_err_recovery_time value should be in secs. + See "Shaky paths detection" below. + .RS +@@ -1000,7 +1000,7 @@ If the rate of IO error on a particular path is greater than the + \fImarginal_path_err_rate_threshold\fR, then the path will not reinstate for + \fImarginal_path_err_recheck_gap_time\fR seconds unless there is only one + active path. After \fImarginal_path_err_recheck_gap_time\fR expires, the path +-will be requeueed for rechecking. If checking result is good enough, the ++will be requeued for rechecking. If checking result is good enough, the + path will be reinstated. See "Shaky paths detection" below. + .RS + .TP +@@ -1031,7 +1031,7 @@ value, the failed path of which the IO error rate is larger than + \fImarginal_path_err_rate_threshold\fR will be kept in failed state for + \fImarginal_path_err_recheck_gap_time\fR seconds. When + \fImarginal_path_err_recheck_gap_time\fR seconds expires, the path will be +-requeueed for checking. If checking result is good enough, the path will be ++requeued for checking. If checking result is good enough, the path will be + reinstated, or else it will keep failed. See "Shaky paths detection" below. + .RS + .TP +@@ -1379,7 +1379,7 @@ The protocol that a path is using can be viewed by running + \fBmultipathd show paths format "%d %P"\fR + .RE + .LP +-For every device, these 5 blacklist criteria are evaluated in the the order ++For every device, these 5 blacklist criteria are evaluated in the order + "property, dev\%node, device, protocol, wwid". If a device turns out to be + blacklisted by any criterion, it's excluded from handling by multipathd, and + the later criteria aren't evaluated any more. For each +diff --git a/multipathd/main.c b/multipathd/main.c +index a160c824..defee10a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -583,7 +583,7 @@ retry: + if (mpp->prflag) { + vector_foreach_slot(mpp->paths, pp, i) { + if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { +- /* persistent reseravtion check*/ ++ /* persistent reservation check*/ + mpath_pr_event_handle(pp); + } + } +@@ -1515,7 +1515,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + condlog(3, "%s: error in change_foreign", __func__); + break; + default: +- condlog(1, "%s: return code %d of change_forein is unsupported", ++ condlog(1, "%s: return code %d of change_foreign is unsupported", + __func__, rc); + break; + } +@@ -1966,7 +1966,7 @@ ghost_delay_tick(struct vectors *vecs) + } + + static void +-defered_failback_tick (vector mpvec) ++deferred_failback_tick (vector mpvec) + { + struct multipath * mpp; + unsigned int i; +@@ -2186,7 +2186,7 @@ static int check_path_reinstate_state(struct path * pp) { + get_monotonic_time(&curr_time); + /* when path failures has exceeded the san_path_err_threshold + * place the path in delayed state till san_path_err_recovery_time +- * so that the cutomer can rectify the issue within this time. After ++ * so that the customer can rectify the issue within this time. After + * the completion of san_path_err_recovery_time it should + * automatically reinstate the path + * (note: we know that san_path_err_threshold > 0 here). +@@ -2647,7 +2647,7 @@ checkerloop (void *ap) + pthread_cleanup_push(cleanup_lock, &vecs->lock); + lock(&vecs->lock); + pthread_testcancel(); +- defered_failback_tick(vecs->mpvec); ++ deferred_failback_tick(vecs->mpvec); + retry_count_tick(vecs->mpvec); + missing_uev_wait_tick(vecs); + ghost_delay_tick(vecs); +diff --git a/tests/directio.c b/tests/directio.c +index 20ccc47a..01fdef28 100644 +--- a/tests/directio.c ++++ b/tests/directio.c +@@ -497,7 +497,7 @@ static void test_free_with_pending(void **state) + do_libcheck_reset(1); + } + +-/* test removing orpahed aio_group on free */ ++/* test removing orphaned aio_group on free */ + static void test_orphaned_aio_group(void **state) + { + struct checker c[AIO_GROUP_SIZE] = {{.cls = NULL}}; +diff --git a/tests/hwtable.c b/tests/hwtable.c +index bfaf613f..334b75e8 100644 +--- a/tests/hwtable.c ++++ b/tests/hwtable.c +@@ -29,7 +29,7 @@ + + #define N_CONF_FILES 2 + +-static const char tmplate[] = "/tmp/hwtable-XXXXXX"; ++static const char template[] = "/tmp/hwtable-XXXXXX"; + + struct key_value { + const char *key; +@@ -136,7 +136,7 @@ static int setup(void **state) + if (hwt == NULL) + return -1; + +- snprintf(buf, sizeof(buf), "%s", tmplate); ++ snprintf(buf, sizeof(buf), "%s", template); + if (mkdtemp(buf) == NULL) { + condlog(0, "mkdtemp: %s", strerror(errno)); + goto err; +@@ -255,7 +255,7 @@ static void write_defaults(const struct hwt_state *hwt) + { "detect_prio", "no" }, + { "detect_checker", "no" }, + }; +- char buf[sizeof(tmplate) + sizeof(bindings_name)]; ++ char buf[sizeof(template) + sizeof(bindings_name)]; + char dirbuf[PATH_MAX]; + + snprintf(buf, sizeof(buf), "%s/%s", hwt->tmpname, bindings_name); +@@ -308,7 +308,7 @@ static void write_device(FILE *ff, int nkv, const struct key_value *kv) + } + + /* +- * Some macros to avoid boilerplace code ++ * Some macros to avoid boilerplate code + */ + + #define CHECK_STATE(state) ({ \ +@@ -448,7 +448,7 @@ static const struct key_value npr_queue = { _no_path_retry, "queue" }; + /***** BEGIN TESTS SECTION *****/ + + /* +- * Dump the configuration, subistitute the dumped configuration ++ * Dump the configuration, substitute the dumped configuration + * for the current one, and verify that the result is identical. + */ + static void replicate_config(const struct hwt_state *hwt, bool local) +diff --git a/tests/mpathvalid.c b/tests/mpathvalid.c +index 0230a88f..df66ed6a 100644 +--- a/tests/mpathvalid.c ++++ b/tests/mpathvalid.c +@@ -399,7 +399,7 @@ static void test_mpathvalid_is_path_good3(void **state) + free(wwid); + } + +-/* mabybe valid with no matching paths */ ++/* maybe valid with no matching paths */ + static void test_mpathvalid_is_path_good4(void **state) + { + const char *wwids[] = { "WWID_A", "WWID_B", "WWID_C", "WWID_D" }; +diff --git a/tests/pgpolicy.c b/tests/pgpolicy.c +index f116d12c..43be831f 100644 +--- a/tests/pgpolicy.c ++++ b/tests/pgpolicy.c +@@ -191,7 +191,7 @@ verify_pathgroups(struct multipath *mp, struct path *pp, int **groups, + /* Test names instead of pointers to get a more + * useful error message */ + assert_string_equal(pgp_path->dev, pp_path->dev); +- /* This test is just a backkup in case the ++ /* This test is just a backup in case the + * something wenth wrong naming the paths */ + assert_ptr_equal(pgp_path, pp_path); + } +diff --git a/tests/valid.c b/tests/valid.c +index e7393a1c..398b771e 100644 +--- a/tests/valid.c ++++ b/tests/valid.c +@@ -293,7 +293,7 @@ static void test_sysfs_is_multipathed(void **state) + + memset(&pp, 0, sizeof(pp)); + conf.find_multipaths = FIND_MULTIPATHS_STRICT; +- /* test for already existing multiapthed device */ ++ /* test for already existing multipathed device */ + will_return(__wrap_sysfs_is_multipathed, true); + will_return(__wrap_sysfs_is_multipathed, wwid); + assert_int_equal(is_path_valid(name, &conf, &pp, true), +@@ -452,7 +452,7 @@ static void test_greedy(void **state) + assert_string_equal(pp.dev, name); + assert_ptr_equal(pp.udev, &test_udev); + assert_string_equal(pp.wwid, wwid); +- /* test greedy success without checking multiapthd */ ++ /* test greedy success without checking multipathd */ + memset(&pp, 0, sizeof(pp)); + setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); + assert_int_equal(is_path_valid(name, &conf, &pp, false), +diff --git a/third-party/valgrind/valgrind.h b/third-party/valgrind/valgrind.h +index 577c8f05..1633b318 100644 +--- a/third-party/valgrind/valgrind.h ++++ b/third-party/valgrind/valgrind.h +@@ -1075,7 +1075,7 @@ typedef + + /* Use these to write the name of your wrapper. NOTE: duplicates + VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts +- the default behaviour equivalance class tag "0000" into the name. ++ the default behaviour equivalence class tag "0000" into the name. + See pub_tool_redir.h for details -- normally you don't need to + think about this, though. */ + +@@ -1620,11 +1620,11 @@ typedef + and say that %r15 is trashed instead. gcc seems happy to go with + that. + +- Oh .. and this all needs to be conditionalised so that it is ++ Oh .. and this all needs to be conditionalized so that it is + unchanged from before this commit, when compiled with older gccs + that don't support __builtin_dwarf_cfa. Furthermore, since + this header file is freestanding, it has to be independent of +- config.h, and so the following conditionalisation cannot depend on ++ config.h, and so the following conditionalization cannot depend on + configure time checks. + + Although it's not clear from +@@ -1673,7 +1673,7 @@ typedef + /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ + macros. In order not to trash the stack redzone, we need to drop + %rsp by 128 before the hidden call, and restore afterwards. The +- nastyness is that it is only by luck that the stack still appears ++ nastiness is that it is only by luck that the stack still appears + to be unwindable during the hidden call - since then the behaviour + of any routine using this macro does not match what the CFI data + says. Sigh. diff --git a/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch b/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch new file mode 100644 index 0000000..f2dbfce --- /dev/null +++ b/0028-multipath-tools-remove-list-of-rebranded-arrays-vend.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 21 Jul 2022 19:22:04 +0200 +Subject: [PATCH] multipath-tools: remove list of rebranded arrays vendors from + man page + +It does not provide useful info, and it is incomplete. + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 853e0feb..8b7dc511 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -315,12 +315,12 @@ accepts the optional prio_arg \fIexclusive_pref_bit\fR. + .TP + .I ontap + (Hardware-dependent) +-Generate the path priority for NetApp ONTAP class and OEM arrays as IBM NSeries. ++Generate the path priority for NetApp ONTAP class, and rebranded arrays. + .TP + .I rdac + (Hardware-dependent) + Generate the path priority for LSI/Engenio/NetApp RDAC class as NetApp SANtricity +-E/EF Series, and OEM arrays from IBM DELL SGI STK and SUN. ++E/EF Series, and rebranded arrays. + .TP + .I hp_sw + (Hardware-dependent) +@@ -496,7 +496,7 @@ Active/Standby mode exclusively. + .I rdac + (Hardware-dependent) + Check the path state for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF +-Series, and OEM arrays from IBM DELL SGI STK and SUN. ++Series, and rebranded arrays. + .TP + .I directio + Read the first sector with direct I/O. This checker could cause spurious path +@@ -1568,7 +1568,7 @@ families. + .I 1 rdac + (Hardware-dependent) + Hardware handler for LSI/Engenio/NetApp RDAC class as NetApp SANtricity E/EF +-Series, and OEM arrays from IBM DELL SGI STK and SUN. ++Series, and rebranded arrays. + .TP + .I 1 hp_sw + (Hardware-dependent) diff --git a/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch b/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch new file mode 100644 index 0000000..8777ea1 --- /dev/null +++ b/0029-multipath-tools-correct-CLARiiON-info-from-multipath.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 23 Jul 2022 00:01:13 +0200 +Subject: [PATCH] multipath-tools: correct CLARiiON info from multipath.conf + man page + +Remove "Unity" from emc prio and hardware_handler, because +Unity does not support PNR mode, just ALUA (page 113 and 153): +https://www.delltechnologies.com/asset/en-us/products/storage/technical-support/docu5128.pdf +And add PNR info. + +Cc: Yanfei Chen +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 8b7dc511..acdd1ae6 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -306,7 +306,7 @@ generate the path priority. This prioritizer accepts the optional prio_arg + .I emc + (Hardware-dependent) + Generate the path priority for DGC class arrays as CLARiiON CX/AX and +-EMC VNX and Unity families. ++EMC VNX families with Failover Mode 1 (Passive Not Ready(PNR)). + .TP + .I alua + (Hardware-dependent) +@@ -1562,8 +1562,8 @@ The following hardware handler are implemented: + .TP 12 + .I 1 emc + (Hardware-dependent) +-Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX and Unity +-families. ++Hardware handler for DGC class arrays as CLARiiON CX/AX and EMC VNX families ++with Failover Mode 1 (Passive Not Ready(PNR)). + .TP + .I 1 rdac + (Hardware-dependent) diff --git a/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch b/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch new file mode 100644 index 0000000..592be10 --- /dev/null +++ b/0030-multipath-tools-add-basic-info-on-how-to-use-multipa.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 23 Jul 2022 15:12:04 +0200 +Subject: [PATCH] multipath-tools: add basic info on how to use multipath-tools + with NVMe devices + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + README.md | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/README.md b/README.md +index 2322082c..b05b1332 100644 +--- a/README.md ++++ b/README.md +@@ -174,3 +174,19 @@ To enable ALUA, the following options should be changed: + + - Huawei OceanStor: + "Host Access Mode" should be changed to "Asymmetric". ++ ++ ++NVMe ++==== ++To use Device Mapper/multipath-tools with NVMe devices, ++if the Native NVMe Multipath subsystem is enabled ++( "Y" in `/sys/module/nvme_core/parameters/multipath` ), ++it has to be disabled: ++ ++`echo "options nvme_core multipath=N" > /etc/modprobe.d/01-nvme_core-mp.conf`, ++regenerate the initramfs (`dracut -f` or `update-initramfs`) and reboot. ++ ++Check that it is disabled(N) with: ++`cat /sys/module/nvme_core/parameters/multipath` ++or ++`systool -m nvme_core -A multipath` diff --git a/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch b/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch new file mode 100644 index 0000000..bb8aa05 --- /dev/null +++ b/0031-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Aug 2022 16:46:26 -0500 +Subject: [PATCH] multipathd: factor out the code to flush a map with no paths + +The code to flush a multipath device because all of its paths have +been removed will be used by another caller, so factor it out of +ev_remove_path(). + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 56 ++++++++++++++++++++++++----------------------- + 1 file changed, 29 insertions(+), 27 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index defee10a..53cbdb61 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -561,6 +561,30 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset) + return 0; + } + ++static bool ++flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { ++ char alias[WWID_SIZE]; ++ ++ /* ++ * flush_map will fail if the device is open ++ */ ++ strlcpy(alias, mpp->alias, WWID_SIZE); ++ if (mpp->flush_on_last_del == FLUSH_ENABLED) { ++ condlog(2, "%s Last path deleted, disabling queueing", ++ mpp->alias); ++ mpp->retry_tick = 0; ++ mpp->no_path_retry = NO_PATH_RETRY_FAIL; ++ mpp->disable_queueing = 1; ++ mpp->stat_map_failures++; ++ dm_queue_if_no_path(mpp->alias, 0); ++ } ++ if (!flush_map(mpp, vecs, 1)) { ++ condlog(2, "%s: removed map after removing all paths", alias); ++ return true; ++ } ++ return false; ++} ++ + static int + update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { +@@ -1363,34 +1387,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + vector_del_slot(mpp->paths, i); + + /* +- * remove the map IF removing the last path ++ * remove the map IF removing the last path. If ++ * flush_map_nopaths succeeds, the path has been removed. + */ +- if (VECTOR_SIZE(mpp->paths) == 0) { +- char alias[WWID_SIZE]; +- +- /* +- * flush_map will fail if the device is open +- */ +- strlcpy(alias, mpp->alias, WWID_SIZE); +- if (mpp->flush_on_last_del == FLUSH_ENABLED) { +- condlog(2, "%s Last path deleted, disabling queueing", mpp->alias); +- mpp->retry_tick = 0; +- mpp->no_path_retry = NO_PATH_RETRY_FAIL; +- mpp->disable_queueing = 1; +- mpp->stat_map_failures++; +- dm_queue_if_no_path(mpp->alias, 0); +- } +- if (!flush_map(mpp, vecs, 1)) { +- condlog(2, "%s: removed map after" +- " removing all paths", +- alias); +- /* flush_map() has freed the path */ +- goto out; +- } +- /* +- * Not an error, continue +- */ +- } ++ if (VECTOR_SIZE(mpp->paths) == 0 && ++ flush_map_nopaths(mpp, vecs)) ++ goto out; + + if (setup_map(mpp, ¶ms, vecs)) { + condlog(0, "%s: failed to setup map for" diff --git a/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch b/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch new file mode 100644 index 0000000..ab04fd9 --- /dev/null +++ b/0032-libmultipath-return-success-if-we-raced-to-remove-a-.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Aug 2022 16:46:27 -0500 +Subject: [PATCH] libmultipath: return success if we raced to remove a map and + lost + +_dm_flush_map() was returning failure if it failed to remove a map, +even if that was because the map had already been removed. Return +success in this case. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/devmapper.c | 4 ++++ + multipathd/main.c | 4 ---- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 1748d258..a49db3b0 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -1111,6 +1111,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, + } + condlog(4, "multipath map %s removed", mapname); + return 0; ++ } else if (dm_is_mpath(mapname) != 1) { ++ condlog(4, "multipath map %s removed externally", ++ mapname); ++ return 0; /*we raced with someone else removing it */ + } else { + condlog(2, "failed to remove multipath map %s", + mapname); +diff --git a/multipathd/main.c b/multipathd/main.c +index 53cbdb61..3fcd6bdb 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -758,10 +758,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) + * the spurious uevent we may generate with the dm_flush_map call below + */ + if (r) { +- /* +- * May not really be an error -- if the map was already flushed +- * from the device mapper by dmsetup(8) for instance. +- */ + if (r == 1) + condlog(0, "%s: can't flush", mpp->alias); + else { diff --git a/0033-multipathd-Handle-losing-all-path-in-update_map.patch b/0033-multipathd-Handle-losing-all-path-in-update_map.patch new file mode 100644 index 0000000..43358d3 --- /dev/null +++ b/0033-multipathd-Handle-losing-all-path-in-update_map.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 9 Aug 2022 16:46:28 -0500 +Subject: [PATCH] multipathd: Handle losing all path in update_map + +Its possible that when a multipath device is being updated, it will end +up that all the paths for it are gone. This can happen if paths are +added and then removed again before multipathd processes the uevent for +the newly created multipath device. In this case multipathd wasn't +taking the proper action for the case where all the paths had been +removed. If flush_on_last_del was set, multipathd wasn't disabling +flushing and if deferred_remove was set, it wasn't doing a deferred +remove. Multipathd should call flush_map_nopaths(), just like +ev_remove_path() does when the last path is removed. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3fcd6bdb..7d127dbe 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -602,6 +602,10 @@ retry: + goto fail; + } + verify_paths(mpp); ++ if (VECTOR_SIZE(mpp->paths) == 0 && ++ flush_map_nopaths(mpp, vecs)) ++ return 1; ++ + mpp->action = ACT_RELOAD; + + if (mpp->prflag) { diff --git a/0034-multipath-fix-systemd-timers-in-the-initramfs.patch b/0034-multipath-fix-systemd-timers-in-the-initramfs.patch new file mode 100644 index 0000000..91178ea --- /dev/null +++ b/0034-multipath-fix-systemd-timers-in-the-initramfs.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 5 Aug 2022 18:16:03 -0500 +Subject: [PATCH] multipath: fix systemd timers in the initramfs + +The systemd timers created for "find_multipaths smart" conflict with +shutdown.target, but not with initrd-cleanup.service. This can make +these timers trigger after the inirtd has started shutting down, +restarting multipathd (which then stops initrd-cleanup.service, since it +conflicts). To avoid this, make sure the timers and the unit they +trigger conflict with inird-cleanup.service. Also don't make them start +multipathd. "multipath -u" will not return "maybe" if multipathd isn't +running or set to run, and since we no longer wait for udev-settle, +multipathd starts up pretty quickly, so it shouldn't be a problem to +not trigger it here. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipath/multipath.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.rules b/multipath/multipath.rules +index 9df11a95..f993d996 100644 +--- a/multipath/multipath.rules ++++ b/multipath/multipath.rules +@@ -71,7 +71,7 @@ ENV{.SAVED_FM_WAIT_UNTIL}=="?*", GOTO="pretend_mpath" + # + # We must trigger an "add" event because LVM2 will only act on those. + +-RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Wants=multipathd.service --property After=multipathd.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" ++RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property Conflicts=initrd-cleanup.service --timer-property Before=initrd-cleanup.service --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Conflicts=initrd-cleanup.service --property Before=initrd-cleanup.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" + + LABEL="pretend_mpath" + ENV{DM_MULTIPATH_DEVICE_PATH}="1" diff --git a/0035-multipathd-Add-missing-ctype-include.patch b/0035-multipathd-Add-missing-ctype-include.patch new file mode 100644 index 0000000..29ea453 --- /dev/null +++ b/0035-multipathd-Add-missing-ctype-include.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Bastian Germann +Date: Thu, 14 Oct 2021 00:34:33 +0200 +Subject: [PATCH] multipathd: Add missing ctype include + +In uxclnt.c, there are isspace calls. Add an explicit include. + +Signed-off-by: Bastian Germann +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/uxclnt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c +index b1b058bd..bdcc7c3f 100644 +--- a/multipathd/uxclnt.c ++++ b/multipathd/uxclnt.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/0036-multipathd-replace-libreadline-with-libedit.patch b/0036-multipathd-replace-libreadline-with-libedit.patch new file mode 100644 index 0000000..f376ee7 --- /dev/null +++ b/0036-multipathd-replace-libreadline-with-libedit.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 12 Aug 2022 18:58:15 +0200 +Subject: [PATCH] multipathd: replace libreadline with libedit + +Linking multipathd with libreadline may cause a license conflict, +because libreadline is licensed under GPL-3.0-or-later, and +libmultipath contains several files under GPL-2.0. + +See: + https://github.com/opensvc/multipath-tools/issues/36 + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=979095 + https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility + +Replace the readline functionality with libedit, which comes under +a BSD license. The readline library can still be enabled (e.g. for +binaries not intended to be distributed) by running +"make READLINE=libreadline". + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 5 +++++ + multipathd/Makefile | 11 ++++++++++- + multipathd/cli.c | 5 +++++ + multipathd/uxclnt.c | 6 ++++++ + 4 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index bcd2212a..ad7afd04 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -8,6 +8,11 @@ + # + # Uncomment to disable dmevents polling support + # ENABLE_DMEVENTS_POLL = 0 ++# ++# Readline library to use, libedit or libreadline ++# Caution: Using libreadline may make the multipathd binary undistributable, ++# see https://github.com/opensvc/multipath-tools/issues/36 ++READLINE = libedit + + # List of scsi device handler modules to load on boot, e.g. + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac +diff --git a/multipathd/Makefile b/multipathd/Makefile +index c937cd55..95acd887 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -22,7 +22,16 @@ CFLAGS += $(BIN_CFLAGS) + LDFLAGS += $(BIN_LDFLAGS) + LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ + -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ +- -ldevmapper -lreadline ++ -ldevmapper ++ ++ifeq ($(READLINE),libedit) ++CPPFLAGS += -DUSE_LIBEDIT ++LIBDEPS += -ledit ++endif ++ifeq ($(READLINE),libreadline) ++CPPFLAGS += -DUSE_LIBREADLINE ++LIBDEPS += -lreadline ++endif + + ifdef SYSTEMD + CPPFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) +diff --git a/multipathd/cli.c b/multipathd/cli.c +index b2ee9a99..fa482a67 100644 +--- a/multipathd/cli.c ++++ b/multipathd/cli.c +@@ -11,7 +11,12 @@ + #include "parser.h" + #include "util.h" + #include "version.h" ++#ifdef USE_LIBEDIT ++#include ++#endif ++#ifdef USE_LIBREADLINE + #include ++#endif + + #include "mpath_cmd.h" + #include "cli.h" +diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c +index bdcc7c3f..251e7d75 100644 +--- a/multipathd/uxclnt.c ++++ b/multipathd/uxclnt.c +@@ -16,8 +16,14 @@ + #include + #include + #include ++ ++#ifdef USE_LIBEDIT ++#include ++#endif ++#ifdef USE_LIBREADLINE + #include + #include ++#endif + + #include "mpath_cmd.h" + #include "uxsock.h" diff --git a/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch b/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch new file mode 100644 index 0000000..f8085e8 --- /dev/null +++ b/0037-libmultipath-convert-license-of-strbuf-code-to-GPL-2.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 12 Aug 2022 21:25:37 +0200 +Subject: [PATCH] libmultipath: convert license of strbuf code to GPL-2.0+ + +This (partly) fixes the license incompatibility reported in +https://github.com/opensvc/multipath-tools/issues/36 + +As I'm the only author (except for a trivial spelling fix), +I see no issue with changing the license. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/strbuf.c | 2 +- + libmultipath/strbuf.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/strbuf.c b/libmultipath/strbuf.c +index f654594d..e23b65e8 100644 +--- a/libmultipath/strbuf.c ++++ b/libmultipath/strbuf.c +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2021 SUSE LLC +- * SPDX-License-Identifier: GPL-2.0-only ++ * SPDX-License-Identifier: GPL-2.0-or-later + */ + #include + #include +diff --git a/libmultipath/strbuf.h b/libmultipath/strbuf.h +index 31ab519a..ae863417 100644 +--- a/libmultipath/strbuf.h ++++ b/libmultipath/strbuf.h +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2021 SUSE LLC +- * SPDX-License-Identifier: GPL-2.0-only ++ * SPDX-License-Identifier: GPL-2.0-or-later + */ + #ifndef _STRBUF_H + #define _STRBUF_H diff --git a/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch b/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch new file mode 100644 index 0000000..375940f --- /dev/null +++ b/0038-github-workflows-build-and-unittest.yaml-add-libedit.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 14:10:39 +0200 +Subject: [PATCH] github workflows: build-and-unittest.yaml: add libedit-dev + +This is is required after switching from libreadline to libedit. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/build-and-unittest.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/.github/workflows/build-and-unittest.yaml b/.github/workflows/build-and-unittest.yaml +index 7ff45842..1ab0d36c 100644 +--- a/.github/workflows/build-and-unittest.yaml ++++ b/.github/workflows/build-and-unittest.yaml +@@ -27,7 +27,7 @@ jobs: + sudo apt-get install --yes gcc + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: build + run: make -O -j$(grep -c ^processor /proc/cpuinfo) + - name: test +@@ -55,7 +55,7 @@ jobs: + sudo apt-get install --yes gcc-10 + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: set CC + run: echo CC=gcc-10 >> $GITHUB_ENV + - name: build +@@ -85,7 +85,7 @@ jobs: + sudo apt-get install --yes clang + make perl-base pkg-config valgrind + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: set CC + run: echo CC=clang >> $GITHUB_ENV + - name: build diff --git a/0039-github-workflows-coverity.yaml-add-libedit-dev.patch b/0039-github-workflows-coverity.yaml-add-libedit-dev.patch new file mode 100644 index 0000000..63ef9dc --- /dev/null +++ b/0039-github-workflows-coverity.yaml-add-libedit-dev.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 14:10:39 +0200 +Subject: [PATCH] github workflows: coverity.yaml: add libedit-dev + +This is is required after switching from libreadline to libedit. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/coverity.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml +index a8b56d43..3c6b3824 100644 +--- a/.github/workflows/coverity.yaml ++++ b/.github/workflows/coverity.yaml +@@ -15,7 +15,7 @@ jobs: + sudo apt-get install --yes + gcc make pkg-config + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: download coverity + run: > + curl -o cov-analysis-linux64.tar.gz diff --git a/0040-github-workflows-abi.yaml-add-libedit-dev.patch b/0040-github-workflows-abi.yaml-add-libedit-dev.patch new file mode 100644 index 0000000..93e2331 --- /dev/null +++ b/0040-github-workflows-abi.yaml-add-libedit-dev.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 14:10:39 +0200 +Subject: [PATCH] github workflows: abi.yaml: add libedit-dev + +This is is required after switching from libreadline to libedit. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/abi.yaml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/abi.yaml b/.github/workflows/abi.yaml +index 0a40104a..89b971cd 100644 +--- a/.github/workflows/abi.yaml ++++ b/.github/workflows/abi.yaml +@@ -30,7 +30,7 @@ jobs: + sudo apt-get install --yes gcc + gcc make pkg-config abigail-tools + libdevmapper-dev libreadline-dev libaio-dev libsystemd-dev +- libudev-dev libjson-c-dev liburcu-dev libcmocka-dev ++ libudev-dev libjson-c-dev liburcu-dev libcmocka-dev libedit-dev + - name: create ABI + run: make -O -j$(grep -c ^processor /proc/cpuinfo) abi.tar.gz + - name: save ABI diff --git a/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch b/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch new file mode 100644 index 0000000..7fc05a6 --- /dev/null +++ b/0041-GitHub-workflows-native.yaml-add-libedit-dev-except-.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 16:52:07 +0200 +Subject: [PATCH] GitHub workflows: native.yaml: add libedit-dev, except for + jessie + +This is is required after switching from libreadline to libedit. + +On jessie, we can use libreadline5 (libreadline-gpl2-dev) without +license issues. Trying to compile against libedit results in an +"incompatible pointer type" error on jessie, because libedit +uses a different prototype for rl_completion_entry_function. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/native.yaml | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml +index ddfd4a09..8b599209 100644 +--- a/.github/workflows/native.yaml ++++ b/.github/workflows/native.yaml +@@ -22,13 +22,24 @@ jobs: + - name: checkout + uses: actions/checkout@v1 + - name: build and test ++ if: ${{ matrix.os != 'jessie' }} + run: make test ++ - name: build and test (jessie) ++ # On jessie, we use libreadline 5 (no licensing issue) ++ if: ${{ matrix.os == 'jessie' }} ++ run: make READLINE=libreadline test + - name: clean + run: make clean + - name: clang ++ if: ${{ matrix.os != 'jessie' }} + env: + CC: clang + run: make test ++ - name: clang (jessie) ++ if: ${{ matrix.os == 'jessie' }} ++ env: ++ CC: clang ++ run: make READLINE=libreadline test + + rolling: + runs-on: ubuntu-20.04 +@@ -56,12 +67,13 @@ jobs: + libjson-c-dev + liburcu-dev + libcmocka-dev ++ libedit-dev + - name: dependencies-alpine + if: ${{ matrix.os == 'alpine' }} + run: > + apk add make gcc clang cmocka + musl-dev lvm2-dev libaio-dev readline-dev ncurses-dev eudev-dev +- userspace-rcu-dev json-c-dev cmocka-dev ++ userspace-rcu-dev json-c-dev cmocka-dev libedit-dev + - name: dependencies-fedora + if: ${{ matrix.os == 'fedora:rawhide' }} + run: > +@@ -76,6 +88,7 @@ jobs: + userspace-rcu-devel + json-c-devel + libcmocka-devel ++ libedit-devel + - name: checkout + uses: actions/checkout@v1 + - name: build and test diff --git a/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch b/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch new file mode 100644 index 0000000..3af19df --- /dev/null +++ b/0042-GitHub-workflows-foreign.yaml-switch-to-Debian-11-bu.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Tue, 16 Aug 2022 23:38:18 +0200 +Subject: [PATCH] GitHub workflows: foreign.yaml: switch to Debian 11 + (bullseye) + +Building the containers in the build-multipath project recently +started failing for buster/s390x and buster/ppc64el. That failure +had nothing to do with the switch to libedit. + +It's about time to switch to bullseye anyway. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .github/workflows/foreign.yaml | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/.github/workflows/foreign.yaml b/.github/workflows/foreign.yaml +index 32915186..f6e69709 100644 +--- a/.github/workflows/foreign.yaml ++++ b/.github/workflows/foreign.yaml +@@ -13,7 +13,7 @@ jobs: + runs-on: ubuntu-20.04 + strategy: + matrix: +- os: [buster] ++ os: [bullseye] + arch: ['ppc64le', 'aarch64', 's390x'] + container: mwilck/multipath-build-${{ matrix.os }}-${{ matrix.arch }} + steps: +@@ -44,7 +44,7 @@ jobs: + needs: build + strategy: + matrix: +- os: [buster] ++ os: [bullseye] + arch: ['ppc64le', 'aarch64', 's390x'] + steps: + - name: get binaries diff --git a/0043-RH-fixup-udev-rules-for-redhat.patch b/0043-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..47a1ab2 --- /dev/null +++ b/0043-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,63 @@ +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/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/0044-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 77% rename from 0002-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0044-RH-Remove-the-property-blacklist-exception-builtin.patch index b8e580a..ded9aab 100644 --- a/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0044-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -1,4 +1,4 @@ -From f7be16ac9fce97585a4552d49f3d3c54a93c9c17 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 2 Jul 2014 12:49:53 -0500 Subject: [PATCH] RH: Remove the property blacklist exception builtin @@ -13,25 +13,26 @@ it. Signed-off-by: Benjamin Marzinski --- - libmultipath/blacklist.c | 5 ++--- - multipath/multipath.conf.5.in | 11 ++++++----- - tests/blacklist.c | 7 ++----- - 3 files changed, 10 insertions(+), 13 deletions(-) + libmultipath/blacklist.c | 6 ++---- + multipath/multipath.conf.5 | 11 ++++++----- + tests/blacklist.c | 7 ++----- + 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 17e1b54a..10d13e98 100644 +index 8d15d2ea..eff690fd 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -230,8 +230,6 @@ setup_default_blist (struct config * conf) - ORIGIN_DEFAULT)) - return 1; - } +@@ -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; + - 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) { -@@ -438,7 +436,8 @@ filter_property(const struct config *conf, struct udev_device *udev, + if (find_blacklist_device(conf->blist_device, +@@ -409,7 +406,8 @@ filter_property(const struct config *conf, struct udev_device *udev, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -41,11 +42,11 @@ index 17e1b54a..10d13e98 100644 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev)) { -diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in -index 3c9ae097..ba291e11 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -1470,9 +1470,14 @@ keywords. Both are regular expressions. For a full description of these keywords +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index acdd1ae6..5ab770ba 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1348,9 +1348,14 @@ keywords. Both are regular expressions. For a full description of these keywords 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 +62,7 @@ index 3c9ae097..ba291e11 100644 . .RS .PP -@@ -1483,10 +1488,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1361,10 +1366,6 @@ Blacklisting by missing properties is only applied to devices which do have the property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) set. Previously, it was applied to every device, possibly causing devices to be blacklisted because of temporary I/O error conditions. @@ -73,10 +74,10 @@ index 3c9ae097..ba291e11 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index ab3da619..52ae03e0 100644 +index 882aa3a1..6a22b660 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -371,9 +371,8 @@ static void test_property_missing(void **state) +@@ -375,9 +375,8 @@ static void test_property_missing(void **state) { static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; conf.blist_property = blist_property_wwn; @@ -87,7 +88,7 @@ index ab3da619..52ae03e0 100644 assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), MATCH_NOTHING); assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -465,9 +464,7 @@ static void test_filter_path_missing1(void **state) +@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state) conf.blist_device = blist_device_foo_bar; conf.blist_protocol = blist_protocol_fcp; conf.blist_wwid = blist_wwid_xyzzy; diff --git a/0045-RH-don-t-start-without-a-config-file.patch b/0045-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000..dda921b --- /dev/null +++ b/0045-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 15 Oct 2014 10:39:30 -0500 +Subject: [PATCH] RH: don't start without a config file + +If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist +all devices when running multipath. A completely blank configuration file +is almost never what users want. Also, people may have the multipath +packages installed but don't want to use them. This patch provides a +simple way to disable multipath. Simply removing or renaming +/etc/multipath.conf will keep multipath from doing anything. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 13 +++++++++++++ + libmultipath/config.h | 1 + + multipath/multipath.rules | 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 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -955,6 +955,19 @@ int _init_config (const char *file, struct config *conf) + } + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); + validate_pctable(conf->overrides, 0, file); ++ } else { ++ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ if (conf->blist_devnode == NULL) { ++ conf->blist_devnode = vector_alloc(); ++ if (!conf->blist_devnode) { ++ condlog(0, "cannot allocate blacklist\n"); ++ goto out; ++ } ++ } ++ if (store_ble(conf->blist_devnode, ".*", ORIGIN_NO_CONFIG)) { ++ condlog(0, "cannot store default no-config blacklist\n"); ++ goto out; ++ } + } + + conf->processed_main_config = 1; +diff --git a/libmultipath/config.h b/libmultipath/config.h +index fdcdff0a..affba937 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -9,6 +9,7 @@ + + #define ORIGIN_DEFAULT 0 + #define ORIGIN_CONFIG 1 ++#define ORIGIN_NO_CONFIG 2 + + 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 +@@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" + ENV{nompath}=="?*", GOTO="end_mpath" + IMPORT{cmdline}="multipath" + ENV{multipath}=="off", GOTO="end_mpath" ++TEST!="/etc/multipath.conf", GOTO="end_mpath" + + ENV{DEVTYPE}!="partition", GOTO="test_dev" + IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 +index 1e318bdc..6aab9325 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8 +@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. + This daemon executes the external \fBmultipath\fR tool when events occur. + In turn, the multipath tool signals the multipathd daemon when it is done with + devmap reconfiguration, so that it can refresh its failed path list. ++ ++In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index aec62dbb..d76f94f9 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket + After=systemd-udevd-kernel.socket + After=multipathd.socket systemd-remount-fs.service + Before=initrd-cleanup.service ++ConditionPathExists=/etc/multipath.conf + DefaultDependencies=no + Conflicts=shutdown.target + Conflicts=initrd-cleanup.service +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index c777e5e3..3c20a2ff 100644 +--- a/multipathd/multipathd.socket ++++ b/multipathd/multipathd.socket +@@ -1,6 +1,7 @@ + [Unit] + Description=multipathd control socket + DefaultDependencies=no ++ConditionPathExists=/etc/multipath.conf + ConditionKernelCommandLine=!nompath + ConditionKernelCommandLine=!multipath=off + ConditionVirtualization=!container diff --git a/0004-RH-Fix-nvme-function-missing-argument.patch b/0046-RH-Fix-nvme-function-missing-argument.patch similarity index 84% rename from 0004-RH-Fix-nvme-function-missing-argument.patch rename to 0046-RH-Fix-nvme-function-missing-argument.patch index 33a8d5f..ced7159 100644 --- a/0004-RH-Fix-nvme-function-missing-argument.patch +++ b/0046-RH-Fix-nvme-function-missing-argument.patch @@ -1,4 +1,4 @@ -From 283b5dd645663a2cf16f2813581772d7a84db6ad Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Jan 2019 14:54:56 -0600 Subject: [PATCH] RH: Fix nvme 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 b3caa7be..f91504c9 100644 +index adb192b6..bfd10ef8 100644 --- a/libmultipath/nvme/argconfig.h +++ b/libmultipath/nvme/argconfig.h -@@ -63,7 +63,7 @@ struct argconfig_commandline_options { +@@ -76,7 +76,7 @@ struct argconfig_commandline_options { extern "C" { #endif diff --git a/0047-RH-use-rpm-optflags-if-present.patch b/0047-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000..bd3b6e1 --- /dev/null +++ b/0047-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 19 Apr 2017 06:10:01 -0500 +Subject: [PATCH] RH: use rpm optflags if present + +Use the passed in optflags when compiling as an RPM, and keep the +default flags as close as possible to the current fedora flags, while +still being generic. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 03450610..2cf6e85f 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,) + +-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 ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ++ endif ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ++ endif ++else ++ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 ++endif ++WARNFLAGS := -Werror -Wextra -Wformat=2 $(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)\" -DRUN_DIR=\"${RUN}\" \ ++ $(WNOCLOBBERED) -Werror=cast-qual \ ++ $(ERROR_DISCARDED_QUALIFIERS) -Wstrict-prototypes ++CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ + -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs ++LDFLAGS := $(LDFLAGS) $(RPM_LD_FLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs + BIN_LDFLAGS = -pie + + # Check whether a function with name $1 has been declared in header file $2. diff --git a/0006-RH-add-mpathconf.patch b/0048-RH-add-mpathconf.patch similarity index 88% rename from 0006-RH-add-mpathconf.patch rename to 0048-RH-add-mpathconf.patch index 46f1126..ff2487f 100644 --- a/0006-RH-add-mpathconf.patch +++ b/0048-RH-add-mpathconf.patch @@ -1,4 +1,4 @@ -From 29e5c6d6e2177e73d1be2ed2af66c1007487bf60 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 16 Oct 2014 15:49:01 -0500 Subject: [PATCH] RH: add mpathconf @@ -10,47 +10,21 @@ 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 --- - .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(+) + libmultipath/config.c | 2 + + multipath/Makefile | 4 + + multipath/mpathconf | 658 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 151 ++++++++++ + 4 files changed, 815 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 -diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt -index a5856bcc..5c9113ba 100644 ---- a/.github/actions/spelling/expect.txt -+++ b/.github/actions/spelling/expect.txt -@@ -131,9 +131,11 @@ Marzinski - misdetection - mpath - mpathb -+mpathconf - mpathpersist - mpathvalid - msecs -+multipathable - multipathc - multipathd - multipathed -@@ -154,6 +156,7 @@ ontap - OOM - opensvc - OPTFLAGS -+outfile - paramp - partx - pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index b8317f4d..0bbaa981 100644 +index f06fcbf9..e2840839 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -939,6 +939,8 @@ int init_config__ (const char *file, struct config *conf) +@@ -957,6 +957,8 @@ int _init_config (const char *file, struct config *conf) validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -60,43 +34,39 @@ index b8317f4d..0bbaa981 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index 2ea9e528..3dc241cc 100644 +index d2b3fd82..00e46a0d 100644 --- a/multipath/Makefile +++ b/multipath/Makefile -@@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so +@@ -21,6 +21,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so 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) -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) -@@ -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 -+ $(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 - $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) -@@ -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 - $(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 + $(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) + 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 + clean: dep_clean + $(RM) core *.o $(EXEC) diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..ce430075 +index 00000000..319664b1 --- /dev/null +++ b/multipath/mpathconf @@ -0,0 +1,658 @@ @@ -133,7 +103,7 @@ index 00000000..ce430075 + +defaults { + user_friendly_names yes -+ find_multipaths on ++ find_multipaths yes +}" + +CONFIGFILE="/etc/multipath.conf" @@ -151,7 +121,7 @@ index 00000000..ce430075 + 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 on): --find_multipaths " ++ echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " + echo "Set recheck_wwid (Defaut n): --recheck_wwid " @@ -355,11 +325,11 @@ index 00000000..ce430075 + exit 1 + fi + if [ "$FIND" = "y" ]; then -+ FIND="on" ++ FIND="yes" + elif [ "$FIND" = "n" ]; then -+ 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'" ++ FIND="no" ++ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" + exit 1 + fi + if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then @@ -524,7 +494,7 @@ index 00000000..ce430075 + echo "multipath is disabled" + fi + if [ -z "$HAVE_FIND" ]; then -+ echo "find_multipaths is off" ++ echo "find_multipaths is no" + else + echo "find_multipaths is $HAVE_FIND" + fi @@ -760,7 +730,7 @@ index 00000000..ce430075 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..ec4e5c56 +index 00000000..9c2fb835 --- /dev/null +++ b/multipath/mpathconf.8 @@ -0,0 +1,151 @@ @@ -806,10 +776,10 @@ index 00000000..ec4e5c56 +.B user_friendly_names +set and +.B find_multipaths -+set to \fBon\fP. To disable these, use the ++set to \fByes\fP. To disable these, use the +.B --user_friendly_names n +and -+.B --find_multipaths off ++.B --find_multipaths n +options +.SH COMMANDS +.TP @@ -852,7 +822,7 @@ index 00000000..ec4e5c56 +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 { \fBon\fP | \fByes\fP | \fBy\fP | \fBoff\fP | \fBno\fP | \fBn\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } ++.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } +If set to \fB\fP, this adds the line +.B find_multipaths +to the @@ -902,7 +872,7 @@ index 00000000..ec4e5c56 +.B service multipathd stop +to stop the multipathd daemon on \fB--disable\fP, and +.B service multipathd reload -+to reconfigure multipathd on \fB--user_friendly_names\fP and ++to reconfigure multipathd on \fB--user_frindly_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/0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 75% rename from 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index cef8b56..fbf22db 100644 --- a/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0049-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -1,4 +1,4 @@ -From d6ad888bad3850bb0a342ebcdc9fd78773eb3b2a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 17 Oct 2014 11:20:34 -0500 Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A @@ -14,16 +14,16 @@ multipathd.service Signed-off-by: Benjamin Marzinski --- - multipath/main.c | 54 ++++++++++++++++++++++++++++++-- - multipath/multipath.8.in | 7 ++++- - multipathd/multipathd.service.in | 1 + + multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- + multipath/multipath.8 | 7 ++++- + multipathd/multipathd.service | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/multipath/main.c b/multipath/main.c -index 31012874..a667c2ee 100644 +index 034dd2f4..4c31820b 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -111,7 +111,7 @@ usage (char * progname) +@@ -120,7 +120,7 @@ usage (char * progname) fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); @@ -32,7 +32,7 @@ index 31012874..a667c2ee 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); -@@ -125,6 +125,8 @@ usage (char * progname) +@@ -134,6 +134,8 @@ usage (char * progname) " -f flush a multipath device map\n" " -F flush all multipath device maps\n" " -a add a device wwid to the wwids file\n" @@ -41,7 +41,7 @@ index 31012874..a667c2ee 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" -@@ -440,6 +442,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 31012874..a667c2ee 100644 static int configure (struct config *conf, enum mpath_cmds cmd, enum devtypes dev_type, char *devpath) -@@ -851,7 +897,7 @@ main (int argc, char *argv[]) +@@ -841,7 +887,7 @@ 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 ) { + while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { switch(arg) { case 'v': if (!isdigit(optarg[0])) { -@@ -922,6 +968,10 @@ main (int argc, char *argv[]) +@@ -912,6 +958,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -112,11 +112,11 @@ index 31012874..a667c2ee 100644 case 'h': usage(argv[0]); exit(RTVL_OK); -diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in -index b88e9a4c..edd742aa 100644 ---- a/multipath/multipath.8.in -+++ b/multipath/multipath.8.in -@@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig. +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 4c7e9885..1d062664 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. .B multipath .RB [\| \-v\ \c .IR level \|] @@ -125,7 +125,7 @@ index b88e9a4c..edd742aa 100644 . .LP .B multipath -@@ -146,6 +146,11 @@ device mapper, path checkers ...). +@@ -145,6 +145,11 @@ device mapper, path checkers ...). Add the WWID for the specified device to the WWIDs file. . .TP @@ -137,15 +137,15 @@ index b88e9a4c..edd742aa 100644 .B \-w Remove the WWID for the specified device from the WWIDs file. . -diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in -index ab166435..1ec08c6e 100644 ---- a/multipathd/multipathd.service.in -+++ b/multipathd/multipathd.service.in -@@ -19,6 +19,7 @@ StartLimitBurst=3 +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index d76f94f9..bb5f383a 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -17,6 +17,7 @@ ConditionVirtualization=!container [Service] Type=notify NotifyAccess=main -+ExecStartPre=-@BINDIR@/multipath -A - ExecStart=@BINDIR@/multipathd -d -s - ExecReload=@BINDIR@/multipathd reconfigure - Restart=on-failure ++ExecStartPre=-/sbin/multipath -A + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + TasksMax=infinity diff --git a/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/0050-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 52% rename from 0008-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0050-RH-reset-default-find_mutipaths-value-to-off.patch index fdc90d4..9b6b7bb 100644 --- a/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0050-RH-reset-default-find_mutipaths-value-to-off.patch @@ -1,4 +1,4 @@ -From 064d761121e7e2c7b63ab280e341d8010a413119 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 7 Jun 2018 17:43:52 -0500 Subject: [PATCH] RH: reset default find_mutipaths value to off @@ -6,18 +6,16 @@ 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 +- - multipath/multipath.conf.5.in | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) + libmultipath/defaults.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 134b690a..e2fe7ac4 100644 +index 7979f208..78b3d938 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -24,7 +24,7 @@ +@@ -23,7 +23,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 @@ -26,16 +24,3 @@ index 134b690a..e2fe7ac4 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 ba291e11..b8389db3 100644 ---- a/multipath/multipath.conf.5.in -+++ b/multipath/multipath.conf.5.in -@@ -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 --The default is: \fBstrict\fR -+The default is: \fBoff\fR - .RE - . - . diff --git a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 86% rename from 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 8065e9f..06233ff 100644 --- a/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0051-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -1,4 +1,4 @@ -From 335b8eb2773b07a602e84e14c1f3e289a9b25b5a Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 11 Apr 2019 13:25:42 -0500 Subject: [PATCH] RH: attempt to get ANA info via sysfs first @@ -13,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 34527b22..4eaa3cc3 100644 +index b5c7873d..e139360c 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c -@@ -23,6 +23,7 @@ +@@ -24,6 +24,7 @@ #include "prio.h" #include "util.h" #include "structs.h" @@ -24,7 +24,7 @@ index 34527b22..4eaa3cc3 100644 enum { ANA_ERR_GETCTRL_FAILED = 1, -@@ -35,6 +36,7 @@ enum { +@@ -36,6 +37,7 @@ enum { ANA_ERR_GETNS_FAILED, ANA_ERR_NO_MEMORY, ANA_ERR_NO_INFORMATION, @@ -32,7 +32,7 @@ index 34527b22..4eaa3cc3 100644 }; static const char *ana_errmsg[] = { -@@ -48,6 +50,7 @@ static const char *ana_errmsg[] = { +@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", [ANA_ERR_NO_MEMORY] = "out of memory", [ANA_ERR_NO_INFORMATION] = "invalid fd", @@ -40,7 +40,7 @@ index 34527b22..4eaa3cc3 100644 }; static const char *anas_string[] = { -@@ -106,6 +109,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, +@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, return -ANA_ERR_GETANAS_NOTFOUND; } @@ -68,7 +68,7 @@ index 34527b22..4eaa3cc3 100644 static int get_ana_info(struct path * pp) { int rc; -@@ -208,8 +232,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) +@@ -210,8 +234,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/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch similarity index 81% rename from 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch rename to 0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch index f7bca92..604ff75 100644 --- a/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ b/0052-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -1,4 +1,4 @@ -From 137c96d16b6bb03d8a52854e152db4ee36b7d9e4 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 25 Mar 2021 13:05:10 -0500 Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output @@ -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 31db8758..21cfcc73 100644 +index 15560f8c..2339c9a9 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c -@@ -1225,13 +1225,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1175,13 +1175,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, good_len = 8; break; case 2: @@ -33,7 +33,7 @@ index 31db8758..21cfcc73 100644 good_len = 8; break; default: -@@ -1249,10 +1245,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, +@@ -1199,10 +1195,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, break; case 0x8: /* SCSI Name: Prio 3 */ @@ -45,10 +45,10 @@ index 31db8758..21cfcc73 100644 case 0x1: /* T-10 Vendor ID: Prio 2 */ diff --git a/tests/vpd.c b/tests/vpd.c -index e3212e61..cdb111bb 100644 +index a7d2092c..2366cfba 100644 --- a/tests/vpd.c +++ b/tests/vpd.c -@@ -232,11 +232,13 @@ static const char * const str_prefix[] = { +@@ -231,11 +231,13 @@ static const char * const str_prefix[] = { [STR_IQN] = "iqn.", }; @@ -62,7 +62,7 @@ index e3212e61..cdb111bb 100644 /** * create_scsi_string_desc() - create a SCSI name string descriptor. -@@ -767,6 +769,7 @@ make_test_vpd_naa(2, 18); +@@ -766,6 +768,7 @@ make_test_vpd_naa(2, 18); make_test_vpd_naa(2, 17); make_test_vpd_naa(2, 16); @@ -70,7 +70,7 @@ index e3212e61..cdb111bb 100644 /* SCSI Name string: EUI64, WWID size: 17 */ make_test_vpd_str(0, 20, 18) make_test_vpd_str(0, 20, 17) -@@ -802,6 +805,7 @@ make_test_vpd_str(18, 20, 18) +@@ -801,6 +804,7 @@ make_test_vpd_str(18, 20, 18) make_test_vpd_str(18, 20, 17) make_test_vpd_str(18, 20, 16) make_test_vpd_str(18, 20, 15) @@ -78,7 +78,7 @@ index e3212e61..cdb111bb 100644 static int test_vpd(void) { -@@ -910,6 +914,7 @@ static int test_vpd(void) +@@ -909,6 +913,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_naa_2_18), cmocka_unit_test(test_vpd_naa_2_17), cmocka_unit_test(test_vpd_naa_2_16), @@ -86,7 +86,7 @@ index e3212e61..cdb111bb 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), -@@ -934,6 +939,7 @@ static int test_vpd(void) +@@ -933,6 +938,7 @@ static int test_vpd(void) cmocka_unit_test(test_vpd_str_18_20_17), cmocka_unit_test(test_vpd_str_18_20_16), cmocka_unit_test(test_vpd_str_18_20_15), diff --git a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch similarity index 85% rename from 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch rename to 0053-RH-add-scsi-device-handlers-to-modules-load.d.patch index 3fe7c25..423f107 100644 --- a/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +++ b/0053-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -1,4 +1,4 @@ -From 374755791536be4870ab2e93ae36549cbaaeb800 Mon Sep 17 00:00:00 2001 +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 25 Mar 2022 18:12:06 -0500 Subject: [PATCH] RH: add scsi device handlers to modules-load.d @@ -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 03aee175..936a622f 100644 +index 2cf6e85f..7277cf5f 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -16,7 +16,7 @@ READLINE := +@@ -16,7 +16,7 @@ READLINE = libedit # List of scsi device handler modules to load on boot, e.g. # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac diff --git a/0054-multipathd-ignore-duplicated-multipathd-command-keys.patch b/0054-multipathd-ignore-duplicated-multipathd-command-keys.patch new file mode 100644 index 0000000..e8bfe22 --- /dev/null +++ b/0054-multipathd-ignore-duplicated-multipathd-command-keys.patch @@ -0,0 +1,153 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 8 Sep 2022 11:54:49 -0500 +Subject: [PATCH] multipathd: ignore duplicated multipathd command keys + +multipath adds rather than or-s the values of command keys. Fix this. +Also, return an invalid fingerprint if a key is used more than once. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/cli.c | 8 +-- + multipathd/cli_handlers.c | 108 +++++++++++++++++++------------------- + 2 files changed, 59 insertions(+), 57 deletions(-) + +diff --git a/multipathd/cli.c b/multipathd/cli.c +index fa482a67..371da644 100644 +--- a/multipathd/cli.c ++++ b/multipathd/cli.c +@@ -333,9 +333,11 @@ fingerprint(const struct _vector *vec) + if (!vec) + return 0; + +- vector_foreach_slot(vec, kw, i) +- fp += kw->code; +- ++ vector_foreach_slot(vec, kw, i) { ++ if (fp & kw->code) ++ return (uint64_t)-1; ++ fp |= kw->code; ++ } + return fp; + } + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index db4d4412..cdf2a97e 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -1521,61 +1521,61 @@ static int cli_unset_all_marginal(void * v, struct strbuf *reply, void * data) + + void init_handler_callbacks(void) + { +- set_handler_callback(LIST+PATHS, cli_list_paths); +- set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt); +- set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw); +- set_handler_callback(LIST+PATH, cli_list_path); +- set_handler_callback(LIST+MAPS, cli_list_maps); +- set_handler_callback(LIST+STATUS, cli_list_status); +- set_unlocked_handler_callback(LIST+DAEMON, cli_list_daemon); +- set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status); +- set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats); +- set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt); +- set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw); +- set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology); +- set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology); +- set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json); +- set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology); +- set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt); +- set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt); +- set_handler_callback(LIST+MAP+JSON, cli_list_map_json); +- set_handler_callback(LIST+CONFIG+LOCAL, cli_list_config_local); +- set_handler_callback(LIST+CONFIG, cli_list_config); +- set_handler_callback(LIST+BLACKLIST, cli_list_blacklist); +- set_handler_callback(LIST+DEVICES, cli_list_devices); +- set_handler_callback(LIST+WILDCARDS, cli_list_wildcards); +- set_handler_callback(RESET+MAPS+STATS, cli_reset_maps_stats); +- set_handler_callback(RESET+MAP+STATS, cli_reset_map_stats); +- set_handler_callback(ADD+PATH, cli_add_path); +- set_handler_callback(DEL+PATH, cli_del_path); +- set_handler_callback(ADD+MAP, cli_add_map); +- set_handler_callback(DEL+MAP, cli_del_map); +- set_handler_callback(DEL+MAPS, cli_del_maps); +- set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group); ++ set_handler_callback(LIST|PATHS, cli_list_paths); ++ set_handler_callback(LIST|PATHS|FMT, cli_list_paths_fmt); ++ set_handler_callback(LIST|PATHS|RAW|FMT, cli_list_paths_raw); ++ set_handler_callback(LIST|PATH, cli_list_path); ++ set_handler_callback(LIST|MAPS, cli_list_maps); ++ set_handler_callback(LIST|STATUS, cli_list_status); ++ set_unlocked_handler_callback(LIST|DAEMON, cli_list_daemon); ++ set_handler_callback(LIST|MAPS|STATUS, cli_list_maps_status); ++ set_handler_callback(LIST|MAPS|STATS, cli_list_maps_stats); ++ set_handler_callback(LIST|MAPS|FMT, cli_list_maps_fmt); ++ set_handler_callback(LIST|MAPS|RAW|FMT, cli_list_maps_raw); ++ set_handler_callback(LIST|MAPS|TOPOLOGY, cli_list_maps_topology); ++ set_handler_callback(LIST|TOPOLOGY, cli_list_maps_topology); ++ set_handler_callback(LIST|MAPS|JSON, cli_list_maps_json); ++ set_handler_callback(LIST|MAP|TOPOLOGY, cli_list_map_topology); ++ set_handler_callback(LIST|MAP|FMT, cli_list_map_fmt); ++ set_handler_callback(LIST|MAP|RAW|FMT, cli_list_map_fmt); ++ set_handler_callback(LIST|MAP|JSON, cli_list_map_json); ++ set_handler_callback(LIST|CONFIG|LOCAL, cli_list_config_local); ++ set_handler_callback(LIST|CONFIG, cli_list_config); ++ set_handler_callback(LIST|BLACKLIST, cli_list_blacklist); ++ set_handler_callback(LIST|DEVICES, cli_list_devices); ++ set_handler_callback(LIST|WILDCARDS, cli_list_wildcards); ++ set_handler_callback(RESET|MAPS|STATS, cli_reset_maps_stats); ++ set_handler_callback(RESET|MAP|STATS, cli_reset_map_stats); ++ set_handler_callback(ADD|PATH, cli_add_path); ++ set_handler_callback(DEL|PATH, cli_del_path); ++ set_handler_callback(ADD|MAP, cli_add_map); ++ set_handler_callback(DEL|MAP, cli_del_map); ++ set_handler_callback(DEL|MAPS, cli_del_maps); ++ set_handler_callback(SWITCH|MAP|GROUP, cli_switch_group); + set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure); +- set_unlocked_handler_callback(RECONFIGURE+ALL, cli_reconfigure_all); +- set_handler_callback(SUSPEND+MAP, cli_suspend); +- set_handler_callback(RESUME+MAP, cli_resume); +- set_handler_callback(RESIZE+MAP, cli_resize); +- set_handler_callback(RELOAD+MAP, cli_reload); +- set_handler_callback(RESET+MAP, cli_reassign); +- set_handler_callback(REINSTATE+PATH, cli_reinstate); +- set_handler_callback(FAIL+PATH, cli_fail); +- set_handler_callback(DISABLEQ+MAP, cli_disable_queueing); +- set_handler_callback(RESTOREQ+MAP, cli_restore_queueing); +- set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing); +- set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing); ++ set_unlocked_handler_callback(RECONFIGURE|ALL, cli_reconfigure_all); ++ set_handler_callback(SUSPEND|MAP, cli_suspend); ++ set_handler_callback(RESUME|MAP, cli_resume); ++ set_handler_callback(RESIZE|MAP, cli_resize); ++ set_handler_callback(RELOAD|MAP, cli_reload); ++ set_handler_callback(RESET|MAP, cli_reassign); ++ set_handler_callback(REINSTATE|PATH, cli_reinstate); ++ set_handler_callback(FAIL|PATH, cli_fail); ++ set_handler_callback(DISABLEQ|MAP, cli_disable_queueing); ++ set_handler_callback(RESTOREQ|MAP, cli_restore_queueing); ++ set_handler_callback(DISABLEQ|MAPS, cli_disable_all_queueing); ++ set_handler_callback(RESTOREQ|MAPS, cli_restore_all_queueing); + set_unlocked_handler_callback(QUIT, cli_quit); + set_unlocked_handler_callback(SHUTDOWN, cli_shutdown); +- set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus); +- set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus); +- set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus); +- set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q); +- set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q); +- set_handler_callback(GETPRKEY+MAP, cli_getprkey); +- set_handler_callback(SETPRKEY+MAP+KEY, cli_setprkey); +- set_handler_callback(UNSETPRKEY+MAP, cli_unsetprkey); +- set_handler_callback(SETMARGINAL+PATH, cli_set_marginal); +- set_handler_callback(UNSETMARGINAL+PATH, cli_unset_marginal); +- set_handler_callback(UNSETMARGINAL+MAP, cli_unset_all_marginal); ++ set_handler_callback(GETPRSTATUS|MAP, cli_getprstatus); ++ set_handler_callback(SETPRSTATUS|MAP, cli_setprstatus); ++ set_handler_callback(UNSETPRSTATUS|MAP, cli_unsetprstatus); ++ set_handler_callback(FORCEQ|DAEMON, cli_force_no_daemon_q); ++ set_handler_callback(RESTOREQ|DAEMON, cli_restore_no_daemon_q); ++ set_handler_callback(GETPRKEY|MAP, cli_getprkey); ++ set_handler_callback(SETPRKEY|MAP|KEY, cli_setprkey); ++ set_handler_callback(UNSETPRKEY|MAP, cli_unsetprkey); ++ set_handler_callback(SETMARGINAL|PATH, cli_set_marginal); ++ set_handler_callback(UNSETMARGINAL|PATH, cli_unset_marginal); ++ set_handler_callback(UNSETMARGINAL|MAP, cli_unset_all_marginal); + } diff --git a/0055-multipath-tools-use-run-instead-of-dev-shm.patch b/0055-multipath-tools-use-run-instead-of-dev-shm.patch new file mode 100644 index 0000000..7d34f0d --- /dev/null +++ b/0055-multipath-tools-use-run-instead-of-dev-shm.patch @@ -0,0 +1,144 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Thu, 1 Sep 2022 19:21:30 +0200 +Subject: [PATCH] multipath-tools: use /run instead of /dev/shm + +/dev/shm may have unsafe permissions. Use /run instead. +Use systemd's tmpfiles.d mechanism to create /run/multipath +early during boot. + +For backward compatibilty, make the runtime directory configurable +via the "runtimedir" make variable. + +Signed-off-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + .gitignore | 2 ++ + Makefile.inc | 3 +++ + libmultipath/defaults.h | 2 +- + multipath/Makefile | 11 ++++++++--- + multipath/{multipath.rules => multipath.rules.in} | 4 ++-- + multipath/tmpfiles.conf.in | 1 + + 6 files changed, 17 insertions(+), 6 deletions(-) + rename multipath/{multipath.rules => multipath.rules.in} (96%) + create mode 100644 multipath/tmpfiles.conf.in + +diff --git a/.gitignore b/.gitignore +index 8e09f952..83bb68fe 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -12,6 +12,8 @@ cscope.files + cscope.out + kpartx/kpartx + multipath/multipath ++multipath/multipath.rules ++multipath/tmpfiles.conf + multipathd/multipathd + mpathpersist/mpathpersist + abi.tar.gz +diff --git a/Makefile.inc b/Makefile.inc +index 7277cf5f..3f8321ad 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -83,6 +83,7 @@ exec_prefix = $(prefix) + usr_prefix = $(prefix) + bindir = $(exec_prefix)/usr/sbin + libudevdir = $(prefix)/$(SYSTEMDPATH)/udev ++tmpfilesdir = $(prefix)/$(SYSTEMDPATH)/tmpfiles.d + udevrulesdir = $(libudevdir)/rules.d + modulesloaddir = $(prefix)/$(SYSTEMDPATH)/modules-load.d + multipathdir = $(TOPDIR)/libmultipath +@@ -103,6 +104,7 @@ includedir = $(prefix)/usr/include + pkgconfdir = $(usrlibdir)/pkgconfig + plugindir := $(prefix)/$(LIB)/multipath + configdir := $(prefix)/etc/multipath/conf.d ++runtimedir := /$(RUN) + + GZIP_PROG = gzip -9 -c + RM = rm -f +@@ -159,6 +161,7 @@ WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int + $(WNOCLOBBERED) -Werror=cast-qual \ + $(ERROR_DISCARDED_QUALIFIERS) -Wstrict-prototypes + CPPFLAGS := -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(plugindir)\" -DRUN_DIR=\"${RUN}\" \ ++ -DRUNTIME_DIR=\"$(runtimedir)\" \ + -DCONFIG_DIR=\"$(configdir)\" -DEXTRAVERSION=\"$(EXTRAVERSION)\" -MMD -MP + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + BIN_CFLAGS = -fPIE -DPIE +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 78b3d938..23107274 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -68,7 +68,7 @@ + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" + #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" + #define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" +-#define MULTIPATH_SHM_BASE "/dev/shm/multipath/" ++#define MULTIPATH_SHM_BASE RUNTIME_DIR "/multipath/" + + + static inline char *set_default(char *str) +diff --git a/multipath/Makefile b/multipath/Makefile +index 00e46a0d..e0a3b1b1 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -13,7 +13,7 @@ EXEC = multipath + + OBJS = main.o + +-all: $(EXEC) ++all: $(EXEC) multipath.rules tmpfiles.conf + + $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so + $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) +@@ -24,9 +24,11 @@ install: + $(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 ++ $(INSTALL_PROGRAM) -m 644 multipath.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)$(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) +@@ -50,9 +52,12 @@ uninstall: + $(RM) $(DESTDIR)$(man8dir)/mpathconf.8 + + clean: dep_clean +- $(RM) core *.o $(EXEC) ++ $(RM) core *.o $(EXEC) multipath.rules tmpfiles.conf + + include $(wildcard $(OBJS:.o=.d)) + + dep_clean: + $(RM) $(OBJS:.o=.d) ++ ++%: %.in ++ sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ +diff --git a/multipath/multipath.rules b/multipath/multipath.rules.in +similarity index 96% +rename from multipath/multipath.rules +rename to multipath/multipath.rules.in +index 68c30644..5c4447a2 100644 +--- a/multipath/multipath.rules ++++ b/multipath/multipath.rules.in +@@ -1,8 +1,8 @@ + # Set DM_MULTIPATH_DEVICE_PATH if the device should be handled by multipath + SUBSYSTEM!="block", GOTO="end_mpath" + KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath" +-ACTION=="remove", TEST=="/dev/shm/multipath/find_multipaths/$major:$minor", \ +- RUN+="/usr/bin/rm -f /dev/shm/multipath/find_multipaths/$major:$minor" ++ACTION=="remove", TEST=="@RUNTIME_DIR@/multipath/find_multipaths/$major:$minor", \ ++ RUN+="/usr/bin/rm -f @RUNTIME_DIR@/multipath/find_multipaths/$major:$minor" + ACTION!="add|change", GOTO="end_mpath" + + IMPORT{cmdline}="nompath" +diff --git a/multipath/tmpfiles.conf.in b/multipath/tmpfiles.conf.in +new file mode 100644 +index 00000000..21be438a +--- /dev/null ++++ b/multipath/tmpfiles.conf.in +@@ -0,0 +1 @@ ++d @RUNTIME_DIR@/multipath 0700 root root - diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 5d80d4e..fdf64c9 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,37 +1,78 @@ Name: device-mapper-multipath -Version: 0.13.0 -Release: 2%{?dist} +Version: 0.9.0 +Release: 4%{?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 +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.13.0.tar.gz -o multipath-tools-0.13.0.tgz -Source0: multipath-tools-0.13.0.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.0.tar.gz -o multipath-tools-0.9.0.tgz +Source0: multipath-tools-0.9.0.tgz Source1: multipath.conf -Patch0001: 0001-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-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 +Patch0054: 0054-multipathd-ignore-duplicated-multipathd-command-keys.patch +Patch0055: 0055-multipath-tools-use-run-instead-of-dev-shm.patch + # runtime Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu -Requires: readline -Requires: libmount +Requires: libedit Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -49,11 +90,10 @@ Conflicts: udisks2 < 2.8.0-2 # build/setup BuildRequires: libaio-devel, device-mapper-devel >= 1.02.89 BuildRequires: libselinux-devel, libsepol-devel -BuildRequires: readline-devel, ncurses-devel +BuildRequires: libedit-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel -BuildRequires: libmount-devel BuildRequires: make %description @@ -65,8 +105,8 @@ The tools are : %package libs Summary: The %{name} modules and shared library -# 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 +# only libmpathcmd is LGPLv2+ +License: GPLv2 and LGPLv2+ %description libs The %{name}-libs provides the path checker @@ -91,8 +131,7 @@ kpartx manages partition creation and removal for device-mapper devices. %package -n libdmmp Summary: device-mapper-multipath C API library -# Automatically converted from old format: GPLv3+ - review is highly recommended. -License: GPL-3.0-or-later +License: GPLv3+ Requires: json-c Requires: %{name} = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release} @@ -111,10 +150,11 @@ 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.13.0 -p1 +%autosetup -n multipath-tools-0.9.0 -p1 cp %{SOURCE1} . %build +%define _sbindir /usr/sbin %define _libdir /usr/%{_lib} %define _libmpathdir %{_libdir}/multipath %define _pkgconfdir %{_libdir}/pkgconfig @@ -125,8 +165,8 @@ cp %{SOURCE1} . bindir=%{_sbindir} \ syslibdir=%{_libdir} \ usrlibdir=%{_libdir} \ - plugindir=%{_libmpathdir} \ - mandir=%{_mandir} \ + libdir=%{_libmpathdir} \ + rcdir=%{_initrddir} \ unitdir=%{_unitdir} \ includedir=%{_includedir} \ pkgconfdir=%{_pkgconfdir} \ @@ -145,7 +185,7 @@ rm -rf %{buildroot}/%{_initrddir} %postun if [ $1 -ge 1 ] ; then - multipathd forcequeueing daemon > /dev/null 2>&1 || : + /sbin/multipathd forcequeueing daemon > /dev/null 2>&1 || : fi %systemd_postun_with_restart multipathd.service @@ -155,39 +195,33 @@ 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 LICENSES/GPL-3.0 +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 %{_sbindir}/multipath %{_sbindir}/multipathd -%{_sbindir}/multipathc %{_sbindir}/mpathconf -%{_sbindir}/mpathcleanup %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service -%{_unitdir}/multipathd-queueing.service %{_unitdir}/multipathd.socket -%{_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* +%{_mandir}/man5/multipath.conf.5.gz +%{_mandir}/man8/multipath.8.gz +%{_mandir}/man8/multipathd.8.gz +%{_mandir}/man8/mpathconf.8.gz +%{_mandir}/man8/mpathpersist.8.gz %config /usr/lib/udev/rules.d/62-multipath.rules %config /usr/lib/udev/rules.d/11-dm-mpath.rules -%config /usr/lib/udev/rules.d/99-z-dm-mpath-late.rules -%dir %{_modulesloaddir} -%{_modulesloaddir}/scsi_dh.conf +%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 LICENSES/LGPL-2.1 +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 %doc README.md %{_libdir}/libmultipath.so %{_libdir}/libmultipath.so.* -%{_libdir}/libmpathutil.so -%{_libdir}/libmpathutil.so.* %{_libdir}/libmpathpersist.so.* %{_libdir}/libmpathcmd.so.* %{_libdir}/libmpathvalid.so.* @@ -204,15 +238,15 @@ fi %{_includedir}/mpath_cmd.h %{_includedir}/mpath_persist.h %{_includedir}/mpath_valid.h -%{_mandir}/man3/mpath_persistent_reserve_in.3* -%{_mandir}/man3/mpath_persistent_reserve_out.3* +%{_mandir}/man3/mpath_persistent_reserve_in.3.gz +%{_mandir}/man3/mpath_persistent_reserve_out.3.gz %files -n kpartx %license LICENSES/GPL-2.0 %doc README.md %{_sbindir}/kpartx /usr/lib/udev/kpartx_id -%{_mandir}/man8/kpartx.8* +%{_mandir}/man8/kpartx.8.gz %config /usr/lib/udev/rules.d/11-dm-parts.rules %config /usr/lib/udev/rules.d/66-kpartx.rules %config /usr/lib/udev/rules.d/68-del-part-nodes.rules @@ -230,158 +264,16 @@ fi %dir %{_includedir}/libdmmp %{_includedir}/libdmmp/* %{_mandir}/man3/dmmp_* -%{_mandir}/man3/libdmmp.h.3* +%{_mandir}/man3/libdmmp.h.3.gz %{_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 -- 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 - -* 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). -- Rebase redhat patches - -* 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) - -* 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 - 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 - -* 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 - -* 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 - -* 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 - * 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 - -* 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 -- 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 - -* 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 - * 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 -- 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 - * 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 - -* 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 -- 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 included in the source tarball - * Patches 0001-0010 are from the upstream staging branch -- Rename redhat patches - * Previous patches 0033-0044 are now 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 - -* 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 +* Tue Oct 25 2022 Benjamin Marzinski - 0.9.0-4 +- Add 0054-multipathd-ignore-duplicated-multipathd-command-keys.patch + * Fixes bz #2137416 +- Add 0055-multipath-tools-use-run-instead-of-dev-shm.patch + * Fixes bz #2137414 +- Resolves: bz #2137414, #2137416 * Fri Aug 19 2022 Benjamin Marzinski - 0.9.0-3 - Update to the head of the upstream staging branch diff --git a/plans/multipath.fmf b/plans/multipath.fmf deleted file mode 100644 index 876c77a..0000000 --- a/plans/multipath.fmf +++ /dev/null @@ -1,58 +0,0 @@ -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/sources b/sources index 233c4ea..14c7342 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.13.0.tgz) = 75c84524ee27590b8b751ea500898a44e5ac3d58d55be6bcab919d0d423049db3a4466fcb9135705cf63ba074416973bb651255063269e9f682f11d21ba57e59 +SHA512 (multipath-tools-0.9.0.tgz) = 6c417f6d1d116fa43bedb9f77769ece9cbb7b35b78a9b3558c41df2360e52a65a07314b12ab7e4a7bbc867b9755250de9db96a2f7eb4a6a37f0b0b3f0bbc840e SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 diff --git a/.fmf/version b/tests/.fmf/version similarity index 100% rename from .fmf/version rename to tests/.fmf/version diff --git a/tests/bindings/main.sh b/tests/bindings/main.sh index 76292e4..2d6f284 100755 --- a/tests/bindings/main.sh +++ b/tests/bindings/main.sh @@ -18,110 +18,40 @@ # Author: Lin Li #set -x -source ../include/tc.sh || exit 200 +source ../include/ec.sh || exit 200 + tlog "running $0" -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" -} - -assert () -{ - local cmd="$*" - _trun_ "$cmd" 0 - if test $? -eq 0; then - tpass_ "$cmd" ; - else - tfail_ "$cmd" ; - cleanup ; - tend ; - fi -} - -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" +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 -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 ]]" +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 + +disk_path=$(get_scsi_debug_devices) +disk=$(basename $disk_path) +mpath_name=$(get_mpath_disk_by_scsi_device $disk) new_alias="mpath_test_$$" trun "sed -i 's/$mpath_name/$new_alias/' /etc/multipath/bindings" -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 -r" +sleep 5 +tok "[[ -b /dev/mapper/$new_alias ]]" +tok is_mpath $new_alias +sleep 5 -cleanup +trun "multipath -F" +sleep 5 +trun "modprobe -r scsi_debug" +trun "service multipathd stop" +sleep 3 +trun "multipath -W" +trun "rm /etc/multipath/bindings" tend diff --git a/tests/find_multipaths/Makefile b/tests/find_multipaths/Makefile new file mode 100644 index 0000000..b78dc57 --- /dev/null +++ b/tests/find_multipaths/Makefile @@ -0,0 +1,49 @@ +#!/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 28c325c..a39af79 100755 --- a/tests/find_multipaths/main.sh +++ b/tests/find_multipaths/main.sh @@ -18,92 +18,38 @@ # Author: Lin Li #set -x -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 -} +source ../include/ec.sh || exit 200 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 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" + trun "multipathd disablequeueing maps" + trun "service multipathd stop" + sleep 5 + trun "udevadm settle" + trun "multipath -F" + sleep 5 + trun "modprobe -r scsi_debug" } -assert () -{ - local cmd="$*" - _trun_ "$cmd" 0 - if test $? -eq 0; then - tpass_ "$cmd" ; - else - tfail_ "$cmd" ; - cleanup ; - tend ; - fi -} +tlog "running $0" -setup_config () -{ - trun "mpathconf --enable --user_friendly_names y --find_multipaths y" - sed -i '/^blacklist[[:space:]]*{/ a\ - device {\ - vendor ".*"\ - product ".*"\ - } +# 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 + +# 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 "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 - cat << _EOF_ >> /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 @@ -111,69 +57,56 @@ blacklist_exceptions { } } _EOF_ - 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 +fi +trun "service multipathd start" 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" -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' +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" # test find_multipaths=y create device for paths have same wwid -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]' ]]" +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" cleanup +trun "multipath -W" +cat /etc/multipath/wwids tend diff --git a/tests/include/ec.sh b/tests/include/ec.sh index 4b0aba9..22dfc40 100755 --- a/tests/include/ec.sh +++ b/tests/include/ec.sh @@ -44,12 +44,9 @@ function _init (){ } function _destroy (){ - Cmd "multipathd disablequeueing maps" + sleep 10 + Cmd "multipath -F" sleep 5 - Cmd "multipath -DF -R2" - Cmd "service multipathd stop" - sleep 5 - Cmd "udevadm settle" Cmd "modprobe -r scsi_debug" } @@ -177,7 +174,10 @@ AA fi #setup scsi_debug echo "INFO: Loading scsi_debug module for simulation of mpath" - modprobe scsi_debug vpd_use_hostno=0 add_host=2 + 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 echo "INFO: Waiting for udev to create /dev/sdX" sleep 15s #wait for udev to create /dev/sdX @@ -189,6 +189,8 @@ 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 35c6e6f..db2f008 100755 --- a/tests/medium_error_scsi_debug/main.sh +++ b/tests/medium_error_scsi_debug/main.sh @@ -16,51 +16,47 @@ # along with this program. If not, see . # Author: LiLin -source ../include/tc.sh || exit 200 -cleanup() +function cleanup() { sleep 5 udevadm settle - trun "multipath -DF" + multipath -F sleep 5 - trun "modprobe -r scsi_debug" + modprobe -r scsi_debug + + return 0 } -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" +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 sleep 5 -trun "multipath" +multipath > /dev/null sleep 5 -trun "multipath -l" mpathdev=`multipath -l | grep scsi_debug | awk '{print $1}' | head -1` -assert "[[ -n \"$mpathdev\" ]]" +if [ -z "$mpathdev" ]; then + echo "------- FAIL, no multipath device created -----" + cleanup + exit 1 +fi 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" ` -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 +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 diff --git a/tests/multipath_conf_syntax/main.sh b/tests/multipath_conf_syntax/main.sh index fb303c3..331d65e 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 in the multipath section: alia'" +tok "multipath 2>&1 | grep 'invalid keyword: alia'" trun "multipath -r" tok "multipath -ll | grep mpath" trun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" diff --git a/tests/provision.fmf b/tests/provision.fmf new file mode 100644 index 0000000..62a6eba --- /dev/null +++ b/tests/provision.fmf @@ -0,0 +1,5 @@ +--- + +standard-inventory-qcow2: + qemu: + m: 2G diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index be60eba..7f3279d 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -48,8 +48,10 @@ 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 --option max_polling_interval:10" -trun "mpathconf --option detect_pgpolicy_use_tpg:yes" +trun "mpathconf --enable --with_module y" +sed -i '/^defaults[[:space:]]*{/ a\ + max_polling_interval 10 +' /etc/multipath.conf trun "service multipathd stop" trun "multipath -F" sleep 5 @@ -67,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 %p" | grep ${mpathdev} | sort -k 3n | head -1 | awk '{print $1}'` +pathname=`multipathd show paths raw format "%d %m" | grep ${mpathdev} | head -1 | awk '{print $1}'` tlog "path to offline: ${pathname}" trun "echo 'offline' > /sys/block/${pathname}/device/state" tlog "waiting for multipathd to fail path" diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..15f26d2 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,44 @@ +--- +# 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 diff --git a/tests/user_friendly_names/main.sh b/tests/user_friendly_names/main.sh index 1d48801..56082fd 100755 --- a/tests/user_friendly_names/main.sh +++ b/tests/user_friendly_names/main.sh @@ -17,125 +17,50 @@ # Author: Lin Li -source ../include/tc.sh || exit 200 +source ../include/ec.sh || exit 200 + tlog "running $0" -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 "rpm -q device-mapper-multipath || yum install -y device-mapper-multipath" +trun "mpathconf --enable --with_multipathd y --user_friendly_names y" -assert () -{ - local cmd="$*" - _trun_ "$cmd" 0 - if test $? -eq 0; then - tpass_ "$cmd" ; - else - tfail_ "$cmd" ; - cleanup ; - tend ; - fi -} +# backup the /etc/multipath.conf +trun "cp /etc/multipath.conf /etc/multipath.conf.$$" +trun "multipath -F" -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 +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 -blacklist_exceptions { - device { - vendor Linux - product scsi_debug - } -} +disk=$(get_scsi_debug_devices) +disk=$(basename $disk) +wwid=$(get_wwid_of_disk $disk) +mpath=$(get_mpath_disk_by_scsi_device $disk) -multipaths { - multipath { - wwid TEST_WWID - alias test - } -} -_EOF_ - trun "cat /etc/multipath.conf" -} +# 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\"" -do_reconfigure () -{ - trun "cat /etc/multipath.conf" - tok "multipathd reconfigure" - sleep 5 -} +# 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" -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 +trun "cp /etc/multipath.conf.$$ /etc/multipath.conf" +trun "multipath -F; multipath" tend diff --git a/tests/user_friendly_names/multipath.conf.no b/tests/user_friendly_names/multipath.conf.no new file mode 100644 index 0000000..b916bfb --- /dev/null +++ b/tests/user_friendly_names/multipath.conf.no @@ -0,0 +1,3 @@ +defaults { + user_friendly_names no +} diff --git a/tests/user_friendly_names/multipath.conf.yes b/tests/user_friendly_names/multipath.conf.yes new file mode 100644 index 0000000..ffc21bb --- /dev/null +++ b/tests/user_friendly_names/multipath.conf.yes @@ -0,0 +1,11 @@ +defaults { + user_friendly_names yes +} + +multipaths { + multipath { + wwid your_wwid + alias test + } +} +