import CS device-mapper-multipath-0.8.7-27.el9
This commit is contained in:
parent
e3b961a789
commit
34e7121e3d
@ -0,0 +1,300 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Muneendra <muneendra.kumar@broadcom.com>
|
||||||
|
Date: Wed, 20 Sep 2023 20:41:15 -0700
|
||||||
|
Subject: [PATCH] multipathd: Added support to handle FPIN-Li events for
|
||||||
|
FC-NVMe
|
||||||
|
|
||||||
|
This patch adds the support to handle FPIN-Li for FC-NVMe.
|
||||||
|
On receiving the FPIN-Li events this patch moves the devices paths
|
||||||
|
which are affected due to link integrity to marginal path groups.
|
||||||
|
The paths which are set to marginal path group will be unset
|
||||||
|
on receiving the RSCN events
|
||||||
|
|
||||||
|
(mwilck: minor compile fix for 32-bit architectures)
|
||||||
|
|
||||||
|
Signed-off-by: Muneendra <muneendra.kumar@broadcom.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
---
|
||||||
|
multipathd/fpin_handlers.c | 206 +++++++++++++++++++++++++++----------
|
||||||
|
1 file changed, 151 insertions(+), 55 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c
|
||||||
|
index 571796e7..d5f7594d 100644
|
||||||
|
--- a/multipathd/fpin_handlers.c
|
||||||
|
+++ b/multipathd/fpin_handlers.c
|
||||||
|
@@ -59,18 +59,15 @@ static void _udev_device_unref(void *p)
|
||||||
|
|
||||||
|
|
||||||
|
/*set/unset the path state to marginal*/
|
||||||
|
-static int fpin_set_pathstate(struct path *pp, bool set)
|
||||||
|
+static void fpin_set_pathstate(struct path *pp, bool set)
|
||||||
|
{
|
||||||
|
const char *action = set ? "set" : "unset";
|
||||||
|
|
||||||
|
- if (!pp || !pp->mpp || !pp->mpp->alias)
|
||||||
|
- return -1;
|
||||||
|
-
|
||||||
|
- condlog(3, "\n%s: %s marginal path %s (fpin)",
|
||||||
|
- action, pp->mpp->alias, pp->dev_t);
|
||||||
|
+ condlog(3, "%s: %s marginal path %s (fpin)",
|
||||||
|
+ pp->mpp ? pp->mpp->alias : "orphan", action, pp->dev_t);
|
||||||
|
pp->marginal = set;
|
||||||
|
- pp->mpp->fpin_must_reload = true;
|
||||||
|
- return 0;
|
||||||
|
+ if (pp->mpp)
|
||||||
|
+ pp->mpp->fpin_must_reload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This will unset marginal state of a device*/
|
||||||
|
@@ -81,14 +78,14 @@ static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs)
|
||||||
|
pp = find_path_by_dev(vecs->pathvec, devname);
|
||||||
|
if (!pp)
|
||||||
|
pp = find_path_by_devt(vecs->pathvec, devname);
|
||||||
|
-
|
||||||
|
- fpin_set_pathstate(pp, false);
|
||||||
|
+ if (pp)
|
||||||
|
+ fpin_set_pathstate(pp, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*This will set the marginal state of a device*/
|
||||||
|
-static int fpin_path_setmarginal(struct path *pp)
|
||||||
|
+static void fpin_path_setmarginal(struct path *pp)
|
||||||
|
{
|
||||||
|
- return fpin_set_pathstate(pp, true);
|
||||||
|
+ fpin_set_pathstate(pp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unsets all the devices in the list from marginal state */
|
||||||
|
@@ -175,8 +172,8 @@ static void fpin_set_rport_marginal(struct udev_device *rport_dev)
|
||||||
|
"Marginal", strlen("Marginal"));
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*Add the marginal devices info into the list*/
|
||||||
|
-static void
|
||||||
|
+/*Add the marginal devices info into the list and return 0 on success*/
|
||||||
|
+static int
|
||||||
|
fpin_add_marginal_dev_info(uint32_t host_num, char *devname)
|
||||||
|
{
|
||||||
|
struct marginal_dev_list *newdev = NULL;
|
||||||
|
@@ -191,65 +188,160 @@ fpin_add_marginal_dev_info(uint32_t host_num, char *devname)
|
||||||
|
list_add_tail(&(newdev->node),
|
||||||
|
&fpin_li_marginal_dev_list_head);
|
||||||
|
pthread_mutex_unlock(&fpin_li_marginal_dev_mutex);
|
||||||
|
- }
|
||||||
|
+ } else
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * This function goes through the vecs->pathvec, and for
|
||||||
|
- * each path, check that the host number,
|
||||||
|
- * the target WWPN associated with the path matches
|
||||||
|
- * with the els wwpn and sets the path and port state to
|
||||||
|
+ * This function compares Transport Address Controller Port pn,
|
||||||
|
+ * Host Transport Address Controller Port pn with the els wwpn ,attached_wwpn
|
||||||
|
+ * and return 1 (match) or 0 (no match) or a negative error code
|
||||||
|
+ */
|
||||||
|
+static int extract_nvme_addresses_chk_path_pwwn(const char *address,
|
||||||
|
+ uint64_t els_wwpn, uint64_t els_attached_wwpn)
|
||||||
|
+
|
||||||
|
+{
|
||||||
|
+ uint64_t traddr;
|
||||||
|
+ uint64_t host_traddr;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Find the position of "traddr=" and "host_traddr="
|
||||||
|
+ * and the address will be in the below format
|
||||||
|
+ * "traddr=nn-0x200400110dff9400:pn-0x200400110dff9400,
|
||||||
|
+ * host_traddr=nn-0x200400110dff9400:pn-0x200400110dff9400"
|
||||||
|
+ */
|
||||||
|
+ const char *traddr_start = strstr(address, "traddr=");
|
||||||
|
+ const char *host_traddr_start = strstr(address, "host_traddr=");
|
||||||
|
+
|
||||||
|
+ if (!traddr_start || !host_traddr_start)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ /* Extract traddr pn */
|
||||||
|
+ if (sscanf(traddr_start, "traddr=nn-%*[^:]:pn-%" SCNx64, &traddr) != 1)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ /* Extract host_traddr pn*/
|
||||||
|
+ if (sscanf(host_traddr_start, "host_traddr=nn-%*[^:]:pn-%" SCNx64,
|
||||||
|
+ &host_traddr) != 1)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ condlog(4, "traddr 0x%" PRIx64 " hosttraddr 0x%" PRIx64 " els_wwpn 0x%"
|
||||||
|
+ PRIx64" els_host_traddr 0x%" PRIx64,
|
||||||
|
+ traddr, host_traddr,
|
||||||
|
+ els_wwpn, els_attached_wwpn);
|
||||||
|
+ if ((host_traddr == els_attached_wwpn) && (traddr == els_wwpn))
|
||||||
|
+ return 1;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * This function check that the Transport Address Controller Port pn,
|
||||||
|
+ * Host Transport Address Controller Port pn associated with the path matches
|
||||||
|
+ * with the els wwpn ,attached_wwpn and sets the path state to
|
||||||
|
* Marginal
|
||||||
|
*/
|
||||||
|
-static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs,
|
||||||
|
+static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp,
|
||||||
|
+ uint64_t els_wwpn, uint64_t attached_wwpn)
|
||||||
|
+{
|
||||||
|
+ struct udev_device *ctl = NULL;
|
||||||
|
+ const char *address = NULL;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL);
|
||||||
|
+ if (ctl == NULL) {
|
||||||
|
+ condlog(2, "%s: No parent device for ", pp->dev);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ address = udev_device_get_sysattr_value(ctl, "address");
|
||||||
|
+ if (!address) {
|
||||||
|
+ condlog(2, "%s: unable to get the address ", pp->dev);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ condlog(4, "\n address %s: dev :%s\n", address, pp->dev);
|
||||||
|
+ ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn);
|
||||||
|
+ if (ret <= 0)
|
||||||
|
+ return;
|
||||||
|
+ ret = fpin_add_marginal_dev_info(host_num, pp->dev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return;
|
||||||
|
+ fpin_path_setmarginal(pp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * This function check the host number, the target WWPN
|
||||||
|
+ * associated with the path matches with the els wwpn and
|
||||||
|
+ * sets the path and port state to Marginal
|
||||||
|
+ */
|
||||||
|
+static void fpin_check_set_scsi_path_marginal(uint16_t host_num, struct path *pp,
|
||||||
|
uint64_t els_wwpn)
|
||||||
|
{
|
||||||
|
- struct path *pp;
|
||||||
|
- struct multipath *mpp;
|
||||||
|
- int i, k;
|
||||||
|
char rport_id[42];
|
||||||
|
const char *value = NULL;
|
||||||
|
struct udev_device *rport_dev = NULL;
|
||||||
|
uint64_t wwpn;
|
||||||
|
int ret = 0;
|
||||||
|
+ sprintf(rport_id, "rport-%d:%d-%d",
|
||||||
|
+ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
|
||||||
|
+ rport_dev = udev_device_new_from_subsystem_sysname(udev,
|
||||||
|
+ "fc_remote_ports", rport_id);
|
||||||
|
+ if (!rport_dev) {
|
||||||
|
+ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev,
|
||||||
|
+ rport_id);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ pthread_cleanup_push(_udev_device_unref, rport_dev);
|
||||||
|
+ value = udev_device_get_sysattr_value(rport_dev, "port_name");
|
||||||
|
+ if (!value)
|
||||||
|
+ goto unref;
|
||||||
|
+
|
||||||
|
+ wwpn = strtol(value, NULL, 16);
|
||||||
|
+ /*
|
||||||
|
+ * If the port wwpn matches sets the path and port state
|
||||||
|
+ * to marginal
|
||||||
|
+ */
|
||||||
|
+ if (wwpn == els_wwpn) {
|
||||||
|
+ ret = fpin_add_marginal_dev_info(host_num, pp->dev);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto unref;
|
||||||
|
+ fpin_path_setmarginal(pp);
|
||||||
|
+ fpin_set_rport_marginal(rport_dev);
|
||||||
|
+ }
|
||||||
|
+unref:
|
||||||
|
+ pthread_cleanup_pop(1);
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * This function goes through the vecs->pathvec, and for
|
||||||
|
+ * each path, it checks and sets the path state to marginal
|
||||||
|
+ * if the path's associated port wwpn ,hostnum matches with
|
||||||
|
+ * els wwnpn ,attached_wwpn
|
||||||
|
+ */
|
||||||
|
+static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs,
|
||||||
|
+ uint64_t els_wwpn, uint64_t attached_wwpn)
|
||||||
|
+{
|
||||||
|
+ struct path *pp;
|
||||||
|
+ struct multipath *mpp;
|
||||||
|
+ int i, k;
|
||||||
|
+ int ret = 0;
|
||||||
|
|
||||||
|
pthread_cleanup_push(cleanup_lock, &vecs->lock);
|
||||||
|
lock(&vecs->lock);
|
||||||
|
pthread_testcancel();
|
||||||
|
|
||||||
|
vector_foreach_slot(vecs->pathvec, pp, k) {
|
||||||
|
- /* Checks the host number and also for the SCSI FCP */
|
||||||
|
- if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no)
|
||||||
|
+ if (!pp->mpp)
|
||||||
|
continue;
|
||||||
|
- sprintf(rport_id, "rport-%d:%d-%d",
|
||||||
|
- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
|
||||||
|
- rport_dev = udev_device_new_from_subsystem_sysname(udev,
|
||||||
|
- "fc_remote_ports", rport_id);
|
||||||
|
- if (!rport_dev) {
|
||||||
|
- condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev,
|
||||||
|
- rport_id);
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- pthread_cleanup_push(_udev_device_unref, rport_dev);
|
||||||
|
- value = udev_device_get_sysattr_value(rport_dev, "port_name");
|
||||||
|
- if (!value)
|
||||||
|
- goto unref;
|
||||||
|
-
|
||||||
|
- if (value)
|
||||||
|
- wwpn = strtol(value, NULL, 16);
|
||||||
|
- /*
|
||||||
|
- * If the port wwpn matches sets the path and port state
|
||||||
|
- * to marginal
|
||||||
|
- */
|
||||||
|
- if (wwpn == els_wwpn) {
|
||||||
|
- ret = fpin_path_setmarginal(pp);
|
||||||
|
- if (ret < 0)
|
||||||
|
- goto unref;
|
||||||
|
- fpin_set_rport_marginal(rport_dev);
|
||||||
|
- fpin_add_marginal_dev_info(host_num, pp->dev);
|
||||||
|
+ /*checks if the bus type is nvme and the protocol is FC-NVMe*/
|
||||||
|
+ if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) {
|
||||||
|
+ fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn);
|
||||||
|
+ } else if ((pp->bus == SYSFS_BUS_SCSI) &&
|
||||||
|
+ (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) &&
|
||||||
|
+ (host_num == pp->sg_id.host_no)) {
|
||||||
|
+ /* Checks the host number and also for the SCSI FCP */
|
||||||
|
+ fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn);
|
||||||
|
}
|
||||||
|
-unref:
|
||||||
|
- pthread_cleanup_pop(1);
|
||||||
|
}
|
||||||
|
/* walk backwards because reload_and_sync_map() can remove mpp */
|
||||||
|
vector_foreach_slot_backwards(vecs->mpvec, mpp, i) {
|
||||||
|
@@ -278,14 +370,18 @@ fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv,
|
||||||
|
struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv;
|
||||||
|
int count = 0;
|
||||||
|
int ret = 0;
|
||||||
|
+ uint64_t attached_wwpn;
|
||||||
|
|
||||||
|
/* Update the wwn to list */
|
||||||
|
wwn_count = be32_to_cpu(li_desc->pname_count);
|
||||||
|
- condlog(4, "Got wwn count as %d\n", wwn_count);
|
||||||
|
+ attached_wwpn = be64_to_cpu(li_desc->attached_wwpn);
|
||||||
|
+ condlog(4, "Got wwn count as %d detecting wwn 0x%" PRIx64
|
||||||
|
+ " attached_wwpn 0x%" PRIx64 "\n",
|
||||||
|
+ wwn_count, be64_to_cpu(li_desc->detecting_wwpn), attached_wwpn);
|
||||||
|
|
||||||
|
for (iter = 0; iter < wwn_count; iter++) {
|
||||||
|
wwpn = be64_to_cpu(li_desc->pname_list[iter]);
|
||||||
|
- ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn);
|
||||||
|
+ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn, attached_wwpn);
|
||||||
|
if (ret < 0)
|
||||||
|
condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn);
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 26 Oct 2023 13:24:34 -0400
|
||||||
|
Subject: [PATCH] multipath-tools: add HPE Alletra 9000 NVMe to hardware table
|
||||||
|
|
||||||
|
Add config to match configuration in 0.9.6 release
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/hwtable.c | 8 ++++++++
|
||||||
|
1 file changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||||
|
index 22ff1881..78ac7988 100644
|
||||||
|
--- a/libmultipath/hwtable.c
|
||||||
|
+++ b/libmultipath/hwtable.c
|
||||||
|
@@ -119,6 +119,14 @@ static struct hwentry default_hw[] = {
|
||||||
|
.dev_loss = MAX_DEV_LOSS_TMO,
|
||||||
|
.vpd_vendor_id = VPD_VP_HP3PAR,
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ /* Alletra 9000 NVMe */
|
||||||
|
+ .vendor = "NVME",
|
||||||
|
+ .product = "HPE Alletra",
|
||||||
|
+ .pgpolicy = GROUP_BY_PRIO,
|
||||||
|
+ .pgfailback = -FAILBACK_IMMEDIATE,
|
||||||
|
+ .no_path_retry = NO_PATH_RETRY_QUEUE,
|
||||||
|
+ },
|
||||||
|
{
|
||||||
|
/* RA8000 / ESA12000 */
|
||||||
|
.vendor = "DEC",
|
70
SOURCES/0093-RH-multipath-add-mpathcleanup-man-page.patch
Normal file
70
SOURCES/0093-RH-multipath-add-mpathcleanup-man-page.patch
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 3 Nov 2023 11:13:04 -0400
|
||||||
|
Subject: [PATCH] RH: multipath: add mpathcleanup man page
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipath/Makefile | 3 +++
|
||||||
|
multipath/mpathcleanup.8 | 24 ++++++++++++++++++++++++
|
||||||
|
2 files changed, 27 insertions(+)
|
||||||
|
create mode 100644 multipath/mpathcleanup.8
|
||||||
|
|
||||||
|
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||||
|
index 1fc04c8d..cdfa160b 100644
|
||||||
|
--- a/multipath/Makefile
|
||||||
|
+++ b/multipath/Makefile
|
||||||
|
@@ -19,6 +19,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||||
|
$(GZIP) $(EXEC).8 > $(EXEC).8.gz
|
||||||
|
$(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
|
||||||
|
$(GZIP) mpathconf.8 > mpathconf.8.gz
|
||||||
|
+ $(GZIP) mpathcleanup.8 > mpathcleanup.8.gz
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||||
|
@@ -35,6 +36,7 @@ install:
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||||
|
$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
|
||||||
|
$(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir)
|
||||||
|
+ $(INSTALL_PROGRAM) -m 644 mpathcleanup.8.gz $(DESTDIR)$(man8dir)
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||||
|
@@ -45,6 +47,7 @@ uninstall:
|
||||||
|
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||||
|
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||||
|
$(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz
|
||||||
|
+ $(RM) $(DESTDIR)$(man8dir)/mpathcleanup.8.gz
|
||||||
|
|
||||||
|
clean: dep_clean
|
||||||
|
$(RM) core *.o $(EXEC) *.gz multipath.rules tmpfiles.conf
|
||||||
|
diff --git a/multipath/mpathcleanup.8 b/multipath/mpathcleanup.8
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..184c35c9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/multipath/mpathcleanup.8
|
||||||
|
@@ -0,0 +1,24 @@
|
||||||
|
+.TH MPATHCLEANUP 8 "November 2023" "" "Linux Administrator's Manual"
|
||||||
|
+.SH NAME
|
||||||
|
+mpathcleanup - A tool to remove a multipath device and its scsi path devices
|
||||||
|
+.SH SYNOPSIS
|
||||||
|
+.B mpathcleanup
|
||||||
|
+[\fB\-h\fR] [\fB\-\-flush\fR] \fBdevice\fR
|
||||||
|
+.SH DESCRIPTION
|
||||||
|
+\fBmpathcleanup\fR is a utility that attempts to remove a multipath device and
|
||||||
|
+its underlying paths. It only works for multipath devices built on top of scsi
|
||||||
|
+devices.
|
||||||
|
+.SH OPTIONS
|
||||||
|
+.TP
|
||||||
|
+.B \-\-flush
|
||||||
|
+Disable queueing on the multipath device and flush the path devices before
|
||||||
|
+removing.
|
||||||
|
+.TP
|
||||||
|
+\fB\-h\fR|\fB\-\-help\fR
|
||||||
|
+Display help text.
|
||||||
|
+.SH "SEE ALSO"
|
||||||
|
+.BR multipath.conf (5),
|
||||||
|
+.BR multipath (8),
|
||||||
|
+.BR multipathd (8)
|
||||||
|
+.SH AUTHOR
|
||||||
|
+Benjamin Marzinski <bmarzins@redhat.com>
|
182
SOURCES/0094-libmultipath-Add-max_retries-config-option.patch
Normal file
182
SOURCES/0094-libmultipath-Add-max_retries-config-option.patch
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 9 Nov 2023 18:46:11 -0500
|
||||||
|
Subject: [PATCH] libmultipath: Add max_retries config option
|
||||||
|
|
||||||
|
This option lets multipath set a scsi disk's max_retries sysfs value.
|
||||||
|
Setting this can be helpful for cases where the path checker succeeds,
|
||||||
|
but IO commands hang and timeout. By default, the SCSI layer will retry
|
||||||
|
IOs 5 times. Reducing this value will allow multipath to retry the IO
|
||||||
|
down another path sooner.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
---
|
||||||
|
libmultipath/config.h | 1 +
|
||||||
|
libmultipath/dict.c | 25 ++++++++++++++++++++++++
|
||||||
|
libmultipath/discovery.c | 40 +++++++++++++++++++++++++++++++++++++-
|
||||||
|
libmultipath/structs.h | 6 ++++++
|
||||||
|
multipath/multipath.conf.5 | 14 +++++++++++++
|
||||||
|
5 files changed, 85 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||||
|
index c1e18363..b0ee8241 100644
|
||||||
|
--- a/libmultipath/config.h
|
||||||
|
+++ b/libmultipath/config.h
|
||||||
|
@@ -162,6 +162,7 @@ struct config {
|
||||||
|
int fast_io_fail;
|
||||||
|
unsigned int dev_loss;
|
||||||
|
int eh_deadline;
|
||||||
|
+ int max_retries;
|
||||||
|
int log_checker_err;
|
||||||
|
int allow_queueing;
|
||||||
|
int allow_usb_devices;
|
||||||
|
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||||
|
index eb2f33a2..0c66c1e1 100644
|
||||||
|
--- a/libmultipath/dict.c
|
||||||
|
+++ b/libmultipath/dict.c
|
||||||
|
@@ -1206,6 +1206,30 @@ declare_hw_snprint(eh_deadline, print_undef_off_zero)
|
||||||
|
declare_pc_handler(eh_deadline, set_undef_off_zero)
|
||||||
|
declare_pc_snprint(eh_deadline, print_undef_off_zero)
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+def_max_retries_handler(struct config *conf, vector strvec, const char *file,
|
||||||
|
+ int line_nr)
|
||||||
|
+{
|
||||||
|
+ char * buff;
|
||||||
|
+
|
||||||
|
+ buff = set_value(strvec);
|
||||||
|
+ if (!buff)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (strcmp(buff, "off") == 0)
|
||||||
|
+ conf->max_retries = MAX_RETRIES_OFF;
|
||||||
|
+ else if (strcmp(buff, "0") == 0)
|
||||||
|
+ conf->max_retries = MAX_RETRIES_ZERO;
|
||||||
|
+ else
|
||||||
|
+ do_set_int(strvec, &conf->max_retries, 1, 5, file, line_nr,
|
||||||
|
+ buff);
|
||||||
|
+
|
||||||
|
+ free(buff);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+declare_def_snprint(max_retries, print_undef_off_zero)
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr)
|
||||||
|
{
|
||||||
|
@@ -2143,6 +2167,7 @@ init_keywords(vector keywords)
|
||||||
|
install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
|
||||||
|
install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
|
||||||
|
install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline);
|
||||||
|
+ install_keyword("max_retries", &def_max_retries_handler, &snprint_def_max_retries);
|
||||||
|
install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file);
|
||||||
|
install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file);
|
||||||
|
install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file);
|
||||||
|
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||||
|
index a592a54e..adf8bbaa 100644
|
||||||
|
--- a/libmultipath/discovery.c
|
||||||
|
+++ b/libmultipath/discovery.c
|
||||||
|
@@ -632,6 +632,42 @@ sysfs_set_eh_deadline(struct path *pp)
|
||||||
|
return (ret <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+sysfs_set_max_retries(struct config *conf, struct path *pp)
|
||||||
|
+{
|
||||||
|
+ struct udev_device *parent;
|
||||||
|
+ char value[16];
|
||||||
|
+ STRBUF_ON_STACK(buf);
|
||||||
|
+ int ret, len;
|
||||||
|
+
|
||||||
|
+ if (conf->max_retries == MAX_RETRIES_UNSET)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (!pp->udev || pp->sg_id.host_no < 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ len = sprintf(value, "%d", (conf->max_retries == MAX_RETRIES_OFF)? -1 :
|
||||||
|
+ (conf->max_retries == MAX_RETRIES_ZERO)? 0 :
|
||||||
|
+ conf->max_retries);
|
||||||
|
+
|
||||||
|
+ parent = udev_device_get_parent_with_subsystem_devtype(pp->udev,
|
||||||
|
+ "scsi", "scsi_device");
|
||||||
|
+ if (!parent)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (print_strbuf(&buf, "scsi_disk/%i:%i:%i:%" PRIu64 "/max_retries",
|
||||||
|
+ pp->sg_id.host_no, pp->sg_id.channel,
|
||||||
|
+ pp->sg_id.scsi_id, pp->sg_id.lun) < 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ ret = sysfs_attr_set_value(parent, get_strbuf_str(&buf), value, len);
|
||||||
|
+ if (len != ret)
|
||||||
|
+ condlog(3, "%s/%s: failed to set value to %s: %s",
|
||||||
|
+ udev_device_get_sysname(parent), get_strbuf_str(&buf),
|
||||||
|
+ value, (ret < 0)? strerror(-ret) : "write underflow");
|
||||||
|
+ return (len != ret);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
|
||||||
|
{
|
||||||
|
@@ -862,13 +898,15 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp)
|
||||||
|
|
||||||
|
if (pp->dev_loss == DEV_LOSS_TMO_UNSET &&
|
||||||
|
pp->fast_io_fail == MP_FAST_IO_FAIL_UNSET &&
|
||||||
|
- pp->eh_deadline == EH_DEADLINE_UNSET)
|
||||||
|
+ pp->eh_deadline == EH_DEADLINE_UNSET &&
|
||||||
|
+ conf->max_retries == MAX_RETRIES_UNSET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pp->bus != SYSFS_BUS_SCSI)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sysfs_set_eh_deadline(pp);
|
||||||
|
+ sysfs_set_max_retries(conf, pp);
|
||||||
|
|
||||||
|
if (pp->dev_loss == DEV_LOSS_TMO_UNSET &&
|
||||||
|
pp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
|
||||||
|
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||||
|
index c1e93e6e..b4252ab5 100644
|
||||||
|
--- a/libmultipath/structs.h
|
||||||
|
+++ b/libmultipath/structs.h
|
||||||
|
@@ -276,6 +276,12 @@ enum eh_deadline_states {
|
||||||
|
EH_DEADLINE_ZERO = UOZ_ZERO,
|
||||||
|
};
|
||||||
|
|
||||||
|
+enum max_retries_states {
|
||||||
|
+ MAX_RETRIES_UNSET = UOZ_UNDEF,
|
||||||
|
+ MAX_RETRIES_OFF = UOZ_OFF,
|
||||||
|
+ MAX_RETRIES_ZERO = UOZ_ZERO,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
enum recheck_wwid_states {
|
||||||
|
RECHECK_WWID_UNDEF = YNU_UNDEF,
|
||||||
|
RECHECK_WWID_OFF = YNU_NO,
|
||||||
|
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||||
|
index 5e447e67..789f0bfc 100644
|
||||||
|
--- a/multipath/multipath.conf.5
|
||||||
|
+++ b/multipath/multipath.conf.5
|
||||||
|
@@ -743,6 +743,20 @@ The default is: \fB<unset>\fR
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
+.B max_retries
|
||||||
|
+Specify the maximum number of times the SCSI layer will retry IO commands for
|
||||||
|
+some types of SCSI errors before returning failure. Setting this can be helpful
|
||||||
|
+for cases where IO commands hang and timeout. By default, the SCSI layer will
|
||||||
|
+retry IOs 5 times. Reducing this value will allow multipath to retry the IO
|
||||||
|
+down another path sooner. Valid values are
|
||||||
|
+\fB0\fR through \fB5\fR.
|
||||||
|
+.RS
|
||||||
|
+.TP
|
||||||
|
+The default is: \fB<unset>\fR
|
||||||
|
+.RE
|
||||||
|
+.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
.B bindings_file
|
||||||
|
This option is deprecated, and will be removed in a future release.
|
||||||
|
The full pathname of the binding file to be used when the user_friendly_names
|
@ -0,0 +1,29 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 9 Nov 2023 18:46:12 -0500
|
||||||
|
Subject: [PATCH] libmutipath: Retain device size if sysfs_get_size fails.
|
||||||
|
|
||||||
|
When paths are allocated their size is initialized to 0. If they've
|
||||||
|
already set a size, and a future call to sysfs_get_size() fails during
|
||||||
|
the parsing, assume that the size hasn't changed, instead of setting it
|
||||||
|
to 0. All other failures in sysfs_get_size() already retain the existing
|
||||||
|
size.
|
||||||
|
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/sysfs.c | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c
|
||||||
|
index 24c12b6a..41354f91 100644
|
||||||
|
--- a/libmultipath/sysfs.c
|
||||||
|
+++ b/libmultipath/sysfs.c
|
||||||
|
@@ -229,7 +229,6 @@ sysfs_get_size (struct path *pp, unsigned long long * size)
|
||||||
|
|
||||||
|
if (r != 1) {
|
||||||
|
condlog(3, "%s: Cannot parse size attribute", pp->dev);
|
||||||
|
- *size = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 9 Nov 2023 18:46:13 -0500
|
||||||
|
Subject: [PATCH] multipathd: check and update all paths when in cli_resize
|
||||||
|
|
||||||
|
When resizing a multipath device, make sure that all the paths have
|
||||||
|
been updated to the new size first.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
---
|
||||||
|
multipathd/cli_handlers.c | 31 ++++++++++++++++++-------------
|
||||||
|
1 file changed, 18 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||||
|
index f322f10f..93c32c5b 100644
|
||||||
|
--- a/multipathd/cli_handlers.c
|
||||||
|
+++ b/multipathd/cli_handlers.c
|
||||||
|
@@ -866,9 +866,11 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||||
|
char * mapname = get_keyparam(v, MAP);
|
||||||
|
struct multipath *mpp;
|
||||||
|
int minor;
|
||||||
|
- unsigned long long size;
|
||||||
|
+ unsigned long long size = 0;
|
||||||
|
struct pathgroup *pgp;
|
||||||
|
struct path *pp;
|
||||||
|
+ unsigned int i, j;
|
||||||
|
+ bool mismatch = false;
|
||||||
|
|
||||||
|
mapname = convert_dev(mapname, 0);
|
||||||
|
condlog(2, "%s: resize map (operator)", mapname);
|
||||||
|
@@ -888,21 +890,24 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pgp = VECTOR_SLOT(mpp->pg, 0);
|
||||||
|
-
|
||||||
|
- if (!pgp){
|
||||||
|
- condlog(0, "%s: couldn't get path group. cannot resize",
|
||||||
|
- mapname);
|
||||||
|
- return 1;
|
||||||
|
+ vector_foreach_slot(mpp->pg, pgp, i) {
|
||||||
|
+ vector_foreach_slot (pgp->paths, pp, j) {
|
||||||
|
+ sysfs_get_size(pp, &pp->size);
|
||||||
|
+ if (!pp->size)
|
||||||
|
+ continue;
|
||||||
|
+ if (!size)
|
||||||
|
+ size = pp->size;
|
||||||
|
+ else if (pp->size != size)
|
||||||
|
+ mismatch = true;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- pp = VECTOR_SLOT(pgp->paths, 0);
|
||||||
|
-
|
||||||
|
- if (!pp){
|
||||||
|
- condlog(0, "%s: couldn't get path. cannot resize", mapname);
|
||||||
|
+ if (!size) {
|
||||||
|
+ condlog(0, "%s: couldn't get size from sysfs. cannot resize",
|
||||||
|
+ mapname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- if (!pp->udev || sysfs_get_size(pp, &size)) {
|
||||||
|
- condlog(0, "%s: couldn't get size for sysfs. cannot resize",
|
||||||
|
+ if (mismatch) {
|
||||||
|
+ condlog(0, "%s: path size not consistent. cannot resize",
|
||||||
|
mapname);
|
||||||
|
return 1;
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 9 Nov 2023 18:46:14 -0500
|
||||||
|
Subject: [PATCH] multipathd: move post-reloading commands into resize_map()
|
||||||
|
|
||||||
|
In preparation for reusing resize_map() in other code, move all code
|
||||||
|
necessary to resize the map to the resize_map() function. Also track if
|
||||||
|
map was removed in the function.
|
||||||
|
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipathd/cli_handlers.c | 16 +++++++++-------
|
||||||
|
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||||
|
index 93c32c5b..b08b248f 100644
|
||||||
|
--- a/multipathd/cli_handlers.c
|
||||||
|
+++ b/multipathd/cli_handlers.c
|
||||||
|
@@ -856,6 +856,10 @@ int resize_map(struct multipath *mpp, unsigned long long size,
|
||||||
|
mpp->size = orig_size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
+ if (setup_multipath(vecs, mpp) != 0)
|
||||||
|
+ return 2;
|
||||||
|
+ sync_map_state(mpp);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -869,7 +873,7 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||||
|
unsigned long long size = 0;
|
||||||
|
struct pathgroup *pgp;
|
||||||
|
struct path *pp;
|
||||||
|
- unsigned int i, j;
|
||||||
|
+ unsigned int i, j, ret;
|
||||||
|
bool mismatch = false;
|
||||||
|
|
||||||
|
mapname = convert_dev(mapname, 0);
|
||||||
|
@@ -919,14 +923,12 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||||
|
condlog(3, "%s old size is %llu, new size is %llu", mapname, mpp->size,
|
||||||
|
size);
|
||||||
|
|
||||||
|
- if (resize_map(mpp, size, vecs) != 0)
|
||||||
|
- return 1;
|
||||||
|
+ ret = resize_map(mpp, size, vecs);
|
||||||
|
|
||||||
|
- if (setup_multipath(vecs, mpp) != 0)
|
||||||
|
- return 1;
|
||||||
|
- sync_map_state(mpp);
|
||||||
|
+ if (ret == 2)
|
||||||
|
+ condlog(0, "%s: map removed while trying to resize", mapname);
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+ return (ret != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
@ -0,0 +1,106 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 10 Nov 2023 17:59:42 -0500
|
||||||
|
Subject: [PATCH] multipathd: move resize_map() to multipathd/main.c
|
||||||
|
|
||||||
|
No functional changes.
|
||||||
|
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipathd/cli_handlers.c | 29 -----------------------------
|
||||||
|
multipathd/main.c | 29 +++++++++++++++++++++++++++++
|
||||||
|
multipathd/main.h | 2 ++
|
||||||
|
3 files changed, 31 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||||
|
index b08b248f..53bebc8d 100644
|
||||||
|
--- a/multipathd/cli_handlers.c
|
||||||
|
+++ b/multipathd/cli_handlers.c
|
||||||
|
@@ -834,35 +834,6 @@ cli_reload(void *v, char **reply, int *len, void *data)
|
||||||
|
return reload_and_sync_map(mpp, vecs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int resize_map(struct multipath *mpp, unsigned long long size,
|
||||||
|
- struct vectors * vecs)
|
||||||
|
-{
|
||||||
|
- char *params __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||||
|
- unsigned long long orig_size = mpp->size;
|
||||||
|
-
|
||||||
|
- mpp->size = size;
|
||||||
|
- update_mpp_paths(mpp, vecs->pathvec);
|
||||||
|
- if (setup_map(mpp, ¶ms, vecs) != 0) {
|
||||||
|
- condlog(0, "%s: failed to setup map for resize : %s",
|
||||||
|
- mpp->alias, strerror(errno));
|
||||||
|
- mpp->size = orig_size;
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
- mpp->action = ACT_RESIZE;
|
||||||
|
- mpp->force_udev_reload = 1;
|
||||||
|
- if (domap(mpp, params, 1) == DOMAP_FAIL) {
|
||||||
|
- condlog(0, "%s: failed to resize map : %s", mpp->alias,
|
||||||
|
- strerror(errno));
|
||||||
|
- mpp->size = orig_size;
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
- if (setup_multipath(vecs, mpp) != 0)
|
||||||
|
- return 2;
|
||||||
|
- sync_map_state(mpp);
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
int
|
||||||
|
cli_resize(void *v, char **reply, int *len, void *data)
|
||||||
|
{
|
||||||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||||
|
index 075e7b13..d99cad72 100644
|
||||||
|
--- a/multipathd/main.c
|
||||||
|
+++ b/multipathd/main.c
|
||||||
|
@@ -1379,6 +1379,35 @@ needs_ro_update(struct multipath *mpp, int ro)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int resize_map(struct multipath *mpp, unsigned long long size,
|
||||||
|
+ struct vectors * vecs)
|
||||||
|
+{
|
||||||
|
+ char *params __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||||
|
+ unsigned long long orig_size = mpp->size;
|
||||||
|
+
|
||||||
|
+ mpp->size = size;
|
||||||
|
+ update_mpp_paths(mpp, vecs->pathvec);
|
||||||
|
+ if (setup_map(mpp, ¶ms, vecs) != 0) {
|
||||||
|
+ condlog(0, "%s: failed to setup map for resize : %s",
|
||||||
|
+ mpp->alias, strerror(errno));
|
||||||
|
+ mpp->size = orig_size;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ mpp->action = ACT_RESIZE;
|
||||||
|
+ mpp->force_udev_reload = 1;
|
||||||
|
+ if (domap(mpp, params, 1) == DOMAP_FAIL) {
|
||||||
|
+ condlog(0, "%s: failed to resize map : %s", mpp->alias,
|
||||||
|
+ strerror(errno));
|
||||||
|
+ mpp->size = orig_size;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ if (setup_multipath(vecs, mpp) != 0)
|
||||||
|
+ return 2;
|
||||||
|
+ sync_map_state(mpp);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||||
|
{
|
||||||
|
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||||
|
index bc1f938f..dbae4935 100644
|
||||||
|
--- a/multipathd/main.h
|
||||||
|
+++ b/multipathd/main.h
|
||||||
|
@@ -66,4 +66,6 @@ int reload_and_sync_map(struct multipath *mpp, struct vectors *vecs,
|
||||||
|
|
||||||
|
void handle_path_wwid_change(struct path *pp, struct vectors *vecs);
|
||||||
|
bool check_path_wwid_change(struct path *pp);
|
||||||
|
+int resize_map(struct multipath *mpp, unsigned long long size,
|
||||||
|
+ struct vectors *vecs);
|
||||||
|
#endif /* MAIN_H */
|
202
SOURCES/0099-multipathd-Add-auto_resize-config-option.patch
Normal file
202
SOURCES/0099-multipathd-Add-auto_resize-config-option.patch
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 9 Nov 2023 18:46:16 -0500
|
||||||
|
Subject: [PATCH] multipathd: Add auto_resize config option
|
||||||
|
|
||||||
|
This option gives multipathd the ability to automatically resize a
|
||||||
|
device when it detects that all of the path devices have changed. By
|
||||||
|
default it is set to never, and multipathd will continue to work like it
|
||||||
|
always has, where a users must manually resize a multipath device.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
---
|
||||||
|
libmultipath/config.h | 1 +
|
||||||
|
libmultipath/defaults.h | 1 +
|
||||||
|
libmultipath/dict.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
libmultipath/dict.h | 1 +
|
||||||
|
libmultipath/structs.h | 7 +++++++
|
||||||
|
multipath/multipath.conf.5 | 15 +++++++++++++++
|
||||||
|
multipathd/main.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
7 files changed, 91 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||||
|
index b0ee8241..5807ac68 100644
|
||||||
|
--- a/libmultipath/config.h
|
||||||
|
+++ b/libmultipath/config.h
|
||||||
|
@@ -201,6 +201,7 @@ struct config {
|
||||||
|
int skip_delegate;
|
||||||
|
unsigned int sequence_nr;
|
||||||
|
int recheck_wwid;
|
||||||
|
+ int auto_resize;
|
||||||
|
|
||||||
|
char * multipath_dir;
|
||||||
|
char * selector;
|
||||||
|
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||||
|
index cec82f07..c3788bbc 100644
|
||||||
|
--- a/libmultipath/defaults.h
|
||||||
|
+++ b/libmultipath/defaults.h
|
||||||
|
@@ -54,6 +54,7 @@
|
||||||
|
#define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1
|
||||||
|
#define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF
|
||||||
|
#define DEFAULT_RECHECK_WWID RECHECK_WWID_OFF
|
||||||
|
+#define DEFAULT_AUTO_RESIZE AUTO_RESIZE_NEVER
|
||||||
|
/* Enable no foreign libraries by default */
|
||||||
|
#define DEFAULT_ENABLE_FOREIGN "NONE"
|
||||||
|
|
||||||
|
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||||
|
index 0c66c1e1..c4db60df 100644
|
||||||
|
--- a/libmultipath/dict.c
|
||||||
|
+++ b/libmultipath/dict.c
|
||||||
|
@@ -1736,6 +1736,43 @@ declare_hw_snprint(recheck_wwid, print_yes_no_undef)
|
||||||
|
|
||||||
|
declare_def_range_handler(uxsock_timeout, DEFAULT_REPLY_TIMEOUT, INT_MAX)
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+def_auto_resize_handler(struct config *conf, vector strvec, const char *file,
|
||||||
|
+ int line_nr)
|
||||||
|
+{
|
||||||
|
+ char * buff;
|
||||||
|
+
|
||||||
|
+ buff = set_value(strvec);
|
||||||
|
+ if (!buff)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (strcmp(buff, "never") == 0)
|
||||||
|
+ conf->auto_resize = AUTO_RESIZE_NEVER;
|
||||||
|
+ else if (strcmp(buff, "grow_only") == 0)
|
||||||
|
+ conf->auto_resize = AUTO_RESIZE_GROW_ONLY;
|
||||||
|
+ else if (strcmp(buff, "grow_shrink") == 0)
|
||||||
|
+ conf->auto_resize = AUTO_RESIZE_GROW_SHRINK;
|
||||||
|
+ else
|
||||||
|
+ condlog(1, "%s line %d, invalid value for auto_resize: \"%s\"",
|
||||||
|
+ file, line_nr, buff);
|
||||||
|
+
|
||||||
|
+ free(buff);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+print_auto_resize(struct strbuf *buff, long v)
|
||||||
|
+{
|
||||||
|
+ if (!v)
|
||||||
|
+ return 0;
|
||||||
|
+ return append_strbuf_quoted(buff,
|
||||||
|
+ v == AUTO_RESIZE_GROW_ONLY ? "grow_only" :
|
||||||
|
+ v == AUTO_RESIZE_GROW_SHRINK ? "grow_shrink" :
|
||||||
|
+ "never");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+declare_def_snprint(auto_resize, print_auto_resize)
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file,
|
||||||
|
int line_nr)
|
||||||
|
@@ -2202,6 +2239,7 @@ init_keywords(vector keywords)
|
||||||
|
install_keyword("remove_retries", &def_remove_retries_handler, &snprint_def_remove_retries);
|
||||||
|
install_keyword("max_sectors_kb", &def_max_sectors_kb_handler, &snprint_def_max_sectors_kb);
|
||||||
|
install_keyword("ghost_delay", &def_ghost_delay_handler, &snprint_def_ghost_delay);
|
||||||
|
+ install_keyword("auto_resize", &def_auto_resize_handler, &snprint_def_auto_resize);
|
||||||
|
install_keyword("find_multipaths_timeout",
|
||||||
|
&def_find_multipaths_timeout_handler,
|
||||||
|
&snprint_def_find_multipaths_timeout);
|
||||||
|
diff --git a/libmultipath/dict.h b/libmultipath/dict.h
|
||||||
|
index d80f990a..d963b4ad 100644
|
||||||
|
--- a/libmultipath/dict.h
|
||||||
|
+++ b/libmultipath/dict.h
|
||||||
|
@@ -19,4 +19,5 @@ int print_dev_loss(struct strbuf *buff, unsigned long v);
|
||||||
|
int print_reservation_key(struct strbuf *buff,
|
||||||
|
struct be64 key, uint8_t flags, int source);
|
||||||
|
int print_off_int_undef(struct strbuf *buff, long v);
|
||||||
|
+int print_auto_resize(struct strbuf *buff, long v);
|
||||||
|
#endif /* _DICT_H */
|
||||||
|
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||||
|
index b4252ab5..8c2d7131 100644
|
||||||
|
--- a/libmultipath/structs.h
|
||||||
|
+++ b/libmultipath/structs.h
|
||||||
|
@@ -167,6 +167,13 @@ enum queue_mode_states {
|
||||||
|
QUEUE_MODE_RQ,
|
||||||
|
};
|
||||||
|
|
||||||
|
+enum auto_resize_state {
|
||||||
|
+ AUTO_RESIZE_UNDEF = 0,
|
||||||
|
+ AUTO_RESIZE_NEVER,
|
||||||
|
+ AUTO_RESIZE_GROW_ONLY,
|
||||||
|
+ AUTO_RESIZE_GROW_SHRINK,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
#define PROTOCOL_UNSET -1
|
||||||
|
|
||||||
|
enum scsi_protocol {
|
||||||
|
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||||
|
index 789f0bfc..38eb5c90 100644
|
||||||
|
--- a/multipath/multipath.conf.5
|
||||||
|
+++ b/multipath/multipath.conf.5
|
||||||
|
@@ -1293,6 +1293,21 @@ The default is: \fBno\fR
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
+.B auto_resize
|
||||||
|
+Controls when multipathd will automatically resize a multipath device. If set
|
||||||
|
+to \fInever\fR, multipath devices must always be manually resized by either
|
||||||
|
+running \fBmultipathd resize map <name>\fR. If set to \fIgrow_only\fR, when
|
||||||
|
+multipathd detects that all of a multipath device's paths have increased in
|
||||||
|
+size, it will automatically grow the multipath device to the new size. If set
|
||||||
|
+to \fIgrow_shrink\fR, multipathd will also automatically shrink the device
|
||||||
|
+once it detects all of its paths have decreased in size.
|
||||||
|
+.RS
|
||||||
|
+.TP
|
||||||
|
+The default is: \fBnever\fR
|
||||||
|
+.RE
|
||||||
|
+.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
.B enable_foreign
|
||||||
|
Enables or disables foreign libraries (see section
|
||||||
|
.I FOREIGN MULTIPATH SUPPORT
|
||||||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||||
|
index d99cad72..6d1a5e4e 100644
|
||||||
|
--- a/multipathd/main.c
|
||||||
|
+++ b/multipathd/main.c
|
||||||
|
@@ -1439,6 +1439,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||||
|
if (pp) {
|
||||||
|
struct multipath *mpp = pp->mpp;
|
||||||
|
char wwid[WWID_SIZE];
|
||||||
|
+ int auto_resize;
|
||||||
|
+
|
||||||
|
+ conf = get_multipath_config();
|
||||||
|
+ auto_resize = conf->auto_resize;
|
||||||
|
+ put_multipath_config(conf);
|
||||||
|
|
||||||
|
if (pp->initialized == INIT_REQUESTED_UDEV) {
|
||||||
|
needs_reinit = 1;
|
||||||
|
@@ -1489,6 +1494,29 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ if (auto_resize != AUTO_RESIZE_NEVER &&
|
||||||
|
+ !mpp->wait_for_udev) {
|
||||||
|
+ struct pathgroup *pgp;
|
||||||
|
+ struct path *pp2;
|
||||||
|
+ unsigned int i, j;
|
||||||
|
+ unsigned long long orig_size = mpp->size;
|
||||||
|
+
|
||||||
|
+ if (!pp->size || pp->size == mpp->size ||
|
||||||
|
+ (pp->size < mpp->size &&
|
||||||
|
+ auto_resize == AUTO_RESIZE_GROW_ONLY))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ vector_foreach_slot(mpp->pg, pgp, i)
|
||||||
|
+ vector_foreach_slot (pgp->paths, pp2, j)
|
||||||
|
+ if (pp2->size && pp2->size != pp->size)
|
||||||
|
+ goto out;
|
||||||
|
+ retval = resize_map(mpp, pp->size, vecs);
|
||||||
|
+ if (retval == 2)
|
||||||
|
+ condlog(2, "%s: map removed during resize", pp->dev);
|
||||||
|
+ else if (retval == 0)
|
||||||
|
+ condlog(2, "%s: resized map from %llu to %llu",
|
||||||
|
+ mpp->alias, orig_size, pp->size);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
lock_cleanup_pop(vecs->lock);
|
@ -0,0 +1,42 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Martin Wilck <mwilck@suse.com>
|
||||||
|
Date: Mon, 18 Dec 2023 16:30:42 -0500
|
||||||
|
Subject: [PATCH] libmultipath: avoid temporarily enabling queueing on reload
|
||||||
|
|
||||||
|
Instead of always enabling queueing when a map is reloaded with
|
||||||
|
no_path_retry set to a positive number, check if the map has timed out
|
||||||
|
in recovery mode, and only enable queueing if it has not. This saves
|
||||||
|
multipathd from having to disable queueing on the map immediately after
|
||||||
|
the reload.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/dmparser.c | 14 ++++++++++++--
|
||||||
|
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c
|
||||||
|
index 16377c54..1ea2d619 100644
|
||||||
|
--- a/libmultipath/dmparser.c
|
||||||
|
+++ b/libmultipath/dmparser.c
|
||||||
|
@@ -61,9 +61,19 @@ int assemble_map(struct multipath *mp, char **params)
|
||||||
|
nr_priority_groups = VECTOR_SIZE(mp->pg);
|
||||||
|
initial_pg_nr = (nr_priority_groups ? mp->bestpg : 0);
|
||||||
|
|
||||||
|
- if (mp->no_path_retry != NO_PATH_RETRY_UNDEF &&
|
||||||
|
- mp->no_path_retry != NO_PATH_RETRY_FAIL) {
|
||||||
|
+ switch (mp->no_path_retry) {
|
||||||
|
+ case NO_PATH_RETRY_UNDEF:
|
||||||
|
+ case NO_PATH_RETRY_FAIL:
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ /* don't enable queueing if no_path_retry has timed out */
|
||||||
|
+ if (mp->in_recovery && mp->retry_tick == 0 &&
|
||||||
|
+ count_active_paths(mp) == 0)
|
||||||
|
+ break;
|
||||||
|
+ /* fallthrough */
|
||||||
|
+ case NO_PATH_RETRY_QUEUE:
|
||||||
|
add_feature(&mp->features, no_path_retry);
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
if (mp->retain_hwhandler == RETAIN_HWHANDLER_ON &&
|
||||||
|
get_linux_version_code() < KERNEL_VERSION(4, 3, 0))
|
@ -0,0 +1,76 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Wed, 22 Nov 2023 16:41:22 -0500
|
||||||
|
Subject: [PATCH] multipathd: Make sure to disable queueing if recovery has
|
||||||
|
failed.
|
||||||
|
|
||||||
|
If a multipath device has no_path_retry set to a number and has lost all
|
||||||
|
paths, gone into recovery mode, and timed out, it will disable
|
||||||
|
queue_if_no_paths. After that, if the device is reloaded by multipath
|
||||||
|
outside of multipathd, it will re-enable queuieng on the device. When
|
||||||
|
multipathd later calls set_no_path_retry() to update the queueing state,
|
||||||
|
it will not disable queue_if_no_paths, since the device is still in the
|
||||||
|
recovery state, so it believes no work needs to be done. The device will
|
||||||
|
remain in the recovery state, with retry_ticks at 0, and queueing
|
||||||
|
enabled, even though there are no usable paths.
|
||||||
|
|
||||||
|
To fix this, in set_no_path_retry(), if no_path_retry is set to a number
|
||||||
|
and the device is queueing but it is in recovery mode and out of
|
||||||
|
retries with no usable paths, manually disable queue_if_no_path.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/structs_vec.c | 26 ++++++++++++++++++++++++--
|
||||||
|
1 file changed, 24 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||||
|
index 4a32b405..86ad89ca 100644
|
||||||
|
--- a/libmultipath/structs_vec.c
|
||||||
|
+++ b/libmultipath/structs_vec.c
|
||||||
|
@@ -614,8 +614,19 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||||
|
!mpp->in_recovery)
|
||||||
|
dm_queue_if_no_path(mpp->alias, 1);
|
||||||
|
leave_recovery_mode(mpp);
|
||||||
|
- } else
|
||||||
|
- enter_recovery_mode(mpp);
|
||||||
|
+ } else {
|
||||||
|
+ /*
|
||||||
|
+ * If in_recovery is set, enter_recovery_mode does
|
||||||
|
+ * nothing. If the device is already in recovery
|
||||||
|
+ * mode and has already timed out, manually call
|
||||||
|
+ * dm_queue_if_no_path to stop it from queueing.
|
||||||
|
+ */
|
||||||
|
+ if ((!check_features || is_queueing) &&
|
||||||
|
+ mpp->in_recovery && mpp->retry_tick == 0)
|
||||||
|
+ dm_queue_if_no_path(mpp->alias, 0);
|
||||||
|
+ if (pathcount(mpp, PATH_PENDING) == 0)
|
||||||
|
+ enter_recovery_mode(mpp);
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -761,6 +772,11 @@ int verify_paths(struct multipath *mpp)
|
||||||
|
* -1 (FAIL) : fail_if_no_path
|
||||||
|
* 0 (UNDEF) : nothing
|
||||||
|
* >0 : queue_if_no_path enabled, turned off after polling n times
|
||||||
|
+ *
|
||||||
|
+ * Since this will only be called when fail_path(), update_multipath(), or
|
||||||
|
+ * io_err_stat_handle_pathfail() are failing a previously active path, the
|
||||||
|
+ * device cannot already be in recovery mode, so there will never be a need
|
||||||
|
+ * to disable queueing here.
|
||||||
|
*/
|
||||||
|
void update_queue_mode_del_path(struct multipath *mpp)
|
||||||
|
{
|
||||||
|
@@ -774,6 +790,12 @@ void update_queue_mode_del_path(struct multipath *mpp)
|
||||||
|
condlog(2, "%s: remaining active paths: %d", mpp->alias, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Since this will only be called from check_path() -> reinstate_path() after
|
||||||
|
+ * the queueing state has been updated in set_no_path_retry, this does not
|
||||||
|
+ * need to worry about modifying the queueing state except when actually
|
||||||
|
+ * leaving recovery mode.
|
||||||
|
+ */
|
||||||
|
void update_queue_mode_add_path(struct multipath *mpp)
|
||||||
|
{
|
||||||
|
int active = count_active_paths(mpp);
|
@ -0,0 +1,131 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Wed, 6 Dec 2023 17:22:02 -0500
|
||||||
|
Subject: [PATCH] multipathd: remove nopath flushing code from flush_map()
|
||||||
|
|
||||||
|
Instead of flush_map() handling both user requested flushes and
|
||||||
|
automatic flushes when the last path has been deleted, make
|
||||||
|
flush_map_nopaths() handle the automatic flushes itself, since a later
|
||||||
|
patch will change the behavior of flush_map().
|
||||||
|
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipathd/cli_handlers.c | 2 +-
|
||||||
|
multipathd/main.c | 45 +++++++++++++++++----------------------
|
||||||
|
multipathd/main.h | 2 +-
|
||||||
|
3 files changed, 21 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||||
|
index 53bebc8d..f04fb558 100644
|
||||||
|
--- a/multipathd/cli_handlers.c
|
||||||
|
+++ b/multipathd/cli_handlers.c
|
||||||
|
@@ -796,7 +796,7 @@ cli_del_maps (void *v, char **reply, int *len, void *data)
|
||||||
|
|
||||||
|
condlog(2, "remove maps (operator)");
|
||||||
|
vector_foreach_slot(vecs->mpvec, mpp, i) {
|
||||||
|
- if (flush_map(mpp, vecs, 0))
|
||||||
|
+ if (flush_map(mpp, vecs))
|
||||||
|
ret++;
|
||||||
|
else
|
||||||
|
i--;
|
||||||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||||
|
index 6d1a5e4e..1b5f82e7 100644
|
||||||
|
--- a/multipathd/main.c
|
||||||
|
+++ b/multipathd/main.c
|
||||||
|
@@ -490,12 +490,11 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset)
|
||||||
|
|
||||||
|
static bool
|
||||||
|
flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||||
|
- char alias[WWID_SIZE];
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flush_map will fail if the device is open
|
||||||
|
*/
|
||||||
|
- strlcpy(alias, mpp->alias, WWID_SIZE);
|
||||||
|
if (mpp->flush_on_last_del == FLUSH_ENABLED) {
|
||||||
|
condlog(2, "%s Last path deleted, disabling queueing",
|
||||||
|
mpp->alias);
|
||||||
|
@@ -505,11 +504,20 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||||
|
mpp->stat_map_failures++;
|
||||||
|
dm_queue_if_no_path(mpp->alias, 0);
|
||||||
|
}
|
||||||
|
- if (!flush_map(mpp, vecs, 1)) {
|
||||||
|
- condlog(2, "%s: removed map after removing all paths", alias);
|
||||||
|
- return true;
|
||||||
|
+ r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||||
|
+ if (r) {
|
||||||
|
+ if (r == 1)
|
||||||
|
+ condlog(0, "%s: can't flush", mpp->alias);
|
||||||
|
+ else {
|
||||||
|
+ condlog(2, "%s: devmap deferred remove", mpp->alias);
|
||||||
|
+ mpp->deferred_remove = DEFERRED_REMOVE_IN_PROGRESS;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
- return false;
|
||||||
|
+
|
||||||
|
+ condlog(2, "%s: map flushed after removing all paths", mpp->alias);
|
||||||
|
+ remove_map_and_stop_waiter(mpp, vecs);
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -685,30 +693,15 @@ sync_maps_state(vector mpvec)
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
-flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
|
||||||
|
+flush_map(struct multipath * mpp, struct vectors * vecs)
|
||||||
|
{
|
||||||
|
- int r;
|
||||||
|
-
|
||||||
|
- if (nopaths)
|
||||||
|
- r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||||
|
- else
|
||||||
|
- r = dm_flush_map(mpp->alias);
|
||||||
|
- /*
|
||||||
|
- * clear references to this map before flushing so we can ignore
|
||||||
|
- * the spurious uevent we may generate with the dm_flush_map call below
|
||||||
|
- */
|
||||||
|
+ int r = dm_flush_map(mpp->alias);
|
||||||
|
if (r) {
|
||||||
|
- if (r == 1)
|
||||||
|
- condlog(0, "%s: can't flush", mpp->alias);
|
||||||
|
- else {
|
||||||
|
- condlog(2, "%s: devmap deferred remove", mpp->alias);
|
||||||
|
- mpp->deferred_remove = DEFERRED_REMOVE_IN_PROGRESS;
|
||||||
|
- }
|
||||||
|
+ condlog(0, "%s: can't flush", mpp->alias);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- condlog(2, "%s: map flushed", mpp->alias);
|
||||||
|
|
||||||
|
+ condlog(2, "%s: map flushed", mpp->alias);
|
||||||
|
remove_map_and_stop_waiter(mpp, vecs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -866,7 +859,7 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs)
|
||||||
|
mpp->alias, mpp->dmi->minor, minor);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- return flush_map(mpp, vecs, 0);
|
||||||
|
+ return flush_map(mpp, vecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||||
|
index dbae4935..4138faa4 100644
|
||||||
|
--- a/multipathd/main.h
|
||||||
|
+++ b/multipathd/main.h
|
||||||
|
@@ -43,7 +43,7 @@ int ev_add_path (struct path *, struct vectors *, int);
|
||||||
|
int ev_remove_path (struct path *, struct vectors *, int);
|
||||||
|
int ev_add_map (char *, const char *, struct vectors *);
|
||||||
|
int ev_remove_map (char *, char *, int, struct vectors *);
|
||||||
|
-int flush_map(struct multipath *, struct vectors *, int);
|
||||||
|
+int flush_map(struct multipath *, struct vectors *);
|
||||||
|
int set_config_state(enum daemon_status);
|
||||||
|
void * mpath_alloc_prin_response(int prin_sa);
|
||||||
|
int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp,
|
@ -0,0 +1,39 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 7 Dec 2023 11:23:18 -0500
|
||||||
|
Subject: [PATCH] multipathd: make flush_map() delete maps like the multipath
|
||||||
|
command
|
||||||
|
|
||||||
|
When the multipath command tries to delete a multipath device, it first
|
||||||
|
disables queueing and then suspends the device to force the IOs to get
|
||||||
|
flushed. Then it attempts to delete the device and any kpartx
|
||||||
|
partitions. multipathd, on the other hand, simply tries to delete the
|
||||||
|
device and kpartx partitions, without disabling queueing or suspending.
|
||||||
|
If there are no paths but there is outstanding IO, multipathd will hang
|
||||||
|
trying to delete the last kpartx device. This is because it must be the
|
||||||
|
last opener of the multipath device (multipath won't try to delete the
|
||||||
|
device if it has any openers besides the kpartx devices) and the kernel
|
||||||
|
will not allow the last opener of a block device to close until all the
|
||||||
|
outstanding IO is flushed. This hang can be avoided if multipathd calls
|
||||||
|
dm_suspend_and_flush_map() like the multipath command does, instead of
|
||||||
|
dm_flush_map().
|
||||||
|
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipathd/main.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||||
|
index 1b5f82e7..3eeca82f 100644
|
||||||
|
--- a/multipathd/main.c
|
||||||
|
+++ b/multipathd/main.c
|
||||||
|
@@ -695,7 +695,7 @@ sync_maps_state(vector mpvec)
|
||||||
|
int
|
||||||
|
flush_map(struct multipath * mpp, struct vectors * vecs)
|
||||||
|
{
|
||||||
|
- int r = dm_flush_map(mpp->alias);
|
||||||
|
+ int r = dm_suspend_and_flush_map(mpp->alias, 0);
|
||||||
|
if (r) {
|
||||||
|
condlog(0, "%s: can't flush", mpp->alias);
|
||||||
|
return r;
|
@ -0,0 +1,83 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 8 Dec 2023 14:50:31 -0500
|
||||||
|
Subject: [PATCH] multipathd: disable queueing when removing unknown maps
|
||||||
|
|
||||||
|
Make cli_del_maps() call dm_suspend_and_flush_map() for the unknown
|
||||||
|
multipath devices as well.
|
||||||
|
|
||||||
|
After this change, all callers of cli_del_maps() set need_suspend, so
|
||||||
|
simplify dm_flush_maps().
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/devmapper.c | 7 ++-----
|
||||||
|
libmultipath/devmapper.h | 2 +-
|
||||||
|
multipath/main.c | 2 +-
|
||||||
|
multipathd/cli_handlers.c | 2 +-
|
||||||
|
4 files changed, 5 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||||
|
index 4b2e8a15..f9de3358 100644
|
||||||
|
--- a/libmultipath/devmapper.c
|
||||||
|
+++ b/libmultipath/devmapper.c
|
||||||
|
@@ -1145,7 +1145,7 @@ dm_flush_map_nopaths(const char * mapname,
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-int dm_flush_maps (int need_suspend, int retries)
|
||||||
|
+int dm_flush_maps (int retries)
|
||||||
|
{
|
||||||
|
int r = 1;
|
||||||
|
struct dm_task *dmt;
|
||||||
|
@@ -1170,10 +1170,7 @@ int dm_flush_maps (int need_suspend, int retries)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
do {
|
||||||
|
- if (need_suspend)
|
||||||
|
- r |= dm_suspend_and_flush_map(names->name, retries);
|
||||||
|
- else
|
||||||
|
- r |= dm_flush_map(names->name);
|
||||||
|
+ r |= dm_suspend_and_flush_map(names->name, retries);
|
||||||
|
next = names->next;
|
||||||
|
names = (void *) names + next;
|
||||||
|
} while (next);
|
||||||
|
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||||
|
index 45a676de..808da28d 100644
|
||||||
|
--- a/libmultipath/devmapper.h
|
||||||
|
+++ b/libmultipath/devmapper.h
|
||||||
|
@@ -55,7 +55,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
|
||||||
|
#define dm_suspend_and_flush_map(mapname, retries) \
|
||||||
|
_dm_flush_map(mapname, 1, 0, 1, retries)
|
||||||
|
int dm_cancel_deferred_remove(struct multipath *mpp);
|
||||||
|
-int dm_flush_maps (int need_suspend, int retries);
|
||||||
|
+int dm_flush_maps (int retries);
|
||||||
|
int dm_fail_path(const char * mapname, char * path);
|
||||||
|
int dm_reinstate_path(const char * mapname, char * path);
|
||||||
|
int dm_queue_if_no_path(const char *mapname, int enable);
|
||||||
|
diff --git a/multipath/main.c b/multipath/main.c
|
||||||
|
index f1077421..e296be6e 100644
|
||||||
|
--- a/multipath/main.c
|
||||||
|
+++ b/multipath/main.c
|
||||||
|
@@ -1126,7 +1126,7 @@ main (int argc, char *argv[])
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else if (cmd == CMD_FLUSH_ALL) {
|
||||||
|
- r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK;
|
||||||
|
+ r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY)
|
||||||
|
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||||
|
index f04fb558..aca8e2df 100644
|
||||||
|
--- a/multipathd/cli_handlers.c
|
||||||
|
+++ b/multipathd/cli_handlers.c
|
||||||
|
@@ -802,7 +802,7 @@ cli_del_maps (void *v, char **reply, int *len, void *data)
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
/* flush any multipath maps that aren't currently known by multipathd */
|
||||||
|
- ret |= dm_flush_maps(0, 0);
|
||||||
|
+ ret |= dm_flush_maps(0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Tue, 16 Jan 2024 20:19:11 -0500
|
||||||
|
Subject: [PATCH] multipathd: fix null pointer dereference in uev_update_path
|
||||||
|
|
||||||
|
The Auto-resize code added a check that deferences pp->mpp without
|
||||||
|
checking that it's non-NULL. Fix it.
|
||||||
|
|
||||||
|
Fixes: 981b83ad1 ("multipathd: Add auto_resize config option")
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
---
|
||||||
|
multipathd/main.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||||
|
index 3eeca82f..26be6dc3 100644
|
||||||
|
--- a/multipathd/main.c
|
||||||
|
+++ b/multipathd/main.c
|
||||||
|
@@ -1487,7 +1487,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- if (auto_resize != AUTO_RESIZE_NEVER &&
|
||||||
|
+ if (auto_resize != AUTO_RESIZE_NEVER && mpp &&
|
||||||
|
!mpp->wait_for_udev) {
|
||||||
|
struct pathgroup *pgp;
|
||||||
|
struct path *pp2;
|
43
SOURCES/0106-multipathd-fix-auto-resize-configuration.patch
Normal file
43
SOURCES/0106-multipathd-fix-auto-resize-configuration.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Tue, 16 Jan 2024 20:19:12 -0500
|
||||||
|
Subject: [PATCH] multipathd: fix auto-resize configuration
|
||||||
|
|
||||||
|
The code acted like AUTO_RESIZE_UNDEFINED didn't exist, but since
|
||||||
|
conf->auto_resize was never set to AUTO_RESIZE_NEVER, the default was in
|
||||||
|
fact AUTO_RESIZE_UNDEFINED, which ended up getting treated like
|
||||||
|
AUTO_RESIZE_GROW_SHRINK. Remove AUTO_RESIZE_UNDEFINED and explicitly
|
||||||
|
default auto_resize tp AUTO_RESIZE_NEVER.
|
||||||
|
|
||||||
|
Fixes: 981b83ad1 ("multipathd: Add auto_resize config option")
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
---
|
||||||
|
libmultipath/config.c | 1 +
|
||||||
|
libmultipath/structs.h | 1 -
|
||||||
|
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||||
|
index 61b0dd51..f31200a3 100644
|
||||||
|
--- a/libmultipath/config.c
|
||||||
|
+++ b/libmultipath/config.c
|
||||||
|
@@ -940,6 +940,7 @@ int _init_config (const char *file, struct config *conf)
|
||||||
|
conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES;
|
||||||
|
conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY;
|
||||||
|
conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
|
||||||
|
+ conf->auto_resize = DEFAULT_AUTO_RESIZE;
|
||||||
|
conf->remove_retries = 0;
|
||||||
|
conf->ghost_delay = DEFAULT_GHOST_DELAY;
|
||||||
|
conf->all_tg_pt = DEFAULT_ALL_TG_PT;
|
||||||
|
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||||
|
index 8c2d7131..d2ad4867 100644
|
||||||
|
--- a/libmultipath/structs.h
|
||||||
|
+++ b/libmultipath/structs.h
|
||||||
|
@@ -168,7 +168,6 @@ enum queue_mode_states {
|
||||||
|
};
|
||||||
|
|
||||||
|
enum auto_resize_state {
|
||||||
|
- AUTO_RESIZE_UNDEF = 0,
|
||||||
|
AUTO_RESIZE_NEVER,
|
||||||
|
AUTO_RESIZE_GROW_ONLY,
|
||||||
|
AUTO_RESIZE_GROW_SHRINK,
|
@ -0,0 +1,28 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 26 Jan 2024 15:40:42 -0500
|
||||||
|
Subject: [PATCH] libmultipath: fix displaying auto_resize config setting
|
||||||
|
|
||||||
|
When 56476ebd3 ("multipathd: fix auto-resize configuration") removed
|
||||||
|
AUTO_RESIZE_UNDEFINED, it didn't update print_auto_resize() to print
|
||||||
|
a value for when it was set to 0 (which is now AUTO_RESIZE_NEVER).
|
||||||
|
|
||||||
|
Fixes: 56476ebd3 ("multipathd: fix auto-resize configuration")
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/dict.c | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||||
|
index c4db60df..ce1b6c99 100644
|
||||||
|
--- a/libmultipath/dict.c
|
||||||
|
+++ b/libmultipath/dict.c
|
||||||
|
@@ -1763,8 +1763,6 @@ def_auto_resize_handler(struct config *conf, vector strvec, const char *file,
|
||||||
|
int
|
||||||
|
print_auto_resize(struct strbuf *buff, long v)
|
||||||
|
{
|
||||||
|
- if (!v)
|
||||||
|
- return 0;
|
||||||
|
return append_strbuf_quoted(buff,
|
||||||
|
v == AUTO_RESIZE_GROW_ONLY ? "grow_only" :
|
||||||
|
v == AUTO_RESIZE_GROW_SHRINK ? "grow_shrink" :
|
@ -1,6 +1,6 @@
|
|||||||
Name: device-mapper-multipath
|
Name: device-mapper-multipath
|
||||||
Version: 0.8.7
|
Version: 0.8.7
|
||||||
Release: 22%{?dist}
|
Release: 27%{?dist}
|
||||||
Summary: Tools to manage multipath devices using device-mapper
|
Summary: Tools to manage multipath devices using device-mapper
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
URL: http://christophe.varoqui.free.fr/
|
URL: http://christophe.varoqui.free.fr/
|
||||||
@ -100,7 +100,23 @@ Patch0087: 0087-multipathd-handle-no-active-paths-in-update_map_pr.patch
|
|||||||
Patch0088: 0088-libmpathpersist-fix-resource-leak-in-update_map_pr.patch
|
Patch0088: 0088-libmpathpersist-fix-resource-leak-in-update_map_pr.patch
|
||||||
Patch0089: 0089-RH-Add-mpathcleanup.patch
|
Patch0089: 0089-RH-Add-mpathcleanup.patch
|
||||||
Patch0090: 0090-RH-make-listing-return-an-error-if-the-config-file-i.patch
|
Patch0090: 0090-RH-make-listing-return-an-error-if-the-config-file-i.patch
|
||||||
|
Patch0091: 0091-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch
|
||||||
|
Patch0092: 0092-multipath-tools-add-HPE-Alletra-9000-NVMe-to-hardwar.patch
|
||||||
|
Patch0093: 0093-RH-multipath-add-mpathcleanup-man-page.patch
|
||||||
|
Patch0094: 0094-libmultipath-Add-max_retries-config-option.patch
|
||||||
|
Patch0095: 0095-libmutipath-Retain-device-size-if-sysfs_get_size-fai.patch
|
||||||
|
Patch0096: 0096-multipathd-check-and-update-all-paths-when-in-cli_re.patch
|
||||||
|
Patch0097: 0097-multipathd-move-post-reloading-commands-into-resize_.patch
|
||||||
|
Patch0098: 0098-multipathd-move-resize_map-to-multipathd-main.c.patch
|
||||||
|
Patch0099: 0099-multipathd-Add-auto_resize-config-option.patch
|
||||||
|
Patch0100: 0100-libmultipath-avoid-temporarily-enabling-queueing-on-.patch
|
||||||
|
Patch0101: 0101-multipathd-Make-sure-to-disable-queueing-if-recovery.patch
|
||||||
|
Patch0102: 0102-multipathd-remove-nopath-flushing-code-from-flush_ma.patch
|
||||||
|
Patch0103: 0103-multipathd-make-flush_map-delete-maps-like-the-multi.patch
|
||||||
|
Patch0104: 0104-multipathd-disable-queueing-when-removing-unknown-ma.patch
|
||||||
|
Patch0105: 0105-multipathd-fix-null-pointer-dereference-in-uev_updat.patch
|
||||||
|
Patch0106: 0106-multipathd-fix-auto-resize-configuration.patch
|
||||||
|
Patch0107: 0107-libmultipath-fix-displaying-auto_resize-config-setti.patch
|
||||||
|
|
||||||
|
|
||||||
# runtime
|
# runtime
|
||||||
@ -243,6 +259,7 @@ fi
|
|||||||
%{_mandir}/man8/multipath.8.gz
|
%{_mandir}/man8/multipath.8.gz
|
||||||
%{_mandir}/man8/multipathd.8.gz
|
%{_mandir}/man8/multipathd.8.gz
|
||||||
%{_mandir}/man8/mpathconf.8.gz
|
%{_mandir}/man8/mpathconf.8.gz
|
||||||
|
%{_mandir}/man8/mpathcleanup.8.gz
|
||||||
%{_mandir}/man8/mpathpersist.8.gz
|
%{_mandir}/man8/mpathpersist.8.gz
|
||||||
%config %{_udevrulesdir}/62-multipath.rules
|
%config %{_udevrulesdir}/62-multipath.rules
|
||||||
%config %{_udevrulesdir}/11-dm-mpath.rules
|
%config %{_udevrulesdir}/11-dm-mpath.rules
|
||||||
@ -303,6 +320,56 @@ fi
|
|||||||
%{_pkgconfdir}/libdmmp.pc
|
%{_pkgconfdir}/libdmmp.pc
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Jan 26 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-27
|
||||||
|
- Add 0105-multipathd-fix-null-pointer-dereference-in-uev_updat.patch
|
||||||
|
- Add 0106-multipathd-fix-auto-resize-configuration.patch
|
||||||
|
- Add 0107-libmultipath-fix-displaying-auto_resize-config-setti.patch
|
||||||
|
* Fixes RHEL-986 ("Add option to allow multipathd to detect device
|
||||||
|
resizes and autoresize.")
|
||||||
|
- Resolves: RHEL-986
|
||||||
|
|
||||||
|
* Wed Jan 3 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-26
|
||||||
|
- Add 0100-libmultipath-avoid-temporarily-enabling-queueing-on-.patch
|
||||||
|
- Add 0101-multipathd-Make-sure-to-disable-queueing-if-recovery.patch
|
||||||
|
* Fixes RHEL-17234 ("RHEL9 dm-multipath no_path_retry [retry number] is
|
||||||
|
undone if paths are later lost for an open map.")
|
||||||
|
- Add 0102-multipathd-remove-nopath-flushing-code-from-flush_ma.patch
|
||||||
|
- Add 0103-multipathd-make-flush_map-delete-maps-like-the-multi.patch
|
||||||
|
- Add 0104-multipathd-disable-queueing-when-removing-unknown-ma.patch
|
||||||
|
* Fixes RHEL-4998 ("When remove external lun from host, rescan lun status
|
||||||
|
will cause the OS hang and no response")
|
||||||
|
- Resolves: RHEL-4998
|
||||||
|
- Resolves: RHEL-17234
|
||||||
|
|
||||||
|
* Mon Nov 20 2023 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-25
|
||||||
|
- Add 0094-libmultipath-Add-max_retries-config-option.patch
|
||||||
|
* Fixes RHEL-1729 ("Allow multipathd to set the max_retries of the
|
||||||
|
scsi_device for paths")
|
||||||
|
- Add 0095-libmutipath-Retain-device-size-if-sysfs_get_size-fai.patch
|
||||||
|
- Add 0096-multipathd-check-and-update-all-paths-when-in-cli_re.patch
|
||||||
|
- Add 0097-multipathd-move-post-reloading-commands-into-resize_.patch
|
||||||
|
- Add 0098-multipathd-move-resize_map-to-multipathd-main.c.patch
|
||||||
|
- Add 0099-multipathd-Add-auto_resize-config-option.patch
|
||||||
|
* Fixes RHEL-986 ("Add option to allow multipathd to detect device
|
||||||
|
resizes and autoresize.")
|
||||||
|
- Resolves: RHEL-986
|
||||||
|
- Resolves: RHEL-1729
|
||||||
|
|
||||||
|
* Fri Nov 3 2023 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-24
|
||||||
|
- Add 0093-RH-multipath-add-mpathcleanup-man-page.patch
|
||||||
|
* Fixes RHEL-1266 ("There is no man page for mpathcleanup")
|
||||||
|
- Resolves: RHEL-1266
|
||||||
|
|
||||||
|
* Wed Nov 1 2023 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-23
|
||||||
|
- Add 0091-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch
|
||||||
|
* Fixes RHEL-6678 (Add support in multipathd for NVMe to listen for FPIN-Li
|
||||||
|
events and mark effected paths as marginal)
|
||||||
|
- Add 0092-multipath-tools-add-HPE-Alletra-9000-NVMe-to-hardwar.patch
|
||||||
|
* Fixes RHEL-1830 (Changes to Arcus NVMeoFC multipath.conf settings for RHEL
|
||||||
|
9.x to be included in kernel by default)
|
||||||
|
- Resolves: RHEL-6678
|
||||||
|
- Resolves: RHEL-1830
|
||||||
|
|
||||||
* Fri Jul 28 2023 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-22
|
* Fri Jul 28 2023 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-22
|
||||||
- Add 0089-RH-Add-mpathcleanup.patch
|
- Add 0089-RH-Add-mpathcleanup.patch
|
||||||
* Fixes RHEL-782
|
* Fixes RHEL-782
|
||||||
|
Loading…
Reference in New Issue
Block a user