import UBI device-mapper-multipath-0.8.7-32.el9
This commit is contained in:
parent
1d69d749f3
commit
23ec6cc36d
@ -0,0 +1,40 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Tue, 9 Apr 2024 14:09:49 -0400
|
||||||
|
Subject: [PATCH] libmultipath: actually truncate too-large vpd page.
|
||||||
|
|
||||||
|
When multipath notices that the vpd page is too large, it needs to
|
||||||
|
actually truncate it. Also, whe calling parse_vpd_pg83() with a possibly
|
||||||
|
truncated page, multipath needs to check that it actually has a whole
|
||||||
|
vpd entry, before trying to use it.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/discovery.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||||
|
index adf8bbaa..ae7eb7e6 100644
|
||||||
|
--- a/libmultipath/discovery.c
|
||||||
|
+++ b/libmultipath/discovery.c
|
||||||
|
@@ -1164,7 +1164,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||||
|
int vpd_type, prio = -1, naa_prio;
|
||||||
|
|
||||||
|
d = in + 4;
|
||||||
|
- while (d < in + in_len) {
|
||||||
|
+ while (d + 4 <= in + in_len && d + d[3] + 4 <= in + in_len) {
|
||||||
|
/* Select 'association: LUN' */
|
||||||
|
if ((d[1] & 0x30) != 0) {
|
||||||
|
d += d[3] + 4;
|
||||||
|
@@ -1363,8 +1363,10 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen)
|
||||||
|
return -ENODATA;
|
||||||
|
}
|
||||||
|
buff_len = get_unaligned_be16(&buff[2]) + 4;
|
||||||
|
- if (buff_len > 4096)
|
||||||
|
+ if (buff_len > 4096) {
|
||||||
|
condlog(3, "vpd pg%02x page truncated", pg);
|
||||||
|
+ buff_len = 4096;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (pg == 0x80)
|
||||||
|
len = parse_vpd_pg80(buff, str, maxlen);
|
@ -0,0 +1,23 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Tue, 9 Apr 2024 14:13:34 -0400
|
||||||
|
Subject: [PATCH] kpartx: fix theoretical overflow in loop device name
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
kpartx/lopart.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/kpartx/lopart.c b/kpartx/lopart.c
|
||||||
|
index 9b652554..80ce1312 100644
|
||||||
|
--- a/kpartx/lopart.c
|
||||||
|
+++ b/kpartx/lopart.c
|
||||||
|
@@ -159,7 +159,7 @@ char *find_loop_by_file(const char *filename)
|
||||||
|
|
||||||
|
char *find_unused_loop_device(void)
|
||||||
|
{
|
||||||
|
- char dev[20], *next_loop_dev = NULL;
|
||||||
|
+ char dev[21], *next_loop_dev = NULL;
|
||||||
|
int fd, next_loop = 0, somedev = 0, someloop = 0, loop_known = 0;
|
||||||
|
struct stat statbuf;
|
||||||
|
struct loop_info loopinfo;
|
@ -0,0 +1,194 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Tue, 19 Dec 2023 17:51:50 -0500
|
||||||
|
Subject: [PATCH] libmultipath: keep track of queueing state in features
|
||||||
|
|
||||||
|
Make multipathd update mpp->features when in enables or disables
|
||||||
|
queuing. This patch handles all the cases except failed removes by
|
||||||
|
dm_suspend_and_flush_map(), which is never called by multipathd.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
---
|
||||||
|
libmultipath/configure.c | 4 +---
|
||||||
|
libmultipath/devmapper.c | 23 +++++++++++++++++++----
|
||||||
|
libmultipath/devmapper.h | 2 +-
|
||||||
|
libmultipath/structs_vec.c | 10 +++++-----
|
||||||
|
multipathd/main.c | 8 ++++----
|
||||||
|
5 files changed, 30 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||||
|
index bbdbb8ca..71acb968 100644
|
||||||
|
--- a/libmultipath/configure.c
|
||||||
|
+++ b/libmultipath/configure.c
|
||||||
|
@@ -1279,9 +1279,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||||
|
mpp->no_path_retry != NO_PATH_RETRY_FAIL)
|
||||||
|
condlog(3, "%s: multipathd not running, unset "
|
||||||
|
"queue_if_no_path feature", mpp->alias);
|
||||||
|
- if (!dm_queue_if_no_path(mpp->alias, 0))
|
||||||
|
- remove_feature(&mpp->features,
|
||||||
|
- "queue_if_no_path");
|
||||||
|
+ dm_queue_if_no_path(mpp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_daemon && mpp->action != ACT_NOTHING)
|
||||||
|
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||||
|
index f9de3358..5711f0ee 100644
|
||||||
|
--- a/libmultipath/devmapper.c
|
||||||
|
+++ b/libmultipath/devmapper.c
|
||||||
|
@@ -57,6 +57,7 @@ static int dm_cancel_remove_partmaps(const char * mapname);
|
||||||
|
static int do_foreach_partmaps(const char * mapname,
|
||||||
|
int (*partmap_func)(const char *, void *),
|
||||||
|
void *data);
|
||||||
|
+static int _dm_queue_if_no_path(const char *mapname, int enable);
|
||||||
|
|
||||||
|
#ifndef LIBDM_API_COOKIE
|
||||||
|
static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
|
||||||
|
@@ -1072,7 +1073,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
|
||||||
|
if (need_suspend &&
|
||||||
|
dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK &&
|
||||||
|
strstr(params, "queue_if_no_path")) {
|
||||||
|
- if (!dm_queue_if_no_path(mapname, 0))
|
||||||
|
+ if (!_dm_queue_if_no_path(mapname, 0))
|
||||||
|
queue_if_no_path = 1;
|
||||||
|
else
|
||||||
|
/* Leave queue_if_no_path alone if unset failed */
|
||||||
|
@@ -1121,7 +1122,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
|
||||||
|
} while (retries-- > 0);
|
||||||
|
|
||||||
|
if (queue_if_no_path == 1)
|
||||||
|
- dm_queue_if_no_path(mapname, 1);
|
||||||
|
+ _dm_queue_if_no_path(mapname, 1);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -1236,8 +1237,8 @@ dm_reinstate_path(const char * mapname, char * path)
|
||||||
|
return dm_message(mapname, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int
|
||||||
|
-dm_queue_if_no_path(const char *mapname, int enable)
|
||||||
|
+static int
|
||||||
|
+_dm_queue_if_no_path(const char *mapname, int enable)
|
||||||
|
{
|
||||||
|
char *message;
|
||||||
|
|
||||||
|
@@ -1249,6 +1250,20 @@ dm_queue_if_no_path(const char *mapname, int enable)
|
||||||
|
return dm_message(mapname, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int dm_queue_if_no_path(struct multipath *mpp, int enable)
|
||||||
|
+{
|
||||||
|
+ int r;
|
||||||
|
+ static const char no_path_retry[] = "queue_if_no_path";
|
||||||
|
+
|
||||||
|
+ if ((r = _dm_queue_if_no_path(mpp->alias, enable)) == 0) {
|
||||||
|
+ if (enable)
|
||||||
|
+ add_feature(&mpp->features, no_path_retry);
|
||||||
|
+ else
|
||||||
|
+ remove_feature(&mpp->features, no_path_retry);
|
||||||
|
+ }
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
dm_groupmsg (const char * msg, const char * mapname, int index)
|
||||||
|
{
|
||||||
|
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||||
|
index 808da28d..41b8c31d 100644
|
||||||
|
--- a/libmultipath/devmapper.h
|
||||||
|
+++ b/libmultipath/devmapper.h
|
||||||
|
@@ -58,7 +58,7 @@ int dm_cancel_deferred_remove(struct multipath *mpp);
|
||||||
|
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);
|
||||||
|
+int dm_queue_if_no_path(struct multipath *mpp, int enable);
|
||||||
|
int dm_switchgroup(const char * mapname, int index);
|
||||||
|
int dm_enablegroup(const char * mapname, int index);
|
||||||
|
int dm_disablegroup(const char * mapname, int index);
|
||||||
|
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||||
|
index 86ad89ca..56915e96 100644
|
||||||
|
--- a/libmultipath/structs_vec.c
|
||||||
|
+++ b/libmultipath/structs_vec.c
|
||||||
|
@@ -579,7 +579,7 @@ static void leave_recovery_mode(struct multipath *mpp)
|
||||||
|
*/
|
||||||
|
if (recovery && (mpp->no_path_retry == NO_PATH_RETRY_QUEUE ||
|
||||||
|
mpp->no_path_retry > 0)) {
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 1);
|
||||||
|
+ dm_queue_if_no_path(mpp, 1);
|
||||||
|
condlog(2, "%s: queue_if_no_path enabled", mpp->alias);
|
||||||
|
condlog(1, "%s: Recovered to normal mode", mpp->alias);
|
||||||
|
}
|
||||||
|
@@ -598,11 +598,11 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||||
|
break;
|
||||||
|
case NO_PATH_RETRY_FAIL:
|
||||||
|
if (!check_features || is_queueing)
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 0);
|
||||||
|
+ dm_queue_if_no_path(mpp, 0);
|
||||||
|
break;
|
||||||
|
case NO_PATH_RETRY_QUEUE:
|
||||||
|
if (!check_features || !is_queueing)
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 1);
|
||||||
|
+ dm_queue_if_no_path(mpp, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (count_active_paths(mpp) > 0) {
|
||||||
|
@@ -612,7 +612,7 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||||
|
*/
|
||||||
|
if ((!check_features || !is_queueing) &&
|
||||||
|
!mpp->in_recovery)
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 1);
|
||||||
|
+ dm_queue_if_no_path(mpp, 1);
|
||||||
|
leave_recovery_mode(mpp);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
@@ -623,7 +623,7 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||||
|
*/
|
||||||
|
if ((!check_features || is_queueing) &&
|
||||||
|
mpp->in_recovery && mpp->retry_tick == 0)
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 0);
|
||||||
|
+ dm_queue_if_no_path(mpp, 0);
|
||||||
|
if (pathcount(mpp, PATH_PENDING) == 0)
|
||||||
|
enter_recovery_mode(mpp);
|
||||||
|
}
|
||||||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||||
|
index 26be6dc3..74f8114c 100644
|
||||||
|
--- a/multipathd/main.c
|
||||||
|
+++ b/multipathd/main.c
|
||||||
|
@@ -502,7 +502,7 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||||
|
mpp->no_path_retry = NO_PATH_RETRY_FAIL;
|
||||||
|
mpp->disable_queueing = 1;
|
||||||
|
mpp->stat_map_failures++;
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 0);
|
||||||
|
+ dm_queue_if_no_path(mpp, 0);
|
||||||
|
}
|
||||||
|
r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||||
|
if (r) {
|
||||||
|
@@ -833,7 +833,7 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- dm_queue_if_no_path(alias, 0);
|
||||||
|
+ dm_queue_if_no_path(mpp, 0);
|
||||||
|
remove_map_and_stop_waiter(mpp, vecs);
|
||||||
|
out:
|
||||||
|
lock_cleanup_pop(vecs->lock);
|
||||||
|
@@ -2015,7 +2015,7 @@ retry_count_tick(vector mpvec)
|
||||||
|
condlog(4, "%s: Retrying.. No active path", mpp->alias);
|
||||||
|
if(--mpp->retry_tick == 0) {
|
||||||
|
mpp->stat_map_failures++;
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 0);
|
||||||
|
+ dm_queue_if_no_path(mpp, 0);
|
||||||
|
condlog(2, "%s: Disable queueing", mpp->alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3110,7 +3110,7 @@ static void cleanup_maps(struct vectors *vecs)
|
||||||
|
put_multipath_config(conf);
|
||||||
|
if (queue_without_daemon == QUE_NO_DAEMON_OFF)
|
||||||
|
vector_foreach_slot(vecs->mpvec, mpp, i)
|
||||||
|
- dm_queue_if_no_path(mpp->alias, 0);
|
||||||
|
+ dm_queue_if_no_path(mpp, 0);
|
||||||
|
remove_maps_and_stop_waiters(vecs);
|
||||||
|
vecs->mpvec = NULL;
|
||||||
|
}
|
54
SOURCES/0111-libmultipath-export-partmap_in_use.patch
Normal file
54
SOURCES/0111-libmultipath-export-partmap_in_use.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 25 Apr 2024 19:35:13 -0400
|
||||||
|
Subject: [PATCH] libmultipath: export partmap_in_use
|
||||||
|
|
||||||
|
A future commit will make use of this function
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/devmapper.c | 2 +-
|
||||||
|
libmultipath/devmapper.h | 1 +
|
||||||
|
libmultipath/libmultipath.version | 5 +++++
|
||||||
|
3 files changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||||
|
index 5711f0ee..4a66e2c4 100644
|
||||||
|
--- a/libmultipath/devmapper.c
|
||||||
|
+++ b/libmultipath/devmapper.c
|
||||||
|
@@ -1028,7 +1028,7 @@ has_partmap(const char *name __attribute__((unused)),
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int
|
||||||
|
+int
|
||||||
|
partmap_in_use(const char *name, void *data)
|
||||||
|
{
|
||||||
|
int part_count, *ret_count = (int *)data;
|
||||||
|
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||||
|
index 41b8c31d..88e0b114 100644
|
||||||
|
--- a/libmultipath/devmapper.h
|
||||||
|
+++ b/libmultipath/devmapper.h
|
||||||
|
@@ -48,6 +48,7 @@ int dm_get_map(const char *, unsigned long long *, char **);
|
||||||
|
int dm_get_status(const char *, char **);
|
||||||
|
int dm_type(const char *, char *);
|
||||||
|
int dm_is_mpath(const char *);
|
||||||
|
+int partmap_in_use(const char *name, void *data);
|
||||||
|
int _dm_flush_map (const char *, int, int, int, int);
|
||||||
|
int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
|
||||||
|
#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0)
|
||||||
|
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||||
|
index 1d018eab..40d9246d 100644
|
||||||
|
--- a/libmultipath/libmultipath.version
|
||||||
|
+++ b/libmultipath/libmultipath.version
|
||||||
|
@@ -302,3 +302,8 @@ LIBMULTIPATH_9.1.2 {
|
||||||
|
global:
|
||||||
|
cleanup_mutex;
|
||||||
|
} LIBMULTIPATH_9.1.1;
|
||||||
|
+
|
||||||
|
+LIBMULTIPATH_9.1.3 {
|
||||||
|
+global:
|
||||||
|
+ partmap_in_use;
|
||||||
|
+} LIBMULTIPATH_9.1.2;
|
@ -0,0 +1,346 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 25 Apr 2024 19:35:14 -0400
|
||||||
|
Subject: [PATCH] libmultipath: change flush_on_last_del to fix a multipathd
|
||||||
|
hang
|
||||||
|
|
||||||
|
Commit 9bd3482e ("multipathd: make flush_map() delete maps like the
|
||||||
|
multipath command") fixed an issue where deleting a queueing multipath
|
||||||
|
device through multipathd could hang because the multipath device had
|
||||||
|
outstanding IO, even though the only openers of it at the time of
|
||||||
|
deletion were the kpartx partition devices. However it is still possible
|
||||||
|
to hang multipathd, because autoremoving the device when all paths have
|
||||||
|
been deleted doesn't disable queueing. To reproduce this hang:
|
||||||
|
|
||||||
|
1. create a multipath device with a kpartx partition on top of it and
|
||||||
|
no_path_retry set to either "queue" or something long enough to run all
|
||||||
|
the commands in the reproducer before it disables queueing.
|
||||||
|
2. disable all the paths to the device with something like:
|
||||||
|
# echo offline > /sys/block/<path_dev>/device/state
|
||||||
|
3. Write directly to the multipath device with something like:
|
||||||
|
# dd if=/dev/zero of=/dev/mapper/<mpath_dev> bs=4K count=1
|
||||||
|
4. delete all the paths to the device with something like:
|
||||||
|
# echo 1 > /sys/block/<path_dev>/device/delete
|
||||||
|
|
||||||
|
Multipathd will hang trying to delete the kpartx device because, as the
|
||||||
|
last opener, it must flush the multipath device before closing it.
|
||||||
|
Because it hangs holding the vecs_lock, multipathd will never disable
|
||||||
|
queueing on the device, so it will hang forever, even if no_path_retry
|
||||||
|
is set to a number.
|
||||||
|
|
||||||
|
This hang can occur, even if deferred_remove is set. Since nothing has
|
||||||
|
the kpartx device opened, device-mapper does an immediate remove, which
|
||||||
|
will still hang. This means that even if deferred_remove is set,
|
||||||
|
multipathd still cannot delete a map while queueing is enabled. It must
|
||||||
|
either disable queueing or skip the autoremove.
|
||||||
|
|
||||||
|
Mulitpath can currently be configured to avoid this hang by setting
|
||||||
|
|
||||||
|
flush_on_last_del yes
|
||||||
|
|
||||||
|
However there are good reasons why users wouldn't want to set that. They
|
||||||
|
may need to be able to survive having all paths getting temporarily
|
||||||
|
deleted. I should note that this is a pretty rare corner case, since
|
||||||
|
multipath automatically sets dev_loss_tmo so that it should not trigger
|
||||||
|
before queueing is disabled.
|
||||||
|
|
||||||
|
This commit avoids the hang by changing the possible values for
|
||||||
|
flush_on_last_del to "never", "unused", and "always", and sets the
|
||||||
|
default to "unused". "always" works like "yes" did, "never" will not
|
||||||
|
disable queueing, and "unused" will only disable queueing if nothing has
|
||||||
|
the kpartx devices or the multipath device open. In order to be safe, if
|
||||||
|
the device has queue_if_no_paths set (and in case of "unused", the
|
||||||
|
device is in-use) the autoremove will be skipped. Also, instead of just
|
||||||
|
trusting the lack of "queue_if_no_paths" in the current mpp->features,
|
||||||
|
multipathd will tell the kernel to disable queueing, just to be sure it
|
||||||
|
actually is.
|
||||||
|
|
||||||
|
I chose "unused" as the default because this should generally only cause
|
||||||
|
multipathd to work differently from the users perspective when nothing
|
||||||
|
has the multipath device open but it is queueing and there is
|
||||||
|
outstanding IO. Without this change, it would have hung instead of
|
||||||
|
failing the outstanding IO. However, I do understand that an argument
|
||||||
|
could be made that "never" makes more sense as default, even though it
|
||||||
|
will cause multipathd to skip autoremoves in cases where it wouldn't
|
||||||
|
before. The change to the behavior of deffered_remove will be
|
||||||
|
noticeable, but skipping an autoremove is much better than hanging.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/defaults.h | 2 +-
|
||||||
|
libmultipath/dict.c | 72 +++++++++++++++++++++++++++++++++-----
|
||||||
|
libmultipath/dict.h | 1 +
|
||||||
|
libmultipath/hwtable.c | 6 ++--
|
||||||
|
libmultipath/propsel.c | 4 ++-
|
||||||
|
libmultipath/structs.h | 7 ++--
|
||||||
|
multipath/multipath.conf.5 | 20 ++++++++---
|
||||||
|
multipathd/main.c | 39 ++++++++++++++++-----
|
||||||
|
8 files changed, 122 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||||
|
index c3788bbc..5e77387e 100644
|
||||||
|
--- a/libmultipath/defaults.h
|
||||||
|
+++ b/libmultipath/defaults.h
|
||||||
|
@@ -41,7 +41,7 @@
|
||||||
|
#define DEFAULT_PRIO PRIO_CONST
|
||||||
|
#define DEFAULT_PRIO_ARGS ""
|
||||||
|
#define DEFAULT_CHECKER TUR
|
||||||
|
-#define DEFAULT_FLUSH FLUSH_DISABLED
|
||||||
|
+#define DEFAULT_FLUSH FLUSH_UNUSED
|
||||||
|
#define DEFAULT_USER_FRIENDLY_NAMES USER_FRIENDLY_NAMES_OFF
|
||||||
|
#define DEFAULT_FORCE_SYNC 0
|
||||||
|
#define UNSET_PARTITION_DELIM "/UNSET/"
|
||||||
|
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||||
|
index ce1b6c99..3c011ece 100644
|
||||||
|
--- a/libmultipath/dict.c
|
||||||
|
+++ b/libmultipath/dict.c
|
||||||
|
@@ -825,14 +825,70 @@ declare_def_snprint(checker_timeout, print_nonzero)
|
||||||
|
declare_def_handler(allow_usb_devices, set_yes_no)
|
||||||
|
declare_def_snprint(allow_usb_devices, print_yes_no)
|
||||||
|
|
||||||
|
-declare_def_handler(flush_on_last_del, set_yes_no_undef)
|
||||||
|
-declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH)
|
||||||
|
-declare_ovr_handler(flush_on_last_del, set_yes_no_undef)
|
||||||
|
-declare_ovr_snprint(flush_on_last_del, print_yes_no_undef)
|
||||||
|
-declare_hw_handler(flush_on_last_del, set_yes_no_undef)
|
||||||
|
-declare_hw_snprint(flush_on_last_del, print_yes_no_undef)
|
||||||
|
-declare_mp_handler(flush_on_last_del, set_yes_no_undef)
|
||||||
|
-declare_mp_snprint(flush_on_last_del, print_yes_no_undef)
|
||||||
|
+
|
||||||
|
+static const char * const flush_on_last_del_optvals[] = {
|
||||||
|
+ [FLUSH_NEVER] = "never",
|
||||||
|
+ [FLUSH_ALWAYS] = "always",
|
||||||
|
+ [FLUSH_UNUSED] = "unused",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+set_flush_on_last_del(vector strvec, void *ptr, const char *file, int line_nr)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ int *flush_val_ptr = (int *)ptr;
|
||||||
|
+ char *buff;
|
||||||
|
+
|
||||||
|
+ buff = set_value(strvec);
|
||||||
|
+ if (!buff)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ for (i = FLUSH_NEVER; i <= FLUSH_UNUSED; i++) {
|
||||||
|
+ if (flush_on_last_del_optvals[i] != NULL &&
|
||||||
|
+ !strcmp(buff, flush_on_last_del_optvals[i])) {
|
||||||
|
+ *flush_val_ptr = i;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (i > FLUSH_UNUSED) {
|
||||||
|
+ bool deprecated = true;
|
||||||
|
+ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0)
|
||||||
|
+ *flush_val_ptr = FLUSH_UNUSED;
|
||||||
|
+ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0)
|
||||||
|
+ *flush_val_ptr = FLUSH_ALWAYS;
|
||||||
|
+ else {
|
||||||
|
+ deprecated = false;
|
||||||
|
+ condlog(1, "%s line %d, invalid value for flush_on_last_del: \"%s\"",
|
||||||
|
+ file, line_nr, buff);
|
||||||
|
+ }
|
||||||
|
+ if (deprecated)
|
||||||
|
+ condlog(3, "%s line %d, \"%s\" is a deprecated value for flush_on_last_del and is treated as \"%s\"",
|
||||||
|
+ file, line_nr, buff,
|
||||||
|
+ flush_on_last_del_optvals[*flush_val_ptr]);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free(buff);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+print_flush_on_last_del(struct strbuf *buff, long v)
|
||||||
|
+{
|
||||||
|
+ if (v == FLUSH_UNDEF)
|
||||||
|
+ return 0;
|
||||||
|
+ return append_strbuf_quoted(buff, flush_on_last_del_optvals[(int)v]);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+declare_def_handler(flush_on_last_del, set_flush_on_last_del)
|
||||||
|
+declare_def_snprint_defint(flush_on_last_del, print_flush_on_last_del,
|
||||||
|
+ DEFAULT_FLUSH)
|
||||||
|
+declare_ovr_handler(flush_on_last_del, set_flush_on_last_del)
|
||||||
|
+declare_ovr_snprint(flush_on_last_del, print_flush_on_last_del)
|
||||||
|
+declare_hw_handler(flush_on_last_del, set_flush_on_last_del)
|
||||||
|
+declare_hw_snprint(flush_on_last_del, print_flush_on_last_del)
|
||||||
|
+declare_mp_handler(flush_on_last_del, set_flush_on_last_del)
|
||||||
|
+declare_mp_snprint(flush_on_last_del, print_flush_on_last_del)
|
||||||
|
|
||||||
|
declare_def_handler(user_friendly_names, set_yes_no_undef)
|
||||||
|
declare_def_snprint_defint(user_friendly_names, print_yes_no_undef,
|
||||||
|
diff --git a/libmultipath/dict.h b/libmultipath/dict.h
|
||||||
|
index d963b4ad..6b1aae5c 100644
|
||||||
|
--- a/libmultipath/dict.h
|
||||||
|
+++ b/libmultipath/dict.h
|
||||||
|
@@ -20,4 +20,5 @@ 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);
|
||||||
|
+int print_flush_on_last_del(struct strbuf *buff, long v);
|
||||||
|
#endif /* _DICT_H */
|
||||||
|
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||||
|
index 78ac7988..94012d50 100644
|
||||||
|
--- a/libmultipath/hwtable.c
|
||||||
|
+++ b/libmultipath/hwtable.c
|
||||||
|
@@ -60,7 +60,7 @@
|
||||||
|
.no_path_retry = NO_PATH_RETRY_UNDEF,
|
||||||
|
.minio = 1000,
|
||||||
|
.minio_rq = 1,
|
||||||
|
- .flush_on_last_del = FLUSH_DISABLED,
|
||||||
|
+ .flush_on_last_del = FLUSH_UNUSED,
|
||||||
|
.user_friendly_names = USER_FRIENDLY_NAMES_OFF,
|
||||||
|
.fast_io_fail = 5,
|
||||||
|
.dev_loss = 600,
|
||||||
|
@@ -800,7 +800,7 @@ static struct hwentry default_hw[] = {
|
||||||
|
.no_path_retry = NO_PATH_RETRY_QUEUE,
|
||||||
|
.pgpolicy = GROUP_BY_PRIO,
|
||||||
|
.pgfailback = -FAILBACK_IMMEDIATE,
|
||||||
|
- .flush_on_last_del = FLUSH_ENABLED,
|
||||||
|
+ .flush_on_last_del = FLUSH_ALWAYS,
|
||||||
|
.dev_loss = MAX_DEV_LOSS_TMO,
|
||||||
|
.prio_name = PRIO_ONTAP,
|
||||||
|
.user_friendly_names = USER_FRIENDLY_NAMES_OFF,
|
||||||
|
@@ -1122,7 +1122,7 @@ static struct hwentry default_hw[] = {
|
||||||
|
.no_path_retry = NO_PATH_RETRY_FAIL,
|
||||||
|
.minio = 1,
|
||||||
|
.minio_rq = 1,
|
||||||
|
- .flush_on_last_del = FLUSH_ENABLED,
|
||||||
|
+ .flush_on_last_del = FLUSH_ALWAYS,
|
||||||
|
.fast_io_fail = 15,
|
||||||
|
.dev_loss = 15,
|
||||||
|
},
|
||||||
|
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||||
|
index 9dea6f92..be781ff7 100644
|
||||||
|
--- a/libmultipath/propsel.c
|
||||||
|
+++ b/libmultipath/propsel.c
|
||||||
|
@@ -902,6 +902,7 @@ out:
|
||||||
|
int select_flush_on_last_del(struct config *conf, struct multipath *mp)
|
||||||
|
{
|
||||||
|
const char *origin;
|
||||||
|
+ STRBUF_ON_STACK(buff);
|
||||||
|
|
||||||
|
mp_set_mpe(flush_on_last_del);
|
||||||
|
mp_set_ovr(flush_on_last_del);
|
||||||
|
@@ -909,8 +910,9 @@ int select_flush_on_last_del(struct config *conf, struct multipath *mp)
|
||||||
|
mp_set_conf(flush_on_last_del);
|
||||||
|
mp_set_default(flush_on_last_del, DEFAULT_FLUSH);
|
||||||
|
out:
|
||||||
|
+ print_flush_on_last_del(&buff, mp->flush_on_last_del);
|
||||||
|
condlog(3, "%s: flush_on_last_del = %s %s", mp->alias,
|
||||||
|
- (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin);
|
||||||
|
+ get_strbuf_str(&buff), origin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||||
|
index d2ad4867..4bf8c93a 100644
|
||||||
|
--- a/libmultipath/structs.h
|
||||||
|
+++ b/libmultipath/structs.h
|
||||||
|
@@ -109,9 +109,10 @@ enum marginal_pathgroups_mode {
|
||||||
|
};
|
||||||
|
|
||||||
|
enum flush_states {
|
||||||
|
- FLUSH_UNDEF = YNU_UNDEF,
|
||||||
|
- FLUSH_DISABLED = YNU_NO,
|
||||||
|
- FLUSH_ENABLED = YNU_YES,
|
||||||
|
+ FLUSH_UNDEF,
|
||||||
|
+ FLUSH_NEVER,
|
||||||
|
+ FLUSH_ALWAYS,
|
||||||
|
+ FLUSH_UNUSED,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum log_checker_err_states {
|
||||||
|
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||||
|
index 38eb5c90..10eddc0c 100644
|
||||||
|
--- a/multipath/multipath.conf.5
|
||||||
|
+++ b/multipath/multipath.conf.5
|
||||||
|
@@ -672,12 +672,22 @@ The default is: \fBno\fR
|
||||||
|
.TP
|
||||||
|
.B flush_on_last_del
|
||||||
|
If set to
|
||||||
|
-.I yes
|
||||||
|
+.I always
|
||||||
|
, multipathd will disable queueing when the last path to a device has been
|
||||||
|
-deleted.
|
||||||
|
-.RS
|
||||||
|
-.TP
|
||||||
|
-The default is: \fBno\fR
|
||||||
|
+deleted. If set to
|
||||||
|
+.I never
|
||||||
|
+, multipathd will not disable queueing when the last path to a device has
|
||||||
|
+been deleted. Since multipath cannot safely remove a device while queueing
|
||||||
|
+is enabled, setting this to \fInever\fR means that multipathd will not
|
||||||
|
+automatically remove an unused multipath device whose paths are all deleted if
|
||||||
|
+it is currently set to queue_if_no_path. If set to
|
||||||
|
+.I unused
|
||||||
|
+, multipathd will only disable queueing when the last path is removed if
|
||||||
|
+nothing currently has the multipath device or any of the kpartx partition
|
||||||
|
+devices on top of it open.
|
||||||
|
+.RS
|
||||||
|
+.TP
|
||||||
|
+The default is: \fBunused\fR
|
||||||
|
.RE
|
||||||
|
.
|
||||||
|
.
|
||||||
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||||
|
index 74f8114c..8ec58f5d 100644
|
||||||
|
--- a/multipathd/main.c
|
||||||
|
+++ b/multipathd/main.c
|
||||||
|
@@ -491,19 +491,42 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset)
|
||||||
|
static bool
|
||||||
|
flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||||
|
int r;
|
||||||
|
+ bool is_queueing = true;
|
||||||
|
|
||||||
|
+ if (mpp->features)
|
||||||
|
+ is_queueing = strstr(mpp->features, "queue_if_no_path");
|
||||||
|
+
|
||||||
|
+ /* It's not safe to do a remove of a map that has "queue_if_no_path"
|
||||||
|
+ * set, since there could be outstanding IO which will cause
|
||||||
|
+ * multipathd to hang while attempting the remove */
|
||||||
|
+ if (mpp->flush_on_last_del == FLUSH_NEVER && is_queueing) {
|
||||||
|
+ condlog(2, "%s: map is queueing, can't remove", mpp->alias);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (mpp->flush_on_last_del == FLUSH_UNUSED &&
|
||||||
|
+ partmap_in_use(mpp->alias, NULL) && is_queueing) {
|
||||||
|
+ condlog(2, "%s: map in use and queueing, can't remove",
|
||||||
|
+ mpp->alias);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
/*
|
||||||
|
- * flush_map will fail if the device is open
|
||||||
|
+ * This will flush FLUSH_NEVER devices and FLUSH_UNUSED devices
|
||||||
|
+ * that are in use, but only if they are already marked as not
|
||||||
|
+ * queueing. That is just to make absolutely certain that they
|
||||||
|
+ * really are not queueing, like they claim.
|
||||||
|
*/
|
||||||
|
- if (mpp->flush_on_last_del == FLUSH_ENABLED) {
|
||||||
|
- condlog(2, "%s Last path deleted, disabling queueing",
|
||||||
|
+ condlog(is_queueing ? 2 : 3, "%s Last path deleted, disabling queueing",
|
||||||
|
+ mpp->alias);
|
||||||
|
+ mpp->retry_tick = 0;
|
||||||
|
+ mpp->no_path_retry = NO_PATH_RETRY_FAIL;
|
||||||
|
+ mpp->disable_queueing = 1;
|
||||||
|
+ mpp->stat_map_failures++;
|
||||||
|
+ if (dm_queue_if_no_path(mpp, 0) != 0) {
|
||||||
|
+ condlog(0, "%s: failed to disable queueing. Not removing",
|
||||||
|
mpp->alias);
|
||||||
|
- mpp->retry_tick = 0;
|
||||||
|
- mpp->no_path_retry = NO_PATH_RETRY_FAIL;
|
||||||
|
- mpp->disable_queueing = 1;
|
||||||
|
- mpp->stat_map_failures++;
|
||||||
|
- dm_queue_if_no_path(mpp, 0);
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||||
|
if (r) {
|
||||||
|
if (r == 1)
|
@ -0,0 +1,40 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 25 Apr 2024 19:35:16 -0400
|
||||||
|
Subject: [PATCH] libmultipath: pad dev_loss_tmo to avoid race with
|
||||||
|
no_path_retry
|
||||||
|
|
||||||
|
Currently multipath makes sure that dev_loss_tmo is at least as long as
|
||||||
|
the configured no path queueing time. The goal is to make sure that path
|
||||||
|
devices aren't removed while the multipath device is still queueing in
|
||||||
|
hopes that they will become usable again.
|
||||||
|
|
||||||
|
This is racy. Multipathd may take longer to check the paths than
|
||||||
|
configured. If strict_timing isn't set, it will definitely take longer.
|
||||||
|
To account for this, pad the minimum dev_loss_tmo value by five seconds
|
||||||
|
(one default checker interval) plus one second per minute of no path
|
||||||
|
queueing time.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/discovery.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||||
|
index ae7eb7e6..b24594cd 100644
|
||||||
|
--- a/libmultipath/discovery.c
|
||||||
|
+++ b/libmultipath/discovery.c
|
||||||
|
@@ -884,6 +884,11 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp)
|
||||||
|
uint64_t no_path_retry_tmo =
|
||||||
|
(uint64_t)mpp->no_path_retry * conf->checkint;
|
||||||
|
|
||||||
|
+ /* pad no_path_retry_tmo by one standard check interval
|
||||||
|
+ * plus one second per minute to account for timing
|
||||||
|
+ * issues with the rechecks */
|
||||||
|
+ no_path_retry_tmo += no_path_retry_tmo / 60 + DEFAULT_CHECKINT;
|
||||||
|
+
|
||||||
|
if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
|
||||||
|
min_dev_loss = MAX_DEV_LOSS_TMO;
|
||||||
|
else
|
@ -0,0 +1,32 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nitin Yewale <nyewale@redhat.com>
|
||||||
|
Date: Thu, 12 Jan 2023 14:28:49 -0600
|
||||||
|
Subject: [PATCH] libmultipath: remove pathgroup wildcard options
|
||||||
|
|
||||||
|
The multipathd command "multipathd show wildcards" shows the pathgroup
|
||||||
|
format wildcards, but there is no way to use them in a multipathd
|
||||||
|
command.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/print.c | 7 -------
|
||||||
|
1 file changed, 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||||
|
index 082e4e30..a6e4c774 100644
|
||||||
|
--- a/libmultipath/print.c
|
||||||
|
+++ b/libmultipath/print.c
|
||||||
|
@@ -803,13 +803,6 @@ int snprint_wildcards(struct strbuf *buff)
|
||||||
|
pd[i].wildcard, pd[i].header)) < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
- if ((rc = append_strbuf_str(buff, "\npathgroup format wildcards:\n")) < 0)
|
||||||
|
- return rc;
|
||||||
|
- for (i = 0; pgd[i].header; i++)
|
||||||
|
- if ((rc = print_strbuf(buff, "%%%c %s\n",
|
||||||
|
- pgd[i].wildcard, pgd[i].header)) < 0)
|
||||||
|
- return rc;
|
||||||
|
-
|
||||||
|
return get_strbuf_len(buff) - initial_len;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Wed, 8 May 2024 19:02:30 -0400
|
||||||
|
Subject: [PATCH] libmultipath: print all values in snprint_failback
|
||||||
|
|
||||||
|
Add the missing output for manual failback and print the defferral time
|
||||||
|
for deferred failbacks, if one isn't currently in progress.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/print.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||||
|
index a6e4c774..535e0271 100644
|
||||||
|
--- a/libmultipath/print.c
|
||||||
|
+++ b/libmultipath/print.c
|
||||||
|
@@ -199,9 +199,13 @@ snprint_failback (struct strbuf *buff, const struct multipath * mpp)
|
||||||
|
return append_strbuf_str(buff, "immediate");
|
||||||
|
if (mpp->pgfailback == -FAILBACK_FOLLOWOVER)
|
||||||
|
return append_strbuf_str(buff, "followover");
|
||||||
|
+ if (mpp->pgfailback == -FAILBACK_MANUAL)
|
||||||
|
+ return append_strbuf_str(buff, "manual");
|
||||||
|
+ if (mpp->pgfailback == FAILBACK_UNDEF)
|
||||||
|
+ return append_strbuf_str(buff, "undef");
|
||||||
|
|
||||||
|
if (!mpp->failback_tick)
|
||||||
|
- return append_strbuf_str(buff, "-");
|
||||||
|
+ return print_strbuf(buff, "%i", mpp->pgfailback);
|
||||||
|
else
|
||||||
|
return snprint_progress(buff, mpp->failback_tick,
|
||||||
|
mpp->pgfailback);
|
@ -0,0 +1,34 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 9 May 2024 12:58:11 -0400
|
||||||
|
Subject: [PATCH] multipathd: Stop double counting map failures for
|
||||||
|
no_path_retry > 0
|
||||||
|
|
||||||
|
If no_path_retry was greater than 0, multipathd was counting a map
|
||||||
|
failure when recovery mode was entered, and again when queueing was
|
||||||
|
disabled. The first one is incorrect, since the map is still queueing.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/structs_vec.c | 5 ++++-
|
||||||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||||
|
index 56915e96..b8e304e0 100644
|
||||||
|
--- a/libmultipath/structs_vec.c
|
||||||
|
+++ b/libmultipath/structs_vec.c
|
||||||
|
@@ -781,10 +781,13 @@ int verify_paths(struct multipath *mpp)
|
||||||
|
void update_queue_mode_del_path(struct multipath *mpp)
|
||||||
|
{
|
||||||
|
int active = count_active_paths(mpp);
|
||||||
|
+ bool is_queueing = mpp->features &&
|
||||||
|
+ strstr(mpp->features, "queue_if_no_path");
|
||||||
|
|
||||||
|
if (active == 0) {
|
||||||
|
enter_recovery_mode(mpp);
|
||||||
|
- if (mpp->no_path_retry != NO_PATH_RETRY_QUEUE)
|
||||||
|
+ if (mpp->no_path_retry == NO_PATH_RETRY_FAIL ||
|
||||||
|
+ (mpp->no_path_retry == NO_PATH_RETRY_UNDEF && !is_queueing))
|
||||||
|
mpp->stat_map_failures++;
|
||||||
|
}
|
||||||
|
condlog(2, "%s: remaining active paths: %d", mpp->alias, active);
|
@ -0,0 +1,102 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 9 May 2024 17:15:34 -0400
|
||||||
|
Subject: [PATCH] multipath-tools man pages: add missing multipathd commands
|
||||||
|
|
||||||
|
Also, the description for "del map $map" was incorrect.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipathd/multipathd.8 | 42 ++++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 37 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||||
|
index 8bd47a80..40a8dc6d 100644
|
||||||
|
--- a/multipathd/multipathd.8
|
||||||
|
+++ b/multipathd/multipathd.8
|
||||||
|
@@ -100,18 +100,24 @@ The following commands can be used in interactive mode:
|
||||||
|
Show the paths that multipathd is monitoring, and their state.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
-.B list|show paths format $format
|
||||||
|
+.B list|show paths [raw] format $format
|
||||||
|
Show the paths that multipathd is monitoring, using a format string with path
|
||||||
|
-format wildcards.
|
||||||
|
+format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||||
|
+padding from the ouput.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
+.B list|show path $path
|
||||||
|
+Show whether path $path is offline or running.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show maps|multipaths
|
||||||
|
Show the multipath devices that the multipathd is monitoring.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
-.B list|show maps|multipaths format $format
|
||||||
|
+.B list|show maps|multipaths [raw] format $format
|
||||||
|
Show the status of all multipath devices that the multipathd is monitoring,
|
||||||
|
-using a format string with multipath format wildcards.
|
||||||
|
+using a format string with multipath format wildcards. Adding \fIraw\fR will
|
||||||
|
+remove the headers and alignment padding from the output.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show maps|multipaths status
|
||||||
|
@@ -124,6 +130,10 @@ Show some statistics of all multipath devices that the multipathd is monitoring.
|
||||||
|
.TP
|
||||||
|
.B list|show maps|multipaths topology
|
||||||
|
Show the current multipath topology. Same as '\fImultipath \-ll\fR'.
|
||||||
|
+.TP
|
||||||
|
+.
|
||||||
|
+.B list|show maps|multipaths json
|
||||||
|
+Show information about all multipath devices in JSON format.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show topology
|
||||||
|
@@ -135,6 +145,16 @@ Show topology of a single multipath device specified by $map, for example
|
||||||
|
36005076303ffc56200000000000010aa. This map could be obtained from '\fIlist maps\fR'.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
+.B list|show map|multipath $map [raw] format $format.
|
||||||
|
+Show the status of multipath device $map, using a format string with multipath
|
||||||
|
+format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||||
|
+padding from the output.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
+.B list|show map|multipath $map json
|
||||||
|
+Show information about multipath device $map in JSON format.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
.B list|show wildcards
|
||||||
|
Show the format wildcards used in interactive commands taking $format.
|
||||||
|
.
|
||||||
|
@@ -168,6 +188,14 @@ paths, and whether multipathd is currently handling a uevent.
|
||||||
|
Show the current state of the multipathd daemon.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
+.B reset maps|multipaths stats
|
||||||
|
+Reset the statistics of all multipath devices.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
+.B reset map|multipath $map stats
|
||||||
|
+Reset the statistics of multipath device $map.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
.B add path $path
|
||||||
|
Add a path to the list of monitored paths. $path is as listed in /sys/block (e.g. sda).
|
||||||
|
.
|
||||||
|
@@ -183,8 +211,12 @@ for the multipath device (e.g. mpath1) or the uid of the multipath device
|
||||||
|
(e.g. 36005076303ffc56200000000000010aa).
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
+.B remove|del maps|multipaths
|
||||||
|
+Remove all multipath devices.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
.B remove|del map|multipath $map
|
||||||
|
-Stop monitoring a multipath device.
|
||||||
|
+Remove the multipath device $map.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B resize map|multipath $map
|
@ -0,0 +1,54 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 10 May 2024 15:36:10 -0400
|
||||||
|
Subject: [PATCH] libmultipath: change the vend/prod/rev printing
|
||||||
|
|
||||||
|
The %s multipath and path wildcards both say they print the device
|
||||||
|
vend/prod/rev string, but neither of them do. The multipath wildcards
|
||||||
|
already provide a way to print the revision string and the %s wildcard
|
||||||
|
is used in the multipath -l output, so leave the wildcard output alone,
|
||||||
|
and change the description to only mention the vendor and product. There
|
||||||
|
is no other way to print the revision by path, and the path %s wildcard
|
||||||
|
is only used in the verbose multipath output, so make it actually print
|
||||||
|
the revision. Also check for unset strings, and print "##" instead of
|
||||||
|
nothing.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/print.c | 9 ++++++---
|
||||||
|
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||||
|
index 535e0271..4552fd43 100644
|
||||||
|
--- a/libmultipath/print.c
|
||||||
|
+++ b/libmultipath/print.c
|
||||||
|
@@ -309,7 +309,7 @@ snprint_multipath_uuid (struct strbuf *buff, const struct multipath * mpp)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-snprint_multipath_vpr (struct strbuf *buff, const struct multipath * mpp)
|
||||||
|
+snprint_multipath_vp (struct strbuf *buff, const struct multipath * mpp)
|
||||||
|
{
|
||||||
|
struct pathgroup * pgp;
|
||||||
|
struct path * pp;
|
||||||
|
@@ -511,7 +511,10 @@ snprint_dm_path_state (struct strbuf *buff, const struct path * pp)
|
||||||
|
static int
|
||||||
|
snprint_vpr (struct strbuf *buff, const struct path * pp)
|
||||||
|
{
|
||||||
|
- return print_strbuf(buff, "%s,%s", pp->vendor_id, pp->product_id);
|
||||||
|
+ return print_strbuf(buff, "%s,%s,%s",
|
||||||
|
+ strlen(pp->vendor_id) ? pp->vendor_id : "##",
|
||||||
|
+ strlen(pp->product_id) ? pp->product_id : "##",
|
||||||
|
+ strlen(pp->rev) ? pp->rev : "##");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -743,7 +746,7 @@ struct multipath_data mpd[] = {
|
||||||
|
{'2', "map_loads", 0, snprint_map_loads},
|
||||||
|
{'3', "total_q_time", 0, snprint_total_q_time},
|
||||||
|
{'4', "q_timeouts", 0, snprint_q_timeouts},
|
||||||
|
- {'s', "vend/prod/rev", 0, snprint_multipath_vpr},
|
||||||
|
+ {'s', "vend/prod", 0, snprint_multipath_vp},
|
||||||
|
{'v', "vend", 0, snprint_multipath_vend},
|
||||||
|
{'p', "prod", 0, snprint_multipath_prod},
|
||||||
|
{'e', "rev", 0, snprint_multipath_rev},
|
@ -0,0 +1,243 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 10 May 2024 20:53:33 -0400
|
||||||
|
Subject: [PATCH] multipath-tools man pages: Add format wildcard descriptions
|
||||||
|
|
||||||
|
Suggested-by: Nitin Yewale <nyewale@redhat.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipathd/multipathd.8 | 193 +++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 189 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||||
|
index 40a8dc6d..d834f89e 100644
|
||||||
|
--- a/multipathd/multipathd.8
|
||||||
|
+++ b/multipathd/multipathd.8
|
||||||
|
@@ -103,7 +103,7 @@ Show the paths that multipathd is monitoring, and their state.
|
||||||
|
.B list|show paths [raw] format $format
|
||||||
|
Show the paths that multipathd is monitoring, using a format string with path
|
||||||
|
format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||||
|
-padding from the ouput.
|
||||||
|
+padding from the output. See "Path format wildcards" below.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show path $path
|
||||||
|
@@ -117,7 +117,8 @@ Show the multipath devices that the multipathd is monitoring.
|
||||||
|
.B list|show maps|multipaths [raw] format $format
|
||||||
|
Show the status of all multipath devices that the multipathd is monitoring,
|
||||||
|
using a format string with multipath format wildcards. Adding \fIraw\fR will
|
||||||
|
-remove the headers and alignment padding from the output.
|
||||||
|
+remove the headers and alignment padding from the output. See "Multipath
|
||||||
|
+format wildcards" below.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show maps|multipaths status
|
||||||
|
@@ -148,7 +149,7 @@ Show topology of a single multipath device specified by $map, for example
|
||||||
|
.B list|show map|multipath $map [raw] format $format.
|
||||||
|
Show the status of multipath device $map, using a format string with multipath
|
||||||
|
format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||||
|
-padding from the output.
|
||||||
|
+padding from the output. See "Multipath format wildcards" below.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show map|multipath $map json
|
||||||
|
@@ -156,7 +157,8 @@ Show information about multipath device $map in JSON format.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show wildcards
|
||||||
|
-Show the format wildcards used in interactive commands taking $format.
|
||||||
|
+Show the format wildcards used in interactive commands taking $format. See
|
||||||
|
+"Format Wildcards" below.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
.B list|show config
|
||||||
|
@@ -339,6 +341,189 @@ Stop multipathd.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.\" ----------------------------------------------------------------------------
|
||||||
|
+.SH "Format Wildcards"
|
||||||
|
+.\" ----------------------------------------------------------------------------
|
||||||
|
+.
|
||||||
|
+Multipathd commands that take a $format option require a format string. This
|
||||||
|
+string controls how a device is printed and should include format wildcards.
|
||||||
|
+When the devices are printed, these wildcards will be replaced by the
|
||||||
|
+appropriate device information. The following wildcards are supported.
|
||||||
|
+.TP
|
||||||
|
+.B Multipath format wildcards
|
||||||
|
+.RS
|
||||||
|
+.TP 12
|
||||||
|
+.B %n
|
||||||
|
+The device name.
|
||||||
|
+.TP
|
||||||
|
+.B %w
|
||||||
|
+The device WWID (uuid).
|
||||||
|
+.TP
|
||||||
|
+.B %d
|
||||||
|
+The device sysfs name (dm-<minor_nr>).
|
||||||
|
+.TP
|
||||||
|
+.B %F
|
||||||
|
+The device \fBfailback\fR setting. For deferred failbacks, it will either
|
||||||
|
+print the configured time if a deferred failback is not in progress, or
|
||||||
|
+it will show the current progress of a deferred failback.
|
||||||
|
+.TP
|
||||||
|
+.B %Q
|
||||||
|
+The device \fBno_path_retry\fR setting. If no_path_retry is set to a
|
||||||
|
+number of retires, it will either print the configured number of checker
|
||||||
|
+retries if the device is not in recovery mode, the number of seconds until
|
||||||
|
+queueing is disabled if the device is queueing in recovery mode, or \fIoff\fR
|
||||||
|
+if the device has disabled queueing.
|
||||||
|
+.TP
|
||||||
|
+.B %N
|
||||||
|
+The number of active paths for the device.
|
||||||
|
+.TP
|
||||||
|
+.B %r
|
||||||
|
+The device write-protect setting, either \fIro\fR or \fIrw\fR.
|
||||||
|
+.TP
|
||||||
|
+.B %t
|
||||||
|
+The device-mapper state of the device, either \fIsuspend\fR or \fIactive\fR.
|
||||||
|
+.TP
|
||||||
|
+.B %S
|
||||||
|
+The device size.
|
||||||
|
+.TP
|
||||||
|
+.B %f
|
||||||
|
+The device table features string.
|
||||||
|
+.TP
|
||||||
|
+.B %x
|
||||||
|
+The number of times the device has entered a state where it will fail IO.
|
||||||
|
+This is an alias for the \fB%4\fR wildcard.
|
||||||
|
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||||
|
+.TP
|
||||||
|
+.B %h
|
||||||
|
+The device table hardware handler string.
|
||||||
|
+.TP
|
||||||
|
+.B %A
|
||||||
|
+The last action multipathd took on the device. This wildcard is for debugging
|
||||||
|
+use, as understanding its meaning requires looking at the code.
|
||||||
|
+.TP
|
||||||
|
+.B %0
|
||||||
|
+The number of times a path in the device has failed.
|
||||||
|
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||||
|
+.TP
|
||||||
|
+.B %1
|
||||||
|
+The number of times multipathd has initiated a pathgroup switch for the device.
|
||||||
|
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||||
|
+.TP
|
||||||
|
+.B %2
|
||||||
|
+The number of times multipathd has loaded a new table for the device.
|
||||||
|
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||||
|
+.TP
|
||||||
|
+.B %3
|
||||||
|
+The approximate number of seconds that multipathd has spent queueing with
|
||||||
|
+no usable paths. This value can be reset with the '\fIreset map $map stats\fR'
|
||||||
|
+command.
|
||||||
|
+.TP
|
||||||
|
+.B %4
|
||||||
|
+The number of times the device has entered a state where it will fail IO.
|
||||||
|
+This is an alias for the \fB%x\fR wildcard.
|
||||||
|
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||||
|
+.TP
|
||||||
|
+.B %s
|
||||||
|
+The vendor/product string for the device.
|
||||||
|
+.TP
|
||||||
|
+.B %v
|
||||||
|
+The array vendor string for the device.
|
||||||
|
+.TP
|
||||||
|
+.B %p
|
||||||
|
+The array product string for the device.
|
||||||
|
+.TP
|
||||||
|
+.B %e
|
||||||
|
+The array firmware revision string for the device.
|
||||||
|
+.TP
|
||||||
|
+.B %G
|
||||||
|
+The foreign library used for the device, or \fB--\fR for native device-mapper
|
||||||
|
+multipath devices.
|
||||||
|
+.TP
|
||||||
|
+.B %g
|
||||||
|
+Data from vendor specific vpd pages for the device, if any.
|
||||||
|
+.RE
|
||||||
|
+.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
+.B Path format wildcards
|
||||||
|
+.RS
|
||||||
|
+.TP 12
|
||||||
|
+.B %w
|
||||||
|
+The device WWID (uuid).
|
||||||
|
+.TP
|
||||||
|
+.B %i
|
||||||
|
+The device Host:Channel:Id:Lun
|
||||||
|
+.TP
|
||||||
|
+.B %d
|
||||||
|
+The device sysfs name.
|
||||||
|
+.TP
|
||||||
|
+.B %D
|
||||||
|
+The device major:minor
|
||||||
|
+.TP
|
||||||
|
+.B %t
|
||||||
|
+The device-mapper state of the device, either \fIactive\fR or \fIfailed\fR.
|
||||||
|
+.TP
|
||||||
|
+.B %o
|
||||||
|
+Whether the device is \fIoffline\fR or \fIrunning\fR.
|
||||||
|
+.TP
|
||||||
|
+.B %T
|
||||||
|
+The multipathd path checker state of the device.
|
||||||
|
+.TP
|
||||||
|
+.B %s
|
||||||
|
+The vendor/product/revision string for the device.
|
||||||
|
+.TP
|
||||||
|
+.B %c
|
||||||
|
+The device's path checker name.
|
||||||
|
+.TP
|
||||||
|
+.B %C
|
||||||
|
+The progress towards the next path checker run on the device.
|
||||||
|
+.TP
|
||||||
|
+.B %p
|
||||||
|
+The device priority.
|
||||||
|
+.TP
|
||||||
|
+.B %S
|
||||||
|
+The device size.
|
||||||
|
+.TP
|
||||||
|
+.B %z
|
||||||
|
+The device serial number.
|
||||||
|
+.TP
|
||||||
|
+.B %M
|
||||||
|
+The device marginal state, either \fImarginal\fR or \fInormal\fR.
|
||||||
|
+.TP
|
||||||
|
+.B %m
|
||||||
|
+The multipath device that this device is a path of.
|
||||||
|
+.TP
|
||||||
|
+.B %N
|
||||||
|
+The host World Wide Node Name (WWNN) of the device.
|
||||||
|
+.TP
|
||||||
|
+.B %n
|
||||||
|
+The target World Wide Node Name (WWNN) of the device.
|
||||||
|
+.TP
|
||||||
|
+.B %R
|
||||||
|
+The host World Wide Port Name (WWPN) of the device.
|
||||||
|
+.TP
|
||||||
|
+.B %r
|
||||||
|
+The target World Wide Port Name (WWPN) of the device.
|
||||||
|
+.TP
|
||||||
|
+.B %a
|
||||||
|
+The host adapter name for the device (only SCSI devices).
|
||||||
|
+.TP
|
||||||
|
+.B %G
|
||||||
|
+The foreign library used for the device, or \fB--\fR for paths of native
|
||||||
|
+device-mapper multipath devices.
|
||||||
|
+.TP
|
||||||
|
+.B %g
|
||||||
|
+Data from vendor specific vpd pages for the device, if any.
|
||||||
|
+.TP
|
||||||
|
+.B %0
|
||||||
|
+The number of times this device has failed.
|
||||||
|
+.TP
|
||||||
|
+.B %P
|
||||||
|
+The device protocol. This output can be used for \fIprotocol\fR blacklist
|
||||||
|
+entries.
|
||||||
|
+.RE
|
||||||
|
+.
|
||||||
|
+.
|
||||||
|
+.\" ----------------------------------------------------------------------------
|
||||||
|
.SH "SYSTEMD INTEGRATION"
|
||||||
|
.\" ----------------------------------------------------------------------------
|
||||||
|
.
|
@ -0,0 +1,103 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: chengjike <chengjike.cheng@huawei.com>
|
||||||
|
Date: Fri, 8 Oct 2021 20:24:49 +0800
|
||||||
|
Subject: [PATCH] multipath-tools: fix "multipath -ll" bug for Native NVME
|
||||||
|
Multipath devices
|
||||||
|
|
||||||
|
After "Native NVME Multipath" is configured,
|
||||||
|
the content displayed is incorrect when you run "multipath -ll" command.
|
||||||
|
Each NVME devices have the same path name. For example:
|
||||||
|
|
||||||
|
[root@localhost home]# multipath -ll
|
||||||
|
eui.710032e8fb22a86c24a52c1000000db8 [nvme]:nvme1n1 NVMe,Huawei-XSG1,1000001
|
||||||
|
size=10485760 features='n/a' hwhandler='ANA' wp=rw
|
||||||
|
|-+- policy='n/a' prio=50 status=optimized
|
||||||
|
| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live
|
||||||
|
`-+- policy='n/a' prio=50 status=optimized
|
||||||
|
`- 1:9:1 nvme1c9n1 0:0 n/a optimized live
|
||||||
|
eui.710032e8fb22a86b24a52c7c00000db7 [nvme]:nvme1n2 NVMe,Huawei-XSG1,1000001
|
||||||
|
size=10485760 features='n/a' hwhandler='ANA' wp=rw
|
||||||
|
|-+- policy='n/a' prio=50 status=optimized
|
||||||
|
| `- 1:4:1 nvme1c4n1 0:0 n/a optimized live
|
||||||
|
`-+- policy='n/a' prio=50 status=optimized
|
||||||
|
`- 1:9:1 nvme1c9n1 0:0 n/a optimized live
|
||||||
|
[root@localhost home]#
|
||||||
|
|
||||||
|
The logical paths of "nvme1n1" and "nvme1n2" are both "nvme1c4n1" and "nvme1c9n1".
|
||||||
|
So when multipath-tools aggregates disks, use "nvme_ns_head->instance" for matching.
|
||||||
|
such as ,Use "b" in "nvmeanb" string to match "z" in "nvmexcynz"(a,b,x,y,z can be any number),
|
||||||
|
and if "b" and "z" are the same, they are related.
|
||||||
|
|
||||||
|
Signed-off-by: chengjike <chengjike.cheng@huawei.com>
|
||||||
|
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/foreign/nvme.c | 26 ++++++++++++++++++++------
|
||||||
|
1 file changed, 20 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c
|
||||||
|
index 23355ca5..76b57283 100644
|
||||||
|
--- a/libmultipath/foreign/nvme.c
|
||||||
|
+++ b/libmultipath/foreign/nvme.c
|
||||||
|
@@ -530,14 +530,18 @@ static int _dirent_controller(const struct dirent *di)
|
||||||
|
|
||||||
|
/* Find the block device for a given nvme controller */
|
||||||
|
struct udev_device *get_ctrl_blkdev(const struct context *ctx,
|
||||||
|
- struct udev_device *ctrl)
|
||||||
|
+ struct udev_device *ctrl, const char *ctrl_name)
|
||||||
|
{
|
||||||
|
+ int ctrl_num, ns_num;
|
||||||
|
struct udev_list_entry *item;
|
||||||
|
struct udev_device *blkdev = NULL;
|
||||||
|
struct udev_enumerate *enm = udev_enumerate_new(ctx->udev);
|
||||||
|
const char *devtype;
|
||||||
|
|
||||||
|
- if (enm == NULL)
|
||||||
|
+ if (enm == NULL || ctrl_name == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (sscanf(ctrl_name, "nvme%dn%d", &ctrl_num, &ns_num) != 2)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pthread_cleanup_push(_udev_enumerate_unref, enm);
|
||||||
|
@@ -555,6 +559,8 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx,
|
||||||
|
item != NULL;
|
||||||
|
item = udev_list_entry_get_next(item)) {
|
||||||
|
struct udev_device *tmp;
|
||||||
|
+ const char *name = NULL ;
|
||||||
|
+ int m, n, l;
|
||||||
|
|
||||||
|
tmp = udev_device_new_from_syspath(ctx->udev,
|
||||||
|
udev_list_entry_get_name(item));
|
||||||
|
@@ -562,11 +568,19 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx,
|
||||||
|
continue;
|
||||||
|
|
||||||
|
devtype = udev_device_get_devtype(tmp);
|
||||||
|
- if (devtype && !strcmp(devtype, "disk")) {
|
||||||
|
+ if (devtype == NULL || strcmp(devtype, "disk")) {
|
||||||
|
+ udev_device_unref(tmp);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ name = udev_device_get_sysname(tmp);
|
||||||
|
+ if (name != NULL &&
|
||||||
|
+ sscanf(name, "nvme%dc%dn%d", &m, &n, &l) == 3 &&
|
||||||
|
+ l == ns_num) {
|
||||||
|
blkdev = tmp;
|
||||||
|
break;
|
||||||
|
- } else
|
||||||
|
- udev_device_unref(tmp);
|
||||||
|
+ }
|
||||||
|
+ udev_device_unref(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blkdev == NULL)
|
||||||
|
@@ -679,7 +693,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map)
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cleanup_push(_udev_device_unref, ctrl);
|
||||||
|
- udev = get_ctrl_blkdev(ctx, ctrl);
|
||||||
|
+ udev = get_ctrl_blkdev(ctx, ctrl, udev_device_get_sysname(map->udev));
|
||||||
|
/*
|
||||||
|
* We give up the reference to the nvme device here and get
|
||||||
|
* it back from the child below.
|
@ -0,0 +1,29 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Wed, 24 Jul 2024 16:38:52 -0400
|
||||||
|
Subject: [PATCH] multipathd: set reply length to zero for NULL replies
|
||||||
|
|
||||||
|
The multipathd cli handlers add one to the reply length to account for
|
||||||
|
NULL byte, but if the reply is NULL, there is no NULL by to account for,
|
||||||
|
and len should be 0, so that mutipathd replies to clients with a
|
||||||
|
default reply.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
multipathd/cli.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/multipathd/cli.c b/multipathd/cli.c
|
||||||
|
index eb2e8c1d..03ad0d64 100644
|
||||||
|
--- a/multipathd/cli.c
|
||||||
|
+++ b/multipathd/cli.c
|
||||||
|
@@ -496,6 +496,9 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout )
|
||||||
|
r = h->fn(cmdvec, reply, len, data);
|
||||||
|
free_keys(cmdvec);
|
||||||
|
|
||||||
|
+ if (*reply == NULL)
|
||||||
|
+ *len = 0;
|
||||||
|
+
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
Name: device-mapper-multipath
|
Name: device-mapper-multipath
|
||||||
Version: 0.8.7
|
Version: 0.8.7
|
||||||
Release: 27%{?dist}
|
Release: 32%{?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/
|
||||||
@ -117,6 +117,20 @@ Patch0104: 0104-multipathd-disable-queueing-when-removing-unknown-ma.patch
|
|||||||
Patch0105: 0105-multipathd-fix-null-pointer-dereference-in-uev_updat.patch
|
Patch0105: 0105-multipathd-fix-null-pointer-dereference-in-uev_updat.patch
|
||||||
Patch0106: 0106-multipathd-fix-auto-resize-configuration.patch
|
Patch0106: 0106-multipathd-fix-auto-resize-configuration.patch
|
||||||
Patch0107: 0107-libmultipath-fix-displaying-auto_resize-config-setti.patch
|
Patch0107: 0107-libmultipath-fix-displaying-auto_resize-config-setti.patch
|
||||||
|
Patch0108: 0108-libmultipath-actually-truncate-too-large-vpd-page.patch
|
||||||
|
Patch0109: 0109-kpartx-fix-theoretical-overflow-in-loop-device-name.patch
|
||||||
|
Patch0110: 0110-libmultipath-keep-track-of-queueing-state-in-feature.patch
|
||||||
|
Patch0111: 0111-libmultipath-export-partmap_in_use.patch
|
||||||
|
Patch0112: 0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch
|
||||||
|
Patch0113: 0113-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch
|
||||||
|
Patch0114: 0114-libmultipath-remove-pathgroup-wildcard-options.patch
|
||||||
|
Patch0115: 0115-libmultipath-print-all-values-in-snprint_failback.patch
|
||||||
|
Patch0116: 0116-multipathd-Stop-double-counting-map-failures-for-no_.patch
|
||||||
|
Patch0117: 0117-multipath-tools-man-pages-add-missing-multipathd-com.patch
|
||||||
|
Patch0118: 0118-libmultipath-change-the-vend-prod-rev-printing.patch
|
||||||
|
Patch0119: 0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch
|
||||||
|
Patch0120: 0120-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch
|
||||||
|
Patch0121: 0121-multipathd-set-reply-length-to-zero-for-NULL-replies.patch
|
||||||
|
|
||||||
|
|
||||||
# runtime
|
# runtime
|
||||||
@ -320,6 +334,48 @@ fi
|
|||||||
%{_pkgconfdir}/libdmmp.pc
|
%{_pkgconfdir}/libdmmp.pc
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Aug 5 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-32
|
||||||
|
- Modify bindings, find_multipaths, and user_friendly_names tests
|
||||||
|
* Fixes RHEL-28068 & RHEL-4459
|
||||||
|
- Resolves: RHEL-28068
|
||||||
|
- Resolves: RHEL-44569
|
||||||
|
|
||||||
|
* Tue Jul 30 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-31
|
||||||
|
- Modify multiple tests especially medium_error_scsi_debug and squelch_scsi_id
|
||||||
|
* Fixes RHEL-28068 & RHEL-4459
|
||||||
|
- Resolves: RHEL-28068
|
||||||
|
- Resolves: RHEL-44569
|
||||||
|
|
||||||
|
* Tue Jul 30 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-30
|
||||||
|
- Add 0120-multipath-tools-fix-multipath-ll-bug-for-Native-NVME.patch
|
||||||
|
* Fixes RHEL-28068
|
||||||
|
- Add 0121-multipathd-set-reply-length-to-zero-for-NULL-replies.patch
|
||||||
|
* Fixes RHEL-44569
|
||||||
|
- Resolves: RHEL-28068
|
||||||
|
- Resolves: RHEL-44569
|
||||||
|
|
||||||
|
* Tue May 21 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-29
|
||||||
|
- Add 0110-libmultipath-keep-track-of-queueing-state-in-feature.patch
|
||||||
|
- Add 0111-libmultipath-export-partmap_in_use.patch
|
||||||
|
- Add 0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch
|
||||||
|
- Add 0113-libmultipath-pad-dev_loss_tmo-to-avoid-race-with-no_.patch
|
||||||
|
* Fixes RHEL-30272
|
||||||
|
- Add 0114-libmultipath-remove-pathgroup-wildcard-options.patch
|
||||||
|
- Add 0115-libmultipath-print-all-values-in-snprint_failback.patch
|
||||||
|
- Add 0116-multipathd-Stop-double-counting-map-failures-for-no_.patch
|
||||||
|
- Add 0117-multipath-tools-man-pages-add-missing-multipathd-com.patch
|
||||||
|
- Add 0118-libmultipath-change-the-vend-prod-rev-printing.patch
|
||||||
|
- Add 0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch
|
||||||
|
* Fixes RHEL-8304
|
||||||
|
- Resolves: RHEL-8304
|
||||||
|
- Resolves: RHEL-30272
|
||||||
|
|
||||||
|
* Tue Apr 9 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-28
|
||||||
|
- Add 0108-libmultipath-actually-truncate-too-large-vpd-page.patch
|
||||||
|
- Add 0109-kpartx-fix-theoretical-overflow-in-loop-device-name.patch
|
||||||
|
* Fixes RHEL-31793 ("RHEL SAST Automation: address (selected) true positives")
|
||||||
|
- Resolves: RHEL-31793
|
||||||
|
|
||||||
* Fri Jan 26 2024 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.7-27
|
* 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 0105-multipathd-fix-null-pointer-dereference-in-uev_updat.patch
|
||||||
- Add 0106-multipathd-fix-auto-resize-configuration.patch
|
- Add 0106-multipathd-fix-auto-resize-configuration.patch
|
||||||
|
Loading…
Reference in New Issue
Block a user