device-mapper-multipath-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
This commit is contained in:
parent
2d7060ef7c
commit
9ae3e98286
194
0110-libmultipath-keep-track-of-queueing-state-in-feature.patch
Normal file
194
0110-libmultipath-keep-track-of-queueing-state-in-feature.patch
Normal file
@ -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
0111-libmultipath-export-partmap_in_use.patch
Normal file
54
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;
|
346
0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch
Normal file
346
0112-libmultipath-change-flush_on_last_del-to-fix-a-multi.patch
Normal file
@ -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
|
32
0114-libmultipath-remove-pathgroup-wildcard-options.patch
Normal file
32
0114-libmultipath-remove-pathgroup-wildcard-options.patch
Normal file
@ -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;
|
||||
}
|
||||
|
32
0115-libmultipath-print-all-values-in-snprint_failback.patch
Normal file
32
0115-libmultipath-print-all-values-in-snprint_failback.patch
Normal file
@ -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);
|
102
0117-multipath-tools-man-pages-add-missing-multipathd-com.patch
Normal file
102
0117-multipath-tools-man-pages-add-missing-multipathd-com.patch
Normal file
@ -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
|
54
0118-libmultipath-change-the-vend-prod-rev-printing.patch
Normal file
54
0118-libmultipath-change-the-vend-prod-rev-printing.patch
Normal file
@ -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},
|
243
0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch
Normal file
243
0119-multipath-tools-man-pages-Add-format-wildcard-descri.patch
Normal file
@ -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"
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.
|
@ -1,6 +1,6 @@
|
||||
Name: device-mapper-multipath
|
||||
Version: 0.8.7
|
||||
Release: 28%{?dist}
|
||||
Release: 29%{?dist}
|
||||
Summary: Tools to manage multipath devices using device-mapper
|
||||
License: GPLv2
|
||||
URL: http://christophe.varoqui.free.fr/
|
||||
@ -119,6 +119,16 @@ Patch0106: 0106-multipathd-fix-auto-resize-configuration.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
|
||||
|
||||
|
||||
# runtime
|
||||
@ -322,6 +332,22 @@ fi
|
||||
%{_pkgconfdir}/libdmmp.pc
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user