import device-mapper-multipath-0.8.6-7.el9
This commit is contained in:
commit
9ddf9f007a
1
.device-mapper-multipath.metadata
Normal file
1
.device-mapper-multipath.metadata
Normal file
@ -0,0 +1 @@
|
||||
a8afc76e75aeaba7e21c066ca95e236be3bfc5b4 SOURCES/multipath-tools-0.8.6.tgz
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SOURCES/multipath-tools-0.8.6.tgz
|
63
SOURCES/0001-RH-fixup-udev-rules-for-redhat.patch
Normal file
63
SOURCES/0001-RH-fixup-udev-rules-for-redhat.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
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 f1e23131..c593fd3b 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -55,7 +55,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
|
||||
multipathdir = $(TOPDIR)/libmultipath
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index d7527d7d..0e0d70d5 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
+++ b/kpartx/kpartx.rules
|
||||
@@ -36,6 +36,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 0828a8f7..b9bbb3cf 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -24,7 +24,7 @@ install:
|
||||
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||
- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules
|
||||
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir)
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir)
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||
@@ -33,7 +33,7 @@ install:
|
||||
uninstall:
|
||||
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||
$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||
- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules
|
||||
+ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||
|
@ -0,0 +1,101 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 2 Jul 2014 12:49:53 -0500
|
||||
Subject: [PATCH] RH: Remove the property blacklist exception builtin
|
||||
|
||||
Multipath set the default property blacklist exceptions to
|
||||
(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal
|
||||
devices. These devices may never have multiple paths, but it is nice
|
||||
to be able to set multipath up on them all the same. This patch simply
|
||||
removes the default, and makes it so that if no property
|
||||
blacklist_exception is given, then devices aren't failed for not matching
|
||||
it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 6c6a5979..785f5ee9 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf)
|
||||
if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT))
|
||||
return 1;
|
||||
|
||||
- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT))
|
||||
- return 1;
|
||||
-
|
||||
vector_foreach_slot (conf->hwtable, hwe, i) {
|
||||
if (hwe->bl_product) {
|
||||
if (find_blacklist_device(conf->blist_device,
|
||||
@@ -407,7 +404,8 @@ filter_property(const struct config *conf, struct udev_device *udev,
|
||||
*uid_attribute != '\0';
|
||||
bool uid_attr_seen = false;
|
||||
|
||||
- r = MATCH_PROPERTY_BLIST_MISSING;
|
||||
+ if (VECTOR_SIZE(conf->elist_property))
|
||||
+ r = MATCH_PROPERTY_BLIST_MISSING;
|
||||
udev_list_entry_foreach(list_entry,
|
||||
udev_device_get_properties_list_entry(udev)) {
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 064e4826..0d2bce09 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1347,9 +1347,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
Regular expression for an udev property. All
|
||||
devices that have matching udev properties will be excluded/included.
|
||||
The handling of the \fIproperty\fR keyword is special,
|
||||
-because devices \fBmust\fR have at least one whitelisted udev property;
|
||||
+because if a property blacklist_exception is set, devices \fBmust\fR have at
|
||||
+least one whitelisted udev property;
|
||||
otherwise they're treated as blacklisted, and the message
|
||||
"\fIblacklisted, udev property missing\fR" is displayed in the logs.
|
||||
+For example, setting the property blacklist_exception to
|
||||
+\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices
|
||||
+that provide a WWN (World Wide Number) to be included, and all others to be
|
||||
+excluded. This works to exclude most non-multipathable devices.
|
||||
.
|
||||
.RS
|
||||
.PP
|
||||
@@ -1360,10 +1365,6 @@ Blacklisting by missing properties is only applied to devices which do have the
|
||||
property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR)
|
||||
set. Previously, it was applied to every device, possibly causing devices to be
|
||||
blacklisted because of temporary I/O error conditions.
|
||||
-.PP
|
||||
-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing
|
||||
-well-behaved SCSI devices and devices that provide a WWN (World Wide Number)
|
||||
-to be included, and all others to be excluded.
|
||||
.RE
|
||||
.TP
|
||||
.B protocol
|
||||
diff --git a/tests/blacklist.c b/tests/blacklist.c
|
||||
index 882aa3a1..6a22b660 100644
|
||||
--- a/tests/blacklist.c
|
||||
+++ b/tests/blacklist.c
|
||||
@@ -375,9 +375,8 @@ static void test_property_missing(void **state)
|
||||
{
|
||||
static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } };
|
||||
conf.blist_property = blist_property_wwn;
|
||||
- expect_condlog(3, "sdb: blacklisted, udev property missing\n");
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
- MATCH_PROPERTY_BLIST_MISSING);
|
||||
+ MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"),
|
||||
MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, ""),
|
||||
@@ -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;
|
||||
- expect_condlog(3, "sdb: blacklisted, udev property missing\n");
|
||||
- assert_int_equal(filter_path(&conf, &miss1_pp),
|
||||
- MATCH_PROPERTY_BLIST_MISSING);
|
||||
+ assert_int_equal(filter_path(&conf, &miss1_pp), MATCH_NOTHING);
|
||||
}
|
||||
|
||||
/* This one matches the property whitelist, to test the other missing
|
94
SOURCES/0003-RH-don-t-start-without-a-config-file.patch
Normal file
94
SOURCES/0003-RH-don-t-start-without-a-config-file.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 13 +++++++++++++
|
||||
libmultipath/config.h | 1 +
|
||||
multipath/multipath.rules | 1 +
|
||||
multipathd/multipathd.8 | 2 ++
|
||||
multipathd/multipathd.service | 1 +
|
||||
5 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 30046a17..5f35c3d3 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -895,6 +895,19 @@ int _init_config (const char *file, struct config *conf)
|
||||
goto out;
|
||||
}
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
+ } else {
|
||||
+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||
+ if (conf->blist_devnode == NULL) {
|
||||
+ 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 933fe0d1..5f01c1fc 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 9df11a95..0486bf70 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 048a838d..8bd47a80 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 7d547fa7..af592057 100644
|
||||
--- a/multipathd/multipathd.service
|
||||
+++ b/multipathd/multipathd.service
|
||||
@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service
|
||||
Before=iscsi.service iscsid.service lvm2-activation-early.service
|
||||
Before=local-fs-pre.target blk-availability.service shutdown.target
|
||||
After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service
|
||||
+ConditionPathExists=/etc/multipath.conf
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
ConditionKernelCommandLine=!nompath
|
26
SOURCES/0004-RH-Fix-nvme-function-missing-argument.patch
Normal file
26
SOURCES/0004-RH-Fix-nvme-function-missing-argument.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 25 Jan 2019 14:54:56 -0600
|
||||
Subject: [PATCH] RH: Fix nvme function missing argument
|
||||
|
||||
A future patch will change the compilation options to error when
|
||||
function declarations have unspecified arguments.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/nvme/argconfig.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h
|
||||
index adb192b6..bfd10ef8 100644
|
||||
--- a/libmultipath/nvme/argconfig.h
|
||||
+++ b/libmultipath/nvme/argconfig.h
|
||||
@@ -76,7 +76,7 @@ struct argconfig_commandline_options {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-typedef void argconfig_help_func();
|
||||
+typedef void argconfig_help_func(void);
|
||||
void argconfig_append_usage(const char *str);
|
||||
void argconfig_print_help(const char *program_desc,
|
||||
const struct argconfig_commandline_options *options);
|
57
SOURCES/0005-RH-use-rpm-optflags-if-present.patch
Normal file
57
SOURCES/0005-RH-use-rpm-optflags-if-present.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 24 ++++++++++++++++++------
|
||||
1 file changed, 18 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index c593fd3b..87fb39f2 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -92,15 +92,27 @@ TEST_CC_OPTION = $(shell \
|
||||
echo "$(2)"; \
|
||||
fi)
|
||||
|
||||
-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||
WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)
|
||||
|
||||
-OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4
|
||||
-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
+ifndef RPM_OPT_FLAGS
|
||||
+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
+ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \
|
||||
+ $(STACKPROT) -grecord-gcc-switches \
|
||||
+ -fasynchronous-unwind-tables --param=ssp-buffer-size=4
|
||||
+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1)
|
||||
+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
|
||||
+ endif
|
||||
+ 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 -Werror=implicit-int \
|
||||
-Werror=implicit-function-declaration -Werror=format-security \
|
||||
- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS)
|
||||
-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2
|
||||
+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
+ -Wstrict-prototypes
|
||||
CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \
|
||||
-DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||
-MMD -MP
|
||||
@@ -138,4 +150,4 @@ check_file = $(shell \
|
||||
|
||||
%.o: %.c
|
||||
@echo building $@ because of $?
|
||||
- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
+ $(CC) $(CFLAGS) -c -o $@ $<
|
771
SOURCES/0006-RH-add-mpathconf.patch
Normal file
771
SOURCES/0006-RH-add-mpathconf.patch
Normal file
@ -0,0 +1,771 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 Oct 2014 15:49:01 -0500
|
||||
Subject: [PATCH] RH: add mpathconf
|
||||
|
||||
mpathconf is a program (largely based on lvmcomf) to help users
|
||||
configure /etc/multipath.conf and enable or disable multipathing. It
|
||||
has a couple of built-in options that can be set directly from the
|
||||
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.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 2 +
|
||||
multipath/Makefile | 5 +
|
||||
multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf.8 | 135 ++++++++++
|
||||
4 files changed, 697 insertions(+)
|
||||
create mode 100644 multipath/mpathconf
|
||||
create mode 100644 multipath/mpathconf.8
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 5f35c3d3..cee3bbb7 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -897,6 +897,8 @@ int _init_config (const char *file, struct config *conf)
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
} else {
|
||||
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||
+ condlog(0, "You can run \"/sbin/mpathconf --enable\" to create");
|
||||
+ condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details");
|
||||
if (conf->blist_devnode == NULL) {
|
||||
conf->blist_devnode = vector_alloc();
|
||||
if (!conf->blist_devnode) {
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index b9bbb3cf..e720c7f6 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS)
|
||||
$(GZIP) $(EXEC).8 > $(EXEC).8.gz
|
||||
$(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
|
||||
+ $(GZIP) mpathconf.8 > mpathconf.8.gz
|
||||
|
||||
install:
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||
$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
@@ -29,13 +31,16 @@ install:
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir)
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
|
||||
+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir)
|
||||
|
||||
uninstall:
|
||||
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||
$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||
$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
+ $(RM) $(DESTDIR)$(bindir)/mpathconf
|
||||
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||
+ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz
|
||||
|
||||
clean: dep_clean
|
||||
$(RM) core *.o $(EXEC) *.gz
|
||||
diff --git a/multipath/mpathconf b/multipath/mpathconf
|
||||
new file mode 100644
|
||||
index 00000000..2f4f3eaf
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf
|
||||
@@ -0,0 +1,555 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2010 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
|
||||
+
|
||||
+#
|
||||
+# Simple editting of /etc/multipath.conf
|
||||
+# This program was largely ripped off from lvmconf
|
||||
+#
|
||||
+
|
||||
+unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST
|
||||
+
|
||||
+DEFAULT_CONFIG="# device-mapper-multipath configuration file
|
||||
+
|
||||
+# For a complete list of the default configuration values, run either:
|
||||
+# # multipath -t
|
||||
+# or
|
||||
+# # multipathd show config
|
||||
+
|
||||
+# For a list of configuration options with descriptions, see the
|
||||
+# multipath.conf man page.
|
||||
+
|
||||
+defaults {
|
||||
+ user_friendly_names yes
|
||||
+ find_multipaths yes
|
||||
+ enable_foreign \"^$\"
|
||||
+}
|
||||
+
|
||||
+blacklist_exceptions {
|
||||
+ property \"(SCSI_IDENT_|ID_WWN)\"
|
||||
+}"
|
||||
+
|
||||
+CONFIGFILE="/etc/multipath.conf"
|
||||
+OUTPUTFILE="/etc/multipath.conf"
|
||||
+MULTIPATHDIR="/etc/multipath"
|
||||
+TMPFILE="/etc/multipath/.multipath.conf.tmp"
|
||||
+WWIDS=0
|
||||
+
|
||||
+function usage
|
||||
+{
|
||||
+ echo "usage: $0 <command>"
|
||||
+ echo ""
|
||||
+ echo "Commands:"
|
||||
+ echo "Enable: --enable "
|
||||
+ echo "Disable: --disable"
|
||||
+ echo "Only allow certain wwids (instead of enable): --allow <WWID>"
|
||||
+ echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>"
|
||||
+ echo "Set find_multipaths (Default y): --find_multipaths <yes|no|strict|greedy|smart>"
|
||||
+ echo "Set default property blacklist (Default y): --property_blacklist <y|n>"
|
||||
+ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign <y|n>"
|
||||
+ echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
|
||||
+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
|
||||
+ echo "select output file (Default /etc/multipath.conf): --outfile <FILE>"
|
||||
+ echo ""
|
||||
+}
|
||||
+
|
||||
+function add_wwid
|
||||
+{
|
||||
+ INDEX=0
|
||||
+ while [ "$INDEX" -lt "$WWIDS" ] ; do
|
||||
+ if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then
|
||||
+ return
|
||||
+ fi
|
||||
+ ((INDEX++))
|
||||
+ done
|
||||
+ WWID_LIST[$WWIDS]="$1"
|
||||
+ ((WWIDS++))
|
||||
+}
|
||||
+
|
||||
+function get_dm_deps
|
||||
+{
|
||||
+ shift 3
|
||||
+ while [ -n "$1" -a -n "$2" ]; do
|
||||
+ MAJOR=$(echo $1 | tr -d '(,')
|
||||
+ MINOR=$(echo $2 | tr -d ')')
|
||||
+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null`
|
||||
+ if [ -n "$UUID" ] ; then
|
||||
+ set_dm_wwid $UUID
|
||||
+ fi
|
||||
+ shift 2
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function set_dm_wwid
|
||||
+{
|
||||
+ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then
|
||||
+ add_wwid "${1##part*-mpath-}"
|
||||
+ elif [[ "$1" =~ ^mpath- ]] ; then
|
||||
+ add_wwid "${1##mpath-}"
|
||||
+ else
|
||||
+ get_dm_deps `dmsetup deps -u $1`
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function set_wwid
|
||||
+{
|
||||
+ UUID=""
|
||||
+ if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then
|
||||
+ MAJOR=${1%%:*}
|
||||
+ MINOR=${1##*:}
|
||||
+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null`
|
||||
+ else
|
||||
+ UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null`
|
||||
+ fi
|
||||
+ if [ -n "$UUID" ] ; then
|
||||
+ set_dm_wwid $UUID
|
||||
+ else
|
||||
+ add_wwid "$1"
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function parse_args
|
||||
+{
|
||||
+ while [ -n "$1" ]; do
|
||||
+ case $1 in
|
||||
+ --enable)
|
||||
+ ENABLE=1
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --disable)
|
||||
+ ENABLE=0
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --allow)
|
||||
+ ENABLE=2
|
||||
+ if [ -n "$2" ]; then
|
||||
+ set_wwid $2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --user_friendly_names)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ FRIENDLY=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --find_multipaths)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ FIND=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --property_blacklist)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ PROPERTY=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --enable_foreign)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ FOREIGN=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --with_module)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ MODULE=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --with_multipathd)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ MULTIPATHD=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --outfile)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ OUTPUTFILE=$2
|
||||
+ HAVE_OUTFILE=1
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ *)
|
||||
+ usage
|
||||
+ exit
|
||||
+ esac
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function validate_args
|
||||
+{
|
||||
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then
|
||||
+ echo "ignoring extra parameters on disable"
|
||||
+ FRIENDLY=""
|
||||
+ FIND=""
|
||||
+ PROPERTY=""
|
||||
+ MODULE=""
|
||||
+ fi
|
||||
+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
|
||||
+ echo "--user_friendly_names must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ "$FIND" = "y" ]; then
|
||||
+ FIND="yes"
|
||||
+ elif [ "$FIND" = "n" ]; then
|
||||
+ FIND="no"
|
||||
+ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then
|
||||
+ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then
|
||||
+ echo "--property_blacklist must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then
|
||||
+ echo "--enable_foreign must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then
|
||||
+ SHOW_STATUS=1
|
||||
+ fi
|
||||
+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
|
||||
+ echo "--with_module must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then
|
||||
+ echo "--with_multipathd must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then
|
||||
+ echo "Because --allow makes changes that cannot be automatically reversed,"
|
||||
+ echo "you must set --outfile when you set --allow"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function add_blacklist_exceptions
|
||||
+{
|
||||
+ INDEX=0
|
||||
+ while [ "$INDEX" -lt "$WWIDS" ] ; do
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\
|
||||
+ wwid '"\"${WWID_LIST[$INDEX]}\""'
|
||||
+' $TMPFILE
|
||||
+ ((INDEX++))
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+umask 0077
|
||||
+
|
||||
+parse_args "$@"
|
||||
+
|
||||
+validate_args
|
||||
+
|
||||
+if [ ! -d "$MULTIPATHDIR" ]; then
|
||||
+ echo "/etc/multipath/ does not exist. failing"
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+rm $TMPFILE 2> /dev/null
|
||||
+echo "$DEFAULT_CONFIG" > $TMPFILE
|
||||
+if [ -f "$CONFIGFILE" ]; then
|
||||
+ cp $CONFIGFILE $TMPFILE
|
||||
+fi
|
||||
+
|
||||
+if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
|
||||
+ HAVE_BLACKLIST=1
|
||||
+fi
|
||||
+
|
||||
+if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then
|
||||
+ HAVE_EXCEPTIONS=1
|
||||
+fi
|
||||
+
|
||||
+if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then
|
||||
+ HAVE_DEFAULTS=1
|
||||
+fi
|
||||
+
|
||||
+if [ -z "$MODULE" -o "$MODULE" = "y" ]; then
|
||||
+ if lsmod | grep -q "dm_multipath" ; then
|
||||
+ HAVE_MODULE=1
|
||||
+ else
|
||||
+ HAVE_MODULE=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$MULTIPATHD" = "y" ]; then
|
||||
+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
|
||||
+ HAVE_MULTIPATHD=1
|
||||
+ else
|
||||
+ HAVE_MULTIPATHD=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ HAVE_DISABLE=1
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ HAVE_DISABLE=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ HAVE_WWID_DISABLE=1
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ HAVE_WWID_DISABLE=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_DEFAULTS" = "1" ]; then
|
||||
+ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p`
|
||||
+ if [ "$HAVE_FIND" = "1" ]; then
|
||||
+ HAVE_FIND="yes"
|
||||
+ elif [ "$HAVE_FIND" = "0" ]; then
|
||||
+ HAVE_FIND="no"
|
||||
+ fi
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
|
||||
+ HAVE_FRIENDLY=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
|
||||
+ HAVE_FRIENDLY=0
|
||||
+ fi
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then
|
||||
+ HAVE_FOREIGN=0
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then
|
||||
+ HAVE_FOREIGN=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then
|
||||
+ HAVE_FOREIGN=2
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_EXCEPTIONS" = "1" ]; then
|
||||
+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ HAVE_PROPERTY=1
|
||||
+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ HAVE_PROPERTY=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -n "$SHOW_STATUS" ]; then
|
||||
+ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
|
||||
+ echo "multipath is enabled"
|
||||
+ else
|
||||
+ echo "multipath is disabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FIND" ]; then
|
||||
+ echo "find_multipaths is no"
|
||||
+ else
|
||||
+ echo "find_multipaths is $HAVE_FIND"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
|
||||
+ echo "user_friendly_names is disabled"
|
||||
+ else
|
||||
+ echo "user_friendly_names is enabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then
|
||||
+ echo "default property blacklist is disabled"
|
||||
+ else
|
||||
+ echo "default property blacklist is enabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then
|
||||
+ echo "enable_foreign is not set (all foreign multipath devices will be shown)"
|
||||
+ elif [ "$HAVE_FOREIGN" = 1 ]; then
|
||||
+ echo "enable_foreign is set (no foreign multipath devices will be shown)"
|
||||
+ else
|
||||
+ echo "enable_foreign is set (foreign multipath devices may not be shown)"
|
||||
+ fi
|
||||
+ if [ -n "$HAVE_MODULE" ]; then
|
||||
+ if [ "$HAVE_MODULE" = 1 ]; then
|
||||
+ echo "dm_multipath module is loaded"
|
||||
+ else
|
||||
+ echo "dm_multipath module is not loaded"
|
||||
+ fi
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_MULTIPATHD" ]; then
|
||||
+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
|
||||
+ HAVE_MULTIPATHD=1
|
||||
+ else
|
||||
+ HAVE_MULTIPATHD=0
|
||||
+ fi
|
||||
+ fi
|
||||
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
|
||||
+ echo "multipathd is running"
|
||||
+ else
|
||||
+ echo "multipathd is not running"
|
||||
+ fi
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+if [ -z "$HAVE_BLACKLIST" ]; then
|
||||
+ cat >> $TMPFILE <<- _EOF_
|
||||
+
|
||||
+blacklist {
|
||||
+}
|
||||
+_EOF_
|
||||
+fi
|
||||
+
|
||||
+if [ -z "$HAVE_DEFAULTS" ]; then
|
||||
+ cat >> $TMPFILE <<- _EOF_
|
||||
+
|
||||
+defaults {
|
||||
+}
|
||||
+_EOF_
|
||||
+fi
|
||||
+
|
||||
+if [ "$ENABLE" = 2 ]; then
|
||||
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_WWID_DISABLE" ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/ a\
|
||||
+ wwid ".*"
|
||||
+' $TMPFILE
|
||||
+ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+ if [ "$HAVE_EXCEPTIONS" = 1 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE
|
||||
+ else
|
||||
+ cat >> $TMPFILE <<- _EOF_
|
||||
+
|
||||
+blacklist_exceptions {
|
||||
+}
|
||||
+_EOF_
|
||||
+ fi
|
||||
+ add_blacklist_exceptions
|
||||
+elif [ "$ENABLE" = 1 ]; then
|
||||
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+elif [ "$ENABLE" = 0 ]; then
|
||||
+ if [ -z "$HAVE_DISABLE" ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/ a\
|
||||
+ devnode ".*"
|
||||
+' $TMPFILE
|
||||
+ elif [ "$HAVE_DISABLE" = 0 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -n "$FIND" ]; then
|
||||
+ if [ -z "$HAVE_FIND" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ find_multipaths '"$FIND"'
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$FIND" != "$HAVE_FIND" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$FRIENDLY" = "n" ]; then
|
||||
+ if [ "$HAVE_FRIENDLY" = 1 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FRIENDLY" = "y" ]; then
|
||||
+ if [ -z "$HAVE_FRIENDLY" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ user_friendly_names yes
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FRIENDLY" = 0 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$PROPERTY" = "n" ]; then
|
||||
+ if [ "$HAVE_PROPERTY" = 1 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$PROPERTY" = "y" ]; then
|
||||
+ if [ -z "$HAVE_PROPERTY" ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\
|
||||
+ property "(SCSI_IDENT_|ID_WWN)"
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_PROPERTY" = 0 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$FOREIGN" = "y" ]; then
|
||||
+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FOREIGN" = "n" ]; then
|
||||
+ if [ -z "$HAVE_FOREIGN" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ enable_foreign "^$"
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -f "$OUTPUTFILE" ]; then
|
||||
+ cp $OUTPUTFILE $OUTPUTFILE.old
|
||||
+ if [ $? != 0 ]; then
|
||||
+ echo "failed to backup old config file, $OUTPUTFILE not updated"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+cp $TMPFILE $OUTPUTFILE
|
||||
+if [ $? != 0 ]; then
|
||||
+ echo "failed to copy new config file into place, check $OUTPUTFILE is still OK"
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+rm -f $TMPFILE
|
||||
+
|
||||
+if [ "$ENABLE" = 1 ]; then
|
||||
+ if [ "$HAVE_MODULE" = 0 ]; then
|
||||
+ modprobe dm_multipath
|
||||
+ fi
|
||||
+ if [ "$HAVE_MULTIPATHD" = 0 ]; then
|
||||
+ systemctl start multipathd.service
|
||||
+ fi
|
||||
+elif [ "$ENABLE" = 0 ]; then
|
||||
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
|
||||
+ systemctl stop multipathd.service
|
||||
+ fi
|
||||
+elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
|
||||
+ systemctl reload multipathd.service
|
||||
+fi
|
||||
diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8
|
||||
new file mode 100644
|
||||
index 00000000..83515eb4
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf.8
|
||||
@@ -0,0 +1,135 @@
|
||||
+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
|
||||
+.SH NAME
|
||||
+mpathconf - A tool for configuring device-mapper-multipath
|
||||
+.SH SYNOPSIS
|
||||
+.B mpathconf
|
||||
+.RB [\| commands \|]
|
||||
+.RB [\| options \|]
|
||||
+.SH DESCRIPTION
|
||||
+.B mpathconf
|
||||
+is a utility that creates or modifies
|
||||
+.B /etc/multipath.conf.
|
||||
+It can enable or disable multipathing and configure some common options.
|
||||
+.B mpathconf
|
||||
+can also load the
|
||||
+.B dm_multipath
|
||||
+module, start and stop the
|
||||
+.B multipathd
|
||||
+daemon, and configure the
|
||||
+.B multipathd
|
||||
+service to start automatically or not. If
|
||||
+.B mpathconf
|
||||
+is called with no commands, it will display the current configuration, but
|
||||
+will not create of modify
|
||||
+.B /etc/multipath.conf
|
||||
+
|
||||
+The default options for mpathconf are
|
||||
+.B --with_module
|
||||
+The
|
||||
+.B --with_multipathd
|
||||
+option is not set by default. Enabling multipathing will load the
|
||||
+.B dm_multipath
|
||||
+module but it will not immediately start it. This is so
|
||||
+that users can manually edit their config file if necessary, before starting
|
||||
+.B multipathd.
|
||||
+
|
||||
+If
|
||||
+.B /etc/multipath.conf
|
||||
+already exists, mpathconf will edit it. If it does not exist, mpathconf will
|
||||
+create a default file with
|
||||
+.B user_friendly_names
|
||||
+set and
|
||||
+.B find_multipaths
|
||||
+set to \fByes\fP. To disable these, use the
|
||||
+.B --user_friendly_names n
|
||||
+and
|
||||
+.B --find_multipaths n
|
||||
+options
|
||||
+.SH COMMANDS
|
||||
+.TP
|
||||
+.B --enable
|
||||
+Removes any line that blacklists all device nodes from the
|
||||
+.B /etc/multipath.conf
|
||||
+blacklist section. Also, creates
|
||||
+.B /etc/multipath.conf
|
||||
+if it doesn't exist.
|
||||
+.TP
|
||||
+.B --disable
|
||||
+Adds a line that blacklists all device nodes to the
|
||||
+.B /etc/multipath.conf
|
||||
+blacklist section. If no blacklist section exists, it will create one.
|
||||
+.TP
|
||||
+.B --allow \fB<device>\fP
|
||||
+Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all
|
||||
+wwids and the blacklist_exceptions to whitelist \fB<device>\fP. \fB<device>\fP
|
||||
+can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper
|
||||
+device, either a multipath device, or any device on stacked on top of one or
|
||||
+more multipath devices. This command can be used multiple times to allow
|
||||
+multiple devices. \fBNOTE:\fP This action will create a configuration file that
|
||||
+mpathconf will not be able to revert back to its previous state. Because
|
||||
+of this, \fB--outfile\fP is required when using \fB--allow\fP.
|
||||
+.TP
|
||||
+.B --user_friendly_names \fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this adds the line
|
||||
+.B user_friendly_names yes
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+defaults section. If set to \fBn\fP, this removes the line, if present. This
|
||||
+command can be used along with any other command.
|
||||
+.TP
|
||||
+.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP }
|
||||
+If set to \fB<value>\fP, this adds the line
|
||||
+.B find_multipaths <value>
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+defaults section. This command can be used along with any other command.
|
||||
+\fBy\fP and \fBn\fP can be used instead of \fByes\fP and \fBno\fP.
|
||||
+.TP
|
||||
+.B --property_blacklist \fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this adds the line
|
||||
+.B property "(SCSI_IDENT_|ID_WWN)"
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+blacklist_exceptions section. If set to \fBn\fP, this removes the line, if
|
||||
+present. This command can be used along with any other command.
|
||||
+.TP
|
||||
+.B --enable_foreign\fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBn\fP, this adds the line
|
||||
+.B enable_foreign "^$"
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+defaults section. if set to \fBy\fP, this removes the line, if present. This
|
||||
+command can be used along with any other command.
|
||||
+.TP
|
||||
+.B --outfile \fB<filename>\fP
|
||||
+Write the resulting multipath configuration to \fB<filename>\fP instead of
|
||||
+\fB/etc/multipath.conf\fP.
|
||||
+.SH OPTIONS
|
||||
+.TP
|
||||
+.B --with_module\fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this runs
|
||||
+.B modprobe dm_multipath
|
||||
+to install the multipath modules. This option only works with the
|
||||
+.B --enable
|
||||
+command. This option is set to \fBy\fP by default.
|
||||
+.TP
|
||||
+.B --with_multipathd { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this runs
|
||||
+.B service multipathd start
|
||||
+to start the multipathd daemon on \fB--enable\fP,
|
||||
+.B service multipathd stop
|
||||
+to stop the multipathd daemon on \fB--disable\fP, and
|
||||
+.B service multipathd reload
|
||||
+to reconfigure multipathd on \fB--user_frindly_names\fP and
|
||||
+\fB--find_multipaths\fP.
|
||||
+This option is set to \fBn\fP by default.
|
||||
+.SH FILES
|
||||
+.BR /etc/multipath.conf
|
||||
+.SH "SEE ALSO"
|
||||
+.BR multipath.conf (5),
|
||||
+.BR modprobe (8),
|
||||
+.BR multipath (8),
|
||||
+.BR multipathd (8),
|
||||
+.BR service (8),
|
||||
+.SH AUTHOR
|
||||
+Benjamin Marzinski <bmarzins@redhat.com>
|
@ -0,0 +1,151 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 17 Oct 2014 11:20:34 -0500
|
||||
Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A
|
||||
|
||||
This patch adds another option to multipath, "-A", which reads
|
||||
/proc/cmdline for mpath.wwid=<WWID> options, and adds any wwids it finds
|
||||
to /etc/multipath/wwids. While this isn't usually important during
|
||||
normal operation, since these wwids should already be added, it can be
|
||||
helpful during installation, to make sure that multipath can claim
|
||||
devices as its own, before LVM or something else makes use of them. The
|
||||
patch also execs "/sbin/multipath -A" before running multipathd in
|
||||
multipathd.service
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 ef89c7cf..f618550d 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -122,7 +122,7 @@ usage (char * progname)
|
||||
fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname);
|
||||
- fprintf (stderr, " %s [-v level] -W\n", progname);
|
||||
+ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname);
|
||||
fprintf (stderr, " %s [-h|-t|-T]\n", progname);
|
||||
@@ -136,6 +136,8 @@ usage (char * progname)
|
||||
" -f flush a multipath device map\n"
|
||||
" -F flush all multipath device maps\n"
|
||||
" -a add a device wwid to the wwids file\n"
|
||||
+ " -A add devices from kernel command line mpath.wwids\n"
|
||||
+ " parameters to wwids file\n"
|
||||
" -c check if a device should be a path in a multipath device\n"
|
||||
" -C check if a multipath device has usable paths\n"
|
||||
" -q allow queue_if_no_path when multipathd is not running\n"
|
||||
@@ -450,6 +452,50 @@ static void cleanup_vecs(void)
|
||||
free_pathvec(vecs.pathvec, FREE_PATHS);
|
||||
}
|
||||
|
||||
+static int remember_cmdline_wwid(void)
|
||||
+{
|
||||
+ FILE *f = NULL;
|
||||
+ char buf[LINE_MAX], *next, *ptr;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ f = fopen("/proc/cmdline", "re");
|
||||
+ if (!f) {
|
||||
+ condlog(0, "can't open /proc/cmdline : %s", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!fgets(buf, sizeof(buf), f)) {
|
||||
+ if (ferror(f))
|
||||
+ condlog(0, "read of /proc/cmdline failed : %s",
|
||||
+ strerror(errno));
|
||||
+ else
|
||||
+ condlog(0, "couldn't read /proc/cmdline");
|
||||
+ fclose(f);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ next = buf;
|
||||
+ while((ptr = strstr(next, "mpath.wwid="))) {
|
||||
+ ptr += 11;
|
||||
+ next = strpbrk(ptr, " \t\n");
|
||||
+ if (next) {
|
||||
+ *next = '\0';
|
||||
+ next++;
|
||||
+ }
|
||||
+ if (strlen(ptr)) {
|
||||
+ if (remember_wwid(ptr) != 0)
|
||||
+ ret = -1;
|
||||
+ }
|
||||
+ else {
|
||||
+ condlog(0, "empty mpath.wwid kernel command line option");
|
||||
+ ret = -1;
|
||||
+ }
|
||||
+ if (!next)
|
||||
+ break;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
configure (struct config *conf, enum mpath_cmds cmd,
|
||||
enum devtypes dev_type, char *devpath)
|
||||
@@ -823,7 +869,7 @@ main (int argc, char *argv[])
|
||||
conf = get_multipath_config();
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -900,6 +946,10 @@ main (int argc, char *argv[])
|
||||
case 'T':
|
||||
cmd = CMD_DUMP_CONFIG;
|
||||
break;
|
||||
+ case 'A':
|
||||
+ if (remember_cmdline_wwid() != 0)
|
||||
+ exit(RTVL_FAIL);
|
||||
+ exit(RTVL_OK);
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(RTVL_OK);
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 5b29a5d9..0478f4e7 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 \|]
|
||||
-.B -W
|
||||
+.RB [\| \-A | \-W \|]
|
||||
.
|
||||
.LP
|
||||
.B multipath
|
||||
@@ -145,6 +145,11 @@ device mapper, path checkers ...).
|
||||
Add the WWID for the specified device to the WWIDs file.
|
||||
.
|
||||
.TP
|
||||
+.B \-A
|
||||
+Add the WWIDs from any kernel command line \fImpath.wwid\fR parameters to the
|
||||
+WWIDs file.
|
||||
+.
|
||||
+.TP
|
||||
.B \-w
|
||||
Remove the WWID for the specified device from the WWIDs file.
|
||||
.
|
||||
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||
index af592057..bc8fa07a 100644
|
||||
--- a/multipathd/multipathd.service
|
||||
+++ b/multipathd/multipathd.service
|
||||
@@ -15,6 +15,7 @@ Type=notify
|
||||
NotifyAccess=main
|
||||
LimitCORE=infinity
|
||||
ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath
|
||||
+ExecStartPre=-/sbin/multipath -A
|
||||
ExecStart=/sbin/multipathd -d -s
|
||||
ExecReload=/sbin/multipathd reconfigure
|
||||
TasksMax=infinity
|
@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 7 Jun 2018 17:43:52 -0500
|
||||
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".
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/defaults.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index c27946c7..e0dd32ad 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -23,7 +23,7 @@
|
||||
#define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF
|
||||
#define DEFAULT_VERBOSITY 2
|
||||
#define DEFAULT_REASSIGN_MAPS 0
|
||||
-#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_STRICT
|
||||
+#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_OFF
|
||||
#define DEFAULT_FAST_IO_FAIL 5
|
||||
#define DEFAULT_DEV_LOSS_TMO 600
|
||||
#define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON
|
@ -0,0 +1,84 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 11 Apr 2019 13:25:42 -0500
|
||||
Subject: [PATCH] RH: attempt to get ANA info via sysfs first
|
||||
|
||||
When the ANA prioritizer is run, first see if the "ana_state" sysfs file
|
||||
exists, and if it does, try to read the state from there. If that fails,
|
||||
fallback to using an ioctl.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/prioritizers/ana.c | 31 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c
|
||||
index b5c7873d..e139360c 100644
|
||||
--- a/libmultipath/prioritizers/ana.c
|
||||
+++ b/libmultipath/prioritizers/ana.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "prio.h"
|
||||
#include "util.h"
|
||||
#include "structs.h"
|
||||
+#include "sysfs.h"
|
||||
|
||||
enum {
|
||||
ANA_ERR_GETCTRL_FAILED = 1,
|
||||
@@ -36,6 +37,7 @@ enum {
|
||||
ANA_ERR_GETNS_FAILED,
|
||||
ANA_ERR_NO_MEMORY,
|
||||
ANA_ERR_NO_INFORMATION,
|
||||
+ ANA_ERR_INVALID_STATE,
|
||||
};
|
||||
|
||||
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",
|
||||
+ [ANA_ERR_INVALID_STATE] = "invalid state",
|
||||
};
|
||||
|
||||
static const char *anas_string[] = {
|
||||
@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log,
|
||||
return -ANA_ERR_GETANAS_NOTFOUND;
|
||||
}
|
||||
|
||||
+static int get_ana_info_sysfs(struct path *pp)
|
||||
+{
|
||||
+ char state[32];
|
||||
+
|
||||
+ if (!pp->udev || sysfs_attr_get_value(pp->udev, "ana_state", state,
|
||||
+ sizeof(state)) <= 0)
|
||||
+ return -ANA_ERR_NO_INFORMATION;
|
||||
+
|
||||
+ if (strcmp(state, "optimized") == 0)
|
||||
+ return NVME_ANA_OPTIMIZED;
|
||||
+ if (strcmp(state, "non-optimized") == 0)
|
||||
+ return NVME_ANA_NONOPTIMIZED;
|
||||
+ if (strcmp(state, "inaccessible") == 0)
|
||||
+ return NVME_ANA_INACCESSIBLE;
|
||||
+ if (strcmp(state, "persistent-loss") == 0)
|
||||
+ return NVME_ANA_PERSISTENT_LOSS;
|
||||
+ if (strcmp(state, "change") == 0)
|
||||
+ return NVME_ANA_CHANGE;
|
||||
+ return -ANA_ERR_INVALID_STATE;
|
||||
+}
|
||||
+
|
||||
static int get_ana_info(struct path * pp)
|
||||
{
|
||||
int rc;
|
||||
@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args,
|
||||
|
||||
if (pp->fd < 0)
|
||||
rc = -ANA_ERR_NO_INFORMATION;
|
||||
- else
|
||||
- rc = get_ana_info(pp);
|
||||
+ else {
|
||||
+ rc = get_ana_info_sysfs(pp);
|
||||
+ if (rc < 0)
|
||||
+ rc = get_ana_info(pp);
|
||||
+ }
|
||||
|
||||
switch (rc) {
|
||||
case NVME_ANA_OPTIMIZED:
|
@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 25 Mar 2021 13:05:10 -0500
|
||||
Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output
|
||||
|
||||
Red Hat sets ID_SERIAL based on the result of scsi_id, instead of using
|
||||
the result of sg_inq and 55-scsi-sg3_id.rules. Make parse_vpd_pg83 match
|
||||
that.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 18 ++----------------
|
||||
1 file changed, 2 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index ec99a7aa..2704270e 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1135,12 +1135,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
naa_prio = 7;
|
||||
break;
|
||||
case 2:
|
||||
- /* IEEE Extended: Prio 6 */
|
||||
- naa_prio = 6;
|
||||
- break;
|
||||
case 3:
|
||||
- /* IEEE Locally assigned: Prio 1 */
|
||||
- naa_prio = 1;
|
||||
+ /* IEEE Extended or Locally assigned: Prio 6 */
|
||||
+ naa_prio = 6;
|
||||
break;
|
||||
default:
|
||||
/* Default: no priority */
|
||||
@@ -1159,17 +1156,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
vpd = d;
|
||||
}
|
||||
break;
|
||||
- case 0x8:
|
||||
- /* SCSI Name: Prio 3 */
|
||||
- if (memcmp(d + 4, "eui.", 4) &&
|
||||
- memcmp(d + 4, "naa.", 4) &&
|
||||
- memcmp(d + 4, "iqn.", 4))
|
||||
- break;
|
||||
- if (prio < 3) {
|
||||
- prio = 3;
|
||||
- vpd = d;
|
||||
- }
|
||||
- break;
|
||||
case 0x1:
|
||||
/* T-10 Vendor ID: Prio 2 */
|
||||
if (prio < 2) {
|
@ -0,0 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 11 May 2021 11:15:47 -0500
|
||||
Subject: [PATCH] multipathd: don't fail to remove path once the map is removed
|
||||
|
||||
In ev_remove_path(), if update_mpp_paths() fails, we delete the entire
|
||||
map. However, since update_mpp_paths() happens before we call
|
||||
set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so
|
||||
remove_map_and_stop_waiter() doesn't remove the path when in removes the
|
||||
map. But with the map removed, there's nothing to keep us from removing
|
||||
the path.
|
||||
|
||||
Call set_path_removed() before update_mpp_paths() to avoid the odd case
|
||||
of ev_remove_path() removing the map but not the path.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs_vec.c | 4 ++--
|
||||
multipathd/main.c | 13 ++++++++-----
|
||||
2 files changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index d242c06b..75390198 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -45,8 +45,8 @@ int update_mpp_paths(struct multipath *mpp, vector pathvec)
|
||||
|
||||
/*
|
||||
* Avoid adding removed paths to the map again
|
||||
- * when we reload it. Such paths may exist if
|
||||
- * domap fails in ev_remove_path().
|
||||
+ * when we reload it. Such paths may exist in
|
||||
+ * ev_remove_paths() or if it returns failure.
|
||||
*/
|
||||
pp1 = find_path_by_devt(pathvec, pp->dev_t);
|
||||
if (pp1 && pp->initialized != INIT_REMOVED &&
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 102946bf..449ce384 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1199,6 +1199,13 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
* avoid referring to the map of an orphaned path
|
||||
*/
|
||||
if ((mpp = pp->mpp)) {
|
||||
+ /*
|
||||
+ * Mark the path as removed. In case of success, we
|
||||
+ * will delete it for good. Otherwise, it will be deleted
|
||||
+ * later, unless all attempts to reload this map fail.
|
||||
+ */
|
||||
+ set_path_removed(pp);
|
||||
+
|
||||
/*
|
||||
* transform the mp->pg vector of vectors of paths
|
||||
* into a mp->params string to feed the device-mapper
|
||||
@@ -1210,13 +1217,9 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
}
|
||||
|
||||
/*
|
||||
- * Mark the path as removed. In case of success, we
|
||||
- * will delete it for good. Otherwise, it will be deleted
|
||||
- * later, unless all attempts to reload this map fail.
|
||||
- * Note: we have to explicitly remove pp from mpp->paths,
|
||||
+ * we have to explicitly remove pp from mpp->paths,
|
||||
* update_mpp_paths() doesn't do that.
|
||||
*/
|
||||
- set_path_removed(pp);
|
||||
i = find_slot(mpp->paths, pp);
|
||||
if (i != -1)
|
||||
vector_del_slot(mpp->paths, i);
|
@ -0,0 +1,26 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 11 May 2021 11:55:14 -0500
|
||||
Subject: [PATCH] multipathd: remove duplicate orphan_paths in flush_map
|
||||
|
||||
remove_map_and_stop_waiter() already calls orphan_paths() so flush_map()
|
||||
doesn't need to call orphan_paths() before calling
|
||||
remove_map_and_stop_waiter().
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 449ce384..6090434c 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -660,7 +660,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
|
||||
else
|
||||
condlog(2, "%s: map flushed", mpp->alias);
|
||||
|
||||
- orphan_paths(vecs->pathvec, mpp, "map flushed");
|
||||
remove_map_and_stop_waiter(mpp, vecs);
|
||||
|
||||
return 0;
|
@ -0,0 +1,225 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 11 May 2021 13:58:57 -0500
|
||||
Subject: [PATCH] multipathd: fix ev_remove_path return code handling
|
||||
|
||||
When ev_remove_path() returned success, callers assumed that the path
|
||||
(and possibly the map) had been removed. When ev_remove_path() returned
|
||||
failure, callers assumed that the path had not been removed. However,
|
||||
the path could be removed on both success or failure. This could cause
|
||||
callers to dereference the path after it was removed.
|
||||
|
||||
To deal with this, make ev_remove_path() return a different symbolic
|
||||
value for each outcome, and make the callers react appropriately for
|
||||
the different values. Found by coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 24 +++++++++++++++++++++--
|
||||
multipathd/main.c | 41 ++++++++++++++++++++-------------------
|
||||
multipathd/main.h | 14 +++++++++++++
|
||||
3 files changed, 57 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 1de6ad8e..6765fcf0 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -752,7 +752,8 @@ cli_add_path (void * v, char ** reply, int * len, void * data)
|
||||
/* Have the checker reinstate this path asap */
|
||||
pp->tick = 1;
|
||||
return 0;
|
||||
- } else if (!ev_remove_path(pp, vecs, true))
|
||||
+ } else if (ev_remove_path(pp, vecs, true) &
|
||||
+ REMOVE_PATH_SUCCESS)
|
||||
/* Path removed in ev_remove_path() */
|
||||
pp = NULL;
|
||||
else {
|
||||
@@ -813,6 +814,7 @@ cli_del_path (void * v, char ** reply, int * len, void * data)
|
||||
struct vectors * vecs = (struct vectors *)data;
|
||||
char * param = get_keyparam(v, PATH);
|
||||
struct path *pp;
|
||||
+ int ret;
|
||||
|
||||
param = convert_dev(param, 1);
|
||||
condlog(2, "%s: remove path (operator)", param);
|
||||
@@ -821,7 +823,25 @@ cli_del_path (void * v, char ** reply, int * len, void * data)
|
||||
condlog(0, "%s: path already removed", param);
|
||||
return 1;
|
||||
}
|
||||
- return ev_remove_path(pp, vecs, 1);
|
||||
+ ret = ev_remove_path(pp, vecs, 1);
|
||||
+ if (ret == REMOVE_PATH_DELAY) {
|
||||
+ *reply = strdup("delayed\n");
|
||||
+ if (*reply)
|
||||
+ *len = strlen(*reply) + 1;
|
||||
+ else {
|
||||
+ *len = 0;
|
||||
+ ret = REMOVE_PATH_FAILURE;
|
||||
+ }
|
||||
+ } else if (ret == REMOVE_PATH_MAP_ERROR) {
|
||||
+ *reply = strdup("map reload error. removed\n");
|
||||
+ if (*reply)
|
||||
+ *len = strlen(*reply) + 1;
|
||||
+ else {
|
||||
+ *len = 0;
|
||||
+ ret = REMOVE_PATH_FAILURE;
|
||||
+ }
|
||||
+ }
|
||||
+ return (ret == REMOVE_PATH_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 6090434c..8e2beddd 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -838,7 +838,7 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs)
|
||||
return;
|
||||
|
||||
udd = udev_device_ref(pp->udev);
|
||||
- if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) {
|
||||
+ if (!(ev_remove_path(pp, vecs, 1) & REMOVE_PATH_SUCCESS) && pp->mpp) {
|
||||
pp->dmstate = PSTATE_FAILED;
|
||||
dm_fail_path(pp->mpp->alias, pp->dev_t);
|
||||
}
|
||||
@@ -948,8 +948,8 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
|
||||
* Make another attempt to remove the path
|
||||
*/
|
||||
pp->mpp = prev_mpp;
|
||||
- ret = ev_remove_path(pp, vecs, true);
|
||||
- if (ret != 0) {
|
||||
+ if (!(ev_remove_path(pp, vecs, true) &
|
||||
+ REMOVE_PATH_SUCCESS)) {
|
||||
/*
|
||||
* Failure in ev_remove_path will keep
|
||||
* path in pathvec in INIT_REMOVED state
|
||||
@@ -960,6 +960,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
|
||||
dm_fail_path(pp->mpp->alias, pp->dev_t);
|
||||
condlog(1, "%s: failed to re-add path still mapped in %s",
|
||||
pp->dev, pp->mpp->alias);
|
||||
+ ret = 1;
|
||||
} else if (r == PATHINFO_OK)
|
||||
/*
|
||||
* Path successfully freed, move on to
|
||||
@@ -1167,7 +1168,6 @@ static int
|
||||
uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
|
||||
{
|
||||
struct path *pp;
|
||||
- int ret;
|
||||
|
||||
condlog(3, "%s: remove path (uevent)", uev->kernel);
|
||||
delete_foreign(uev->udev);
|
||||
@@ -1177,21 +1177,18 @@ uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
|
||||
pthread_testcancel();
|
||||
pp = find_path_by_dev(vecs->pathvec, uev->kernel);
|
||||
if (pp)
|
||||
- ret = ev_remove_path(pp, vecs, need_do_map);
|
||||
+ ev_remove_path(pp, vecs, need_do_map);
|
||||
lock_cleanup_pop(vecs->lock);
|
||||
- if (!pp) {
|
||||
- /* Not an error; path might have been purged earlier */
|
||||
+ if (!pp) /* Not an error; path might have been purged earlier */
|
||||
condlog(0, "%s: path already removed", uev->kernel);
|
||||
- return 0;
|
||||
- }
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
{
|
||||
struct multipath * mpp;
|
||||
- int i, retval = 0;
|
||||
+ int i, retval = REMOVE_PATH_SUCCESS;
|
||||
char params[PARAMS_SIZE] = {0};
|
||||
|
||||
/*
|
||||
@@ -1245,7 +1242,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
condlog(2, "%s: removed map after"
|
||||
" removing all paths",
|
||||
alias);
|
||||
- retval = 0;
|
||||
/* flush_map() has freed the path */
|
||||
goto out;
|
||||
}
|
||||
@@ -1262,11 +1258,14 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
|
||||
if (mpp->wait_for_udev) {
|
||||
mpp->wait_for_udev = 2;
|
||||
+ retval = REMOVE_PATH_DELAY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (!need_do_map)
|
||||
+ if (!need_do_map) {
|
||||
+ retval = REMOVE_PATH_DELAY;
|
||||
goto out;
|
||||
+ }
|
||||
/*
|
||||
* reload the map
|
||||
*/
|
||||
@@ -1275,7 +1274,7 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
condlog(0, "%s: failed in domap for "
|
||||
"removal of path %s",
|
||||
mpp->alias, pp->dev);
|
||||
- retval = 1;
|
||||
+ retval = REMOVE_PATH_FAILURE;
|
||||
} else {
|
||||
/*
|
||||
* update our state from kernel
|
||||
@@ -1283,12 +1282,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
char devt[BLK_DEV_SIZE];
|
||||
|
||||
strlcpy(devt, pp->dev_t, sizeof(devt));
|
||||
+
|
||||
+ /* setup_multipath will free the path
|
||||
+ * regardless of whether it succeeds or
|
||||
+ * fails */
|
||||
if (setup_multipath(vecs, mpp))
|
||||
- return 1;
|
||||
- /*
|
||||
- * Successful map reload without this path:
|
||||
- * sync_map_state() will free it.
|
||||
- */
|
||||
+ return REMOVE_PATH_MAP_ERROR;
|
||||
sync_map_state(mpp);
|
||||
|
||||
condlog(2, "%s: path removed from map %s",
|
||||
@@ -1304,8 +1303,10 @@ out:
|
||||
return retval;
|
||||
|
||||
fail:
|
||||
+ condlog(0, "%s: error removing path. removing map %s", pp->dev,
|
||||
+ mpp->alias);
|
||||
remove_map_and_stop_waiter(mpp, vecs);
|
||||
- return 1;
|
||||
+ return REMOVE_PATH_MAP_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index ddd953f9..bc1f938f 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -13,6 +13,20 @@ enum daemon_status {
|
||||
DAEMON_STATUS_SIZE,
|
||||
};
|
||||
|
||||
+enum remove_path_result {
|
||||
+ REMOVE_PATH_FAILURE = 0x0, /* path could not be removed. It is still
|
||||
+ * part of the kernel map, but its state
|
||||
+ * is set to INIT_REMOVED, and it will be
|
||||
+ * removed at the next possible occassion */
|
||||
+ REMOVE_PATH_SUCCESS = 0x1, /* path was removed */
|
||||
+ REMOVE_PATH_DELAY = 0x2, /* path is set to be removed later. it
|
||||
+ * currently still exists and is part of the
|
||||
+ * kernel map */
|
||||
+ REMOVE_PATH_MAP_ERROR = 0x5, /* map was removed because of error. value
|
||||
+ * includes REMOVE_PATH_SUCCESS bit
|
||||
+ * because the path was also removed */
|
||||
+};
|
||||
+
|
||||
struct prout_param_descriptor;
|
||||
struct prin_resp;
|
||||
|
46
SOURCES/0014-multipath-free-vectors-in-configure.patch
Normal file
46
SOURCES/0014-multipath-free-vectors-in-configure.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 11 May 2021 15:25:21 -0500
|
||||
Subject: [PATCH] multipath: free vectors in configure
|
||||
|
||||
configure() can retry multiple times, each time reallocing a maps and
|
||||
paths vector, and leaking the previous ones. Fix this by always freeing
|
||||
the vectors before configure() exits. Found by coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index f618550d..9fe53dcd 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -512,7 +512,6 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
*/
|
||||
curmp = vector_alloc();
|
||||
pathvec = vector_alloc();
|
||||
- atexit(cleanup_vecs);
|
||||
|
||||
if (!curmp || !pathvec) {
|
||||
condlog(0, "can not allocate memory");
|
||||
@@ -624,6 +623,11 @@ out:
|
||||
if (refwwid)
|
||||
FREE(refwwid);
|
||||
|
||||
+ free_multipathvec(curmp, KEEP_PATHS);
|
||||
+ vecs.mpvec = NULL;
|
||||
+ free_pathvec(pathvec, FREE_PATHS);
|
||||
+ vecs.pathvec = NULL;
|
||||
+
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -869,6 +873,7 @@ main (int argc, char *argv[])
|
||||
conf = get_multipath_config();
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
+ atexit(cleanup_vecs);
|
||||
while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 11 May 2021 16:03:13 -0500
|
||||
Subject: [PATCH] kpartx: Don't leak memory when getblock returns NULL
|
||||
|
||||
If a new block was allocated, but couldn't be filled, getblock will
|
||||
discard it. When it does so, it needs to free the block to avoid leaking
|
||||
memory. Found by coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/kpartx.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
|
||||
index 8ff116b8..7bc64543 100644
|
||||
--- a/kpartx/kpartx.c
|
||||
+++ b/kpartx/kpartx.c
|
||||
@@ -766,6 +766,8 @@ getblock (int fd, unsigned int blknr) {
|
||||
if (read(fd, bp->block, secsz) != secsz) {
|
||||
fprintf(stderr, "read error, sector %d\n", secnr);
|
||||
blockhead = bp->next;
|
||||
+ free(bp->block);
|
||||
+ free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 14 May 2021 13:45:28 -0500
|
||||
Subject: [PATCH] multipathd: don't rescan_path on wwid change in
|
||||
uev_update_path
|
||||
|
||||
If get_uid() is returning a different wwid in uev_update_path(), then
|
||||
the uid_attribute must have already gotten updated, which was the
|
||||
purpose behind calling rescan_path() in the first place.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 8e2beddd..2750f5e9 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1359,7 +1359,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
condlog(0, "%s: path wwid changed from '%s' to '%s'",
|
||||
uev->kernel, wwid, pp->wwid);
|
||||
ev_remove_path(pp, vecs, 1);
|
||||
- rescan_path(uev->udev);
|
||||
needs_reinit = 1;
|
||||
goto out;
|
||||
} else {
|
@ -0,0 +1,204 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 9 Jul 2021 14:30:10 -0500
|
||||
Subject: [PATCH] RH: mpathconf: correctly handle spaces after option names
|
||||
|
||||
mpathconf was either accepting any number of spaces, including zero,
|
||||
after option names, or it was only accepting one space. It should
|
||||
accept one or more spaces. Also, fix enable_foreign handling. It was
|
||||
still working like it did in RHEL8, where the default was to enable
|
||||
all foreign devices.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/mpathconf | 62 +++++++++++++++++++++++++--------------------
|
||||
1 file changed, 34 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/multipath/mpathconf b/multipath/mpathconf
|
||||
index 2f4f3eaf..039b3e47 100644
|
||||
--- a/multipath/mpathconf
|
||||
+++ b/multipath/mpathconf
|
||||
@@ -240,7 +240,7 @@ function validate_args
|
||||
echo "--enable_foreign must be either 'y' or 'n'"
|
||||
exit 1
|
||||
fi
|
||||
- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then
|
||||
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then
|
||||
SHOW_STATUS=1
|
||||
fi
|
||||
if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
|
||||
@@ -315,46 +315,50 @@ if [ "$MULTIPATHD" = "y" ]; then
|
||||
fi
|
||||
|
||||
if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
- if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
HAVE_DISABLE=1
|
||||
- elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
HAVE_DISABLE=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
- if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
HAVE_WWID_DISABLE=1
|
||||
- elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
HAVE_WWID_DISABLE=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$HAVE_DEFAULTS" = "1" ]; then
|
||||
- HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p`
|
||||
+ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p`
|
||||
if [ "$HAVE_FIND" = "1" ]; then
|
||||
HAVE_FIND="yes"
|
||||
elif [ "$HAVE_FIND" = "0" ]; then
|
||||
HAVE_FIND="no"
|
||||
fi
|
||||
- if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then
|
||||
HAVE_FRIENDLY=1
|
||||
- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then
|
||||
HAVE_FRIENDLY=0
|
||||
fi
|
||||
if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then
|
||||
HAVE_FOREIGN=0
|
||||
- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then
|
||||
HAVE_FOREIGN=1
|
||||
- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\^\$\"" ; then
|
||||
+ HAVE_FOREIGN=2
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"NONE\"" ; then
|
||||
HAVE_FOREIGN=2
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then
|
||||
+ HAVE_FOREIGN=3
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$HAVE_EXCEPTIONS" = "1" ]; then
|
||||
- if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
HAVE_PROPERTY=1
|
||||
- elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
HAVE_PROPERTY=0
|
||||
fi
|
||||
fi
|
||||
@@ -381,8 +385,10 @@ if [ -n "$SHOW_STATUS" ]; then
|
||||
echo "default property blacklist is enabled"
|
||||
fi
|
||||
if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then
|
||||
- echo "enable_foreign is not set (all foreign multipath devices will be shown)"
|
||||
+ echo "enable_foreign is not set (no foreign multipath devices will be shown)"
|
||||
elif [ "$HAVE_FOREIGN" = 1 ]; then
|
||||
+ echo "enable_foreign is set (all foreign multipath devices will be shown)"
|
||||
+ elif [ "$HAVE_FOREIGN" = 2 ]; then
|
||||
echo "enable_foreign is set (no foreign multipath devices will be shown)"
|
||||
else
|
||||
echo "enable_foreign is set (foreign multipath devices may not be shown)"
|
||||
@@ -427,14 +433,14 @@ fi
|
||||
|
||||
if [ "$ENABLE" = 2 ]; then
|
||||
if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
fi
|
||||
if [ -z "$HAVE_WWID_DISABLE" ]; then
|
||||
sed -i '/^blacklist[[:space:]]*{/ a\
|
||||
wwid ".*"
|
||||
' $TMPFILE
|
||||
elif [ "$HAVE_WWID_DISABLE" = 0 ]; then
|
||||
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"/ wwid ".*"/' $TMPFILE
|
||||
fi
|
||||
if [ "$HAVE_EXCEPTIONS" = 1 ]; then
|
||||
sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE
|
||||
@@ -448,7 +454,7 @@ _EOF_
|
||||
add_blacklist_exceptions
|
||||
elif [ "$ENABLE" = 1 ]; then
|
||||
if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
fi
|
||||
elif [ "$ENABLE" = 0 ]; then
|
||||
if [ -z "$HAVE_DISABLE" ]; then
|
||||
@@ -456,7 +462,7 @@ elif [ "$ENABLE" = 0 ]; then
|
||||
devnode ".*"
|
||||
' $TMPFILE
|
||||
elif [ "$HAVE_DISABLE" = 0 ]; then
|
||||
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -467,14 +473,14 @@ if [ -n "$FIND" ]; then
|
||||
' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
elif [ "$FIND" != "$HAVE_FIND" ]; then
|
||||
- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$FRIENDLY" = "n" ]; then
|
||||
if [ "$HAVE_FRIENDLY" = 1 ]; then
|
||||
- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
fi
|
||||
elif [ "$FRIENDLY" = "y" ]; then
|
||||
@@ -484,14 +490,14 @@ elif [ "$FRIENDLY" = "y" ]; then
|
||||
' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
elif [ "$HAVE_FRIENDLY" = 0 ]; then
|
||||
- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$PROPERTY" = "n" ]; then
|
||||
if [ "$HAVE_PROPERTY" = 1 ]; then
|
||||
- sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
fi
|
||||
elif [ "$PROPERTY" = "y" ]; then
|
||||
@@ -501,24 +507,24 @@ elif [ "$PROPERTY" = "y" ]; then
|
||||
' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
elif [ "$HAVE_PROPERTY" = 0 ]; then
|
||||
- sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
fi
|
||||
fi
|
||||
|
||||
-if [ "$FOREIGN" = "y" ]; then
|
||||
- if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+if [ "$FOREIGN" = "n" ]; then
|
||||
+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then
|
||||
sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
fi
|
||||
-elif [ "$FOREIGN" = "n" ]; then
|
||||
+elif [ "$FOREIGN" = "y" ]; then
|
||||
if [ -z "$HAVE_FOREIGN" ]; then
|
||||
sed -i '/^defaults[[:space:]]*{/ a\
|
||||
- enable_foreign "^$"
|
||||
+ enable_foreign ".*"
|
||||
' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
- elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE
|
||||
+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE
|
||||
CHANGED_CONFIG=1
|
||||
fi
|
||||
fi
|
@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 15 Jul 2021 14:46:49 -0500
|
||||
Subject: [PATCH] multipath.conf: fix typo in ghost_delay description
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/multipath.conf.5 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 0d2bce09..689d09aa 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1251,7 +1251,7 @@ The default is: in \fB/sys/block/<dev>/queue/max_sectors_kb\fR
|
||||
Sets the number of seconds that multipath will wait after creating a device
|
||||
with only ghost paths before marking it ready for use in systemd. This gives
|
||||
the active paths time to appear before the multipath runs the hardware handler
|
||||
-to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIon\fR
|
||||
+to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIno\fR
|
||||
makes multipath immediately mark a device with only ghost paths as ready.
|
||||
.RS
|
||||
.TP
|
@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 15 Jul 2021 17:09:05 -0500
|
||||
Subject: [PATCH] mpathpersist: fail commands when no usable paths exist
|
||||
|
||||
"mpathpersist -oCK <reservation_key> <device>" will return success if it
|
||||
is run on devices with no usable paths, but nothing is actually done.
|
||||
The -L command will fail, but it should give up sooner, and with a more
|
||||
helpful error message.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_persist.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
|
||||
index 190e9707..26710e79 100644
|
||||
--- a/libmpathpersist/mpath_persist.c
|
||||
+++ b/libmpathpersist/mpath_persist.c
|
||||
@@ -604,7 +604,8 @@ int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope,
|
||||
return ret ;
|
||||
}
|
||||
}
|
||||
- return MPATH_PR_SUCCESS;
|
||||
+ condlog (0, "%s: no path available", mpp->wwid);
|
||||
+ return MPATH_PR_DMMP_ERROR;
|
||||
}
|
||||
|
||||
int send_prout_activepath(char * dev, int rq_servact, int rq_scope,
|
||||
@@ -663,6 +664,11 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
|
||||
|
||||
active_pathcount = count_active_paths(mpp);
|
||||
|
||||
+ if (active_pathcount == 0) {
|
||||
+ condlog (0, "%s: no path available", mpp->wwid);
|
||||
+ return MPATH_PR_DMMP_ERROR;
|
||||
+ }
|
||||
+
|
||||
struct threadinfo thread[active_pathcount];
|
||||
memset(thread, 0, sizeof(thread));
|
||||
for (i = 0; i < active_pathcount; i++){
|
@ -0,0 +1,119 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 16 Jul 2021 12:39:17 -0500
|
||||
Subject: [PATCH] multipath: print warning if multipathd is not running.
|
||||
|
||||
If multipath notices that multipath devices exist or were created, and
|
||||
multipathd is not running, it now prints a warning message, so users are
|
||||
notified of the issue.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 13 +++++++++++--
|
||||
libmultipath/configure.h | 1 +
|
||||
libmultipath/libmultipath.version | 5 +++++
|
||||
multipath/main.c | 5 +++++
|
||||
4 files changed, 22 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 6ca1f4bb..9da85ce6 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -1083,7 +1083,8 @@ deadmap (struct multipath * mpp)
|
||||
return 1; /* dead */
|
||||
}
|
||||
|
||||
-int check_daemon(void)
|
||||
+extern int
|
||||
+check_daemon(void)
|
||||
{
|
||||
int fd;
|
||||
char *reply;
|
||||
@@ -1138,6 +1139,8 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||
struct config *conf;
|
||||
int allow_queueing;
|
||||
struct bitfield *size_mismatch_seen;
|
||||
+ bool map_processed = false;
|
||||
+ bool no_daemon = false;
|
||||
|
||||
/* ignore refwwid if it's empty */
|
||||
if (refwwid && !strlen(refwwid))
|
||||
@@ -1288,7 +1291,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||
conf = get_multipath_config();
|
||||
allow_queueing = conf->allow_queueing;
|
||||
put_multipath_config(conf);
|
||||
- if (!is_daemon && !allow_queueing && !check_daemon()) {
|
||||
+ if (!is_daemon && !allow_queueing &&
|
||||
+ (no_daemon || !check_daemon())) {
|
||||
+ no_daemon = true;
|
||||
if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
|
||||
mpp->no_path_retry != NO_PATH_RETRY_FAIL)
|
||||
condlog(3, "%s: multipathd not running, unset "
|
||||
@@ -1311,6 +1316,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||
else
|
||||
remove_map(mpp, vecs->pathvec, vecs->mpvec,
|
||||
KEEP_VEC);
|
||||
+ map_processed = true;
|
||||
}
|
||||
/*
|
||||
* Flush maps with only dead paths (ie not in sysfs)
|
||||
@@ -1336,6 +1342,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||
condlog(2, "%s: remove (dead)", alias);
|
||||
}
|
||||
}
|
||||
+ if (map_processed && !is_daemon && (no_daemon || !check_daemon()))
|
||||
+ condlog(2, "multipath devices exist, but multipathd service is not running");
|
||||
+
|
||||
ret = CP_OK;
|
||||
out:
|
||||
free(size_mismatch_seen);
|
||||
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
|
||||
index 70cf77a3..741066b3 100644
|
||||
--- a/libmultipath/configure.h
|
||||
+++ b/libmultipath/configure.h
|
||||
@@ -60,3 +60,4 @@ struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type);
|
||||
void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath);
|
||||
void trigger_partitions_udev_change(struct udev_device *dev, const char *action,
|
||||
int len);
|
||||
+int check_daemon(void);
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index 0cff3111..d8be5fd2 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -274,3 +274,8 @@ global:
|
||||
local:
|
||||
*;
|
||||
};
|
||||
+
|
||||
+LIBMULTIPATH_5.1.0 {
|
||||
+global:
|
||||
+ check_daemon;
|
||||
+} LIBMULTIPATH_5.0.0;
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 9fe53dcd..85e4481d 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -182,6 +182,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid)
|
||||
int i;
|
||||
struct multipath * mpp;
|
||||
int flags = (cmd == CMD_LIST_SHORT ? DI_NOIO : DI_ALL);
|
||||
+ bool maps_present = false;
|
||||
|
||||
if (dm_get_maps(curmp))
|
||||
return 1;
|
||||
@@ -214,11 +215,15 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid)
|
||||
|
||||
if (cmd == CMD_CREATE)
|
||||
reinstate_paths(mpp);
|
||||
+
|
||||
+ maps_present = true;
|
||||
}
|
||||
|
||||
if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG)
|
||||
print_foreign_topology(libmp_verbosity);
|
||||
|
||||
+ if (maps_present && !check_daemon())
|
||||
+ condlog(2, "multipath devices exist, but multipathd service is not running");
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 29 Jul 2021 13:16:57 -0500
|
||||
Subject: [PATCH] libmultipath: deal with dynamic PTHREAD_STACK_MIN
|
||||
|
||||
Starting in glibc-2.34 (commit 5d98a7da), PTHREAD_STACK_MIN is defined
|
||||
as sysconf(_SC_THREAD_STACK_MIN) if _GNU_SOURCE is defined. sysconf()
|
||||
returns a long and can, at least in theory, return -1. This change
|
||||
causes compilation to fail in setup_thread_attr() due to a comparision
|
||||
with different signedness, since stacksize is a size_t.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/util.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/util.c b/libmultipath/util.c
|
||||
index 0e37f3ff..17f8fcc6 100644
|
||||
--- a/libmultipath/util.c
|
||||
+++ b/libmultipath/util.c
|
||||
@@ -223,8 +223,8 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached)
|
||||
|
||||
ret = pthread_attr_init(attr);
|
||||
assert(ret == 0);
|
||||
- if (stacksize < PTHREAD_STACK_MIN)
|
||||
- stacksize = PTHREAD_STACK_MIN;
|
||||
+ if (PTHREAD_STACK_MIN > 0 && stacksize < (size_t)PTHREAD_STACK_MIN)
|
||||
+ stacksize = (size_t)PTHREAD_STACK_MIN;
|
||||
ret = pthread_attr_setstacksize(attr, stacksize);
|
||||
assert(ret == 0);
|
||||
if (detached) {
|
@ -0,0 +1,82 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 17 May 2021 22:37:34 +0200
|
||||
Subject: [PATCH] multipathd: cli_handlers: cleanup setting reply length
|
||||
|
||||
Create a macro for setting the reply length for string literals
|
||||
correctly, and use it where necessary.
|
||||
|
||||
In cli_del_path(), don't change the function's return code
|
||||
if just the buffer allocation for the reply failed.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 33 ++++++++++++---------------------
|
||||
1 file changed, 12 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 6765fcf0..96064944 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -32,6 +32,12 @@
|
||||
#include "foreign.h"
|
||||
#include "cli_handlers.h"
|
||||
|
||||
+#define SET_REPLY_AND_LEN(__rep, __len, string_literal) \
|
||||
+ do { \
|
||||
+ *(__rep) = strdup(string_literal); \
|
||||
+ *(__len) = *(__rep) ? sizeof(string_literal) : 0; \
|
||||
+ } while (0)
|
||||
+
|
||||
int
|
||||
show_paths (char ** r, int * len, struct vectors * vecs, char * style,
|
||||
int pretty)
|
||||
@@ -802,8 +808,7 @@ cli_add_path (void * v, char ** reply, int * len, void * data)
|
||||
}
|
||||
return ev_add_path(pp, vecs, 1);
|
||||
blacklisted:
|
||||
- *reply = strdup("blacklisted\n");
|
||||
- *len = strlen(*reply) + 1;
|
||||
+ SET_REPLY_AND_LEN(reply, len, "blacklisted\n");
|
||||
condlog(2, "%s: path blacklisted", param);
|
||||
return 0;
|
||||
}
|
||||
@@ -824,23 +829,10 @@ cli_del_path (void * v, char ** reply, int * len, void * data)
|
||||
return 1;
|
||||
}
|
||||
ret = ev_remove_path(pp, vecs, 1);
|
||||
- if (ret == REMOVE_PATH_DELAY) {
|
||||
- *reply = strdup("delayed\n");
|
||||
- if (*reply)
|
||||
- *len = strlen(*reply) + 1;
|
||||
- else {
|
||||
- *len = 0;
|
||||
- ret = REMOVE_PATH_FAILURE;
|
||||
- }
|
||||
- } else if (ret == REMOVE_PATH_MAP_ERROR) {
|
||||
- *reply = strdup("map reload error. removed\n");
|
||||
- if (*reply)
|
||||
- *len = strlen(*reply) + 1;
|
||||
- else {
|
||||
- *len = 0;
|
||||
- ret = REMOVE_PATH_FAILURE;
|
||||
- }
|
||||
- }
|
||||
+ if (ret == REMOVE_PATH_DELAY)
|
||||
+ SET_REPLY_AND_LEN(reply, len, "delayed\n");
|
||||
+ else if (ret == REMOVE_PATH_MAP_ERROR)
|
||||
+ SET_REPLY_AND_LEN(reply, len, "map reload error. removed\n");
|
||||
return (ret == REMOVE_PATH_FAILURE);
|
||||
}
|
||||
|
||||
@@ -865,8 +857,7 @@ cli_add_map (void * v, char ** reply, int * len, void * data)
|
||||
invalid = 1;
|
||||
pthread_cleanup_pop(1);
|
||||
if (invalid) {
|
||||
- *reply = strdup("blacklisted\n");
|
||||
- *len = strlen(*reply) + 1;
|
||||
+ SET_REPLY_AND_LEN(reply, len, "blacklisted\n");
|
||||
condlog(2, "%s: map blacklisted", param);
|
||||
return 1;
|
||||
}
|
93
SOURCES/multipath.conf
Normal file
93
SOURCES/multipath.conf
Normal file
@ -0,0 +1,93 @@
|
||||
# This is a basic configuration file with some examples, for device mapper
|
||||
# multipath.
|
||||
#
|
||||
# For a complete list of the default configuration values, run either
|
||||
# multipath -t
|
||||
# or
|
||||
# multipathd show config
|
||||
#
|
||||
# For a list of configuration options with descriptions, see the multipath.conf
|
||||
# man page
|
||||
|
||||
## By default, devices with vendor = "IBM" and product = "S/390.*" are
|
||||
## blacklisted. To enable mulitpathing on these devies, uncomment the
|
||||
## following lines.
|
||||
#blacklist_exceptions {
|
||||
# device {
|
||||
# vendor "IBM"
|
||||
# product "S/390.*"
|
||||
# }
|
||||
#}
|
||||
|
||||
## Use user friendly names, instead of using WWIDs as names.
|
||||
defaults {
|
||||
user_friendly_names yes
|
||||
find_multipaths yes
|
||||
}
|
||||
##
|
||||
## Here is an example of how to configure some standard options.
|
||||
##
|
||||
#
|
||||
#defaults {
|
||||
# udev_dir /dev
|
||||
# polling_interval 10
|
||||
# selector "round-robin 0"
|
||||
# path_grouping_policy multibus
|
||||
# prio alua
|
||||
# path_checker readsector0
|
||||
# rr_min_io 100
|
||||
# max_fds 8192
|
||||
# rr_weight priorities
|
||||
# failback immediate
|
||||
# no_path_retry fail
|
||||
# user_friendly_names yes
|
||||
#}
|
||||
##
|
||||
## The wwid line in the following blacklist section is shown as an example
|
||||
## of how to blacklist devices by wwid. The 2 devnode lines are the
|
||||
## compiled in default blacklist. If you want to blacklist entire types
|
||||
## of devices, such as all scsi devices, you should use a devnode line.
|
||||
## However, if you want to blacklist specific devices, you should use
|
||||
## a wwid line. Since there is no guarantee that a specific device will
|
||||
## not change names on reboot (from /dev/sda to /dev/sdb for example)
|
||||
## devnode lines are not recommended for blacklisting specific devices.
|
||||
##
|
||||
#blacklist {
|
||||
# wwid 26353900f02796769
|
||||
# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
|
||||
# devnode "^hd[a-z]"
|
||||
#}
|
||||
#multipaths {
|
||||
# multipath {
|
||||
# wwid 3600508b4000156d700012000000b0000
|
||||
# alias yellow
|
||||
# path_grouping_policy multibus
|
||||
# path_checker readsector0
|
||||
# path_selector "round-robin 0"
|
||||
# failback manual
|
||||
# rr_weight priorities
|
||||
# no_path_retry 5
|
||||
# }
|
||||
# multipath {
|
||||
# wwid 1DEC_____321816758474
|
||||
# alias red
|
||||
# }
|
||||
#}
|
||||
#devices {
|
||||
# device {
|
||||
# vendor "COMPAQ "
|
||||
# product "HSV110 (C)COMPAQ"
|
||||
# path_grouping_policy multibus
|
||||
# path_checker readsector0
|
||||
# path_selector "round-robin 0"
|
||||
# hardware_handler "0"
|
||||
# failback 15
|
||||
# rr_weight priorities
|
||||
# no_path_retry queue
|
||||
# }
|
||||
# device {
|
||||
# vendor "COMPAQ "
|
||||
# product "MSA1000 "
|
||||
# path_grouping_policy multibus
|
||||
# }
|
||||
#}
|
1912
SPECS/device-mapper-multipath.spec
Normal file
1912
SPECS/device-mapper-multipath.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user