import device-mapper-multipath-0.8.4-17.el8

This commit is contained in:
CentOS Sources 2021-11-09 05:04:13 -05:00 committed by Stepan Oksanichenko
parent 21a06b324d
commit 33978456d2
14 changed files with 1272 additions and 5 deletions

View File

@ -0,0 +1,129 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lixiaokeng <lixiaokeng@huawei.com>
Date: Mon, 21 Sep 2020 12:00:39 +0800
Subject: [PATCH] libmultipath: check udev_device_get_* return value to avoid
segfault
The udev_device_get_* function may return NULL, and it will be
deregerenced in str* and sscanf func. We check the return value
to avoid segfault. Fix all.
Reviewed-by: Martin Wilck <mwilck@suse.com>
Signed-off-by:Lixiaokeng<lixiaokeng@huawei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Signed-off-by: Linfeilong <linfeilong@huawei.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/configure.c | 4 +++-
libmultipath/discovery.c | 9 +++++++--
libmultipath/foreign/nvme.c | 10 +++++++---
3 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
index 2e8f34f9..a6893d8d 100644
--- a/libmultipath/configure.c
+++ b/libmultipath/configure.c
@@ -511,6 +511,7 @@ static void trigger_partitions_udev_change(struct udev_device *dev,
{
struct udev_enumerate *part_enum;
struct udev_list_entry *item;
+ const char *devtype;
part_enum = udev_enumerate_new(udev);
if (!part_enum)
@@ -531,7 +532,8 @@ static void trigger_partitions_udev_change(struct udev_device *dev,
if (!part)
continue;
- if (!strcmp("partition", udev_device_get_devtype(part))) {
+ devtype = udev_device_get_devtype(part);
+ if (devtype && !strcmp("partition", devtype)) {
condlog(4, "%s: triggering %s event for %s", __func__,
action, syspath);
sysfs_attr_set_value(part, "uevent", action, len);
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index a328aafa..74abf34d 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -353,7 +353,7 @@ sysfs_get_tgt_nodename(struct path *pp, char *node)
tgtdev = udev_device_get_parent(parent);
while (tgtdev) {
tgtname = udev_device_get_sysname(tgtdev);
- if (sscanf(tgtname, "end_device-%d:%d",
+ if (tgtname && sscanf(tgtname, "end_device-%d:%d",
&host, &tgtid) == 2)
break;
tgtdev = udev_device_get_parent(tgtdev);
@@ -386,7 +386,7 @@ sysfs_get_tgt_nodename(struct path *pp, char *node)
/* Check for FibreChannel */
tgtdev = udev_device_get_parent(parent);
value = udev_device_get_sysname(tgtdev);
- if (sscanf(value, "rport-%d:%d-%d",
+ if (value && sscanf(value, "rport-%d:%d-%d",
&host, &channel, &tgtid) == 3) {
tgtdev = udev_device_new_from_subsystem_sysname(udev,
"fc_remote_ports", value);
@@ -516,6 +516,9 @@ int sysfs_get_host_pci_name(const struct path *pp, char *pci_name)
*/
value = udev_device_get_sysname(parent);
+ if (!value)
+ return 1;
+
strncpy(pci_name, value, SLOT_NAME_SIZE);
udev_device_unref(hostdev);
return 0;
@@ -1518,6 +1521,8 @@ ccw_sysfs_pathinfo (struct path * pp, vector hwtable)
* host / bus / target / lun
*/
attr_path = udev_device_get_sysname(parent);
+ if (!attr_path)
+ return PATHINFO_FAILED;
pp->sg_id.lun = 0;
if (sscanf(attr_path, "%i.%i.%x",
&pp->sg_id.host_no,
diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c
index 09cdddf0..5feb1e95 100644
--- a/libmultipath/foreign/nvme.c
+++ b/libmultipath/foreign/nvme.c
@@ -482,6 +482,7 @@ _find_path_by_syspath(struct nvme_map *map, const char *syspath)
struct nvme_pathgroup *pg;
char real[PATH_MAX];
const char *ppath;
+ const char *psyspath;
int i;
ppath = realpath(syspath, real);
@@ -493,8 +494,8 @@ _find_path_by_syspath(struct nvme_map *map, const char *syspath)
vector_foreach_slot(&map->pgvec, pg, i) {
struct nvme_path *path = nvme_pg_to_path(pg);
- if (!strcmp(ppath,
- udev_device_get_syspath(path->udev)))
+ psyspath = udev_device_get_syspath(path->udev);
+ if (psyspath && !strcmp(ppath, psyspath))
return path;
}
condlog(4, "%s: %s: %s not found", __func__, THIS, ppath);
@@ -538,6 +539,7 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx,
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)
return NULL;
@@ -562,7 +564,9 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx,
udev_list_entry_get_name(item));
if (tmp == NULL)
continue;
- if (!strcmp(udev_device_get_devtype(tmp), "disk")) {
+
+ devtype = udev_device_get_devtype(tmp);
+ if (devtype && !strcmp(devtype, "disk")) {
blkdev = tmp;
break;
} else
--
2.17.2

View File

@ -0,0 +1,47 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Wed, 24 Feb 2021 00:33:20 -0600
Subject: [PATCH] libmultipath: cleanup code to strip wwid trailing spaces
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
libmultipath/discovery.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 74abf34d..126a70b3 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -2062,11 +2062,11 @@ int
get_uid (struct path * pp, int path_state, struct udev_device *udev,
int allow_fallback)
{
- char *c;
const char *origin = "unknown";
ssize_t len = 0;
struct config *conf;
int used_fallback = 0;
+ size_t i;
if (!pp->uid_attribute && !pp->getuid) {
conf = get_multipath_config();
@@ -2119,12 +2119,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev,
return 1;
} else {
/* Strip any trailing blanks */
- c = strchr(pp->wwid, '\0');
- c--;
- while (c && c >= pp->wwid && *c == ' ') {
- *c = '\0';
- c--;
- }
+ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--);
+ /* no-op */
+ pp->wwid[i] = '\0';
}
condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev,
*pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
--
2.17.2

View File

@ -0,0 +1,429 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Wed, 24 Feb 2021 00:33:22 -0600
Subject: [PATCH] multipathd: add recheck_wwid option to verify the path wwid
There are cases where the wwid of a path changes due to LUN remapping
without triggering uevent for the changed path. Multipathd has no method
for trying to catch these cases, and corruption has resulted because of
it.
In order to have a better chance at catching these cases, multipath now
has a recheck_wwid option. If this is set to "yes", when a failed path
has become active again, multipathd will recheck its wwid. If multipathd
notices that a path's wwid has changed, it will remove and re-add the
path, just like the existing wwid checking code for change events does.
In cases where the no uevent occurs, both the udev database entry and
sysfs will have the old wwid, so the only way to get a current wwid is
to ask the device directly. Currently multipath only has code to
directly get the wwid for scsi devices, so this option only effects scsi
devices, and they must be configured to be able to use the uid_fallback
methods. To make sure both the sysfs and udev database values are
updated, multipathd triggers a both a rescan of the device and a udev
add event.
Co-developed-by: Chongyun Wu <wucy11@chinatelecom.cn>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>Reviewed-by: Martin Wilck <mwilck@suse.com>
---
libmultipath/config.c | 2 +
libmultipath/config.h | 2 +
libmultipath/configure.c | 4 +-
libmultipath/configure.h | 2 +
libmultipath/defaults.h | 1 +
libmultipath/dict.c | 11 ++++++
libmultipath/discovery.c | 3 +-
libmultipath/discovery.h | 1 +
libmultipath/propsel.c | 21 ++++++++++
libmultipath/propsel.h | 1 +
libmultipath/structs.h | 7 ++++
multipath/multipath.conf.5 | 14 +++++++
multipathd/cli_handlers.c | 9 +++++
multipathd/main.c | 78 ++++++++++++++++++++++++++++++++++++++
multipathd/main.h | 2 +
15 files changed, 155 insertions(+), 3 deletions(-)
diff --git a/libmultipath/config.c b/libmultipath/config.c
index dd645f17..abbddaf1 100644
--- a/libmultipath/config.c
+++ b/libmultipath/config.c
@@ -371,6 +371,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src)
merge_num(max_sectors_kb);
merge_num(ghost_delay);
merge_num(all_tg_pt);
+ merge_num(recheck_wwid);
merge_num(vpd_vendor_id);
merge_num(san_path_err_threshold);
merge_num(san_path_err_forget_rate);
@@ -762,6 +763,7 @@ load_config (char * file)
conf->remove_retries = 0;
conf->ghost_delay = DEFAULT_GHOST_DELAY;
conf->all_tg_pt = DEFAULT_ALL_TG_PT;
+ conf->recheck_wwid = DEFAULT_RECHECK_WWID;
/*
* preload default hwtable
*/
diff --git a/libmultipath/config.h b/libmultipath/config.h
index a22c1b4e..e2e3f143 100644
--- a/libmultipath/config.h
+++ b/libmultipath/config.h
@@ -84,6 +84,7 @@ struct hwentry {
int ghost_delay;
int all_tg_pt;
int vpd_vendor_id;
+ int recheck_wwid;
char * bl_product;
};
@@ -188,6 +189,7 @@ struct config {
int skip_delegate;
unsigned int version[3];
unsigned int sequence_nr;
+ int recheck_wwid;
char * multipath_dir;
char * selector;
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
index a6893d8d..f24d9283 100644
--- a/libmultipath/configure.c
+++ b/libmultipath/configure.c
@@ -506,8 +506,8 @@ trigger_udev_change(const struct multipath *mpp)
udev_device_unref(udd);
}
-static void trigger_partitions_udev_change(struct udev_device *dev,
- const char *action, int len)
+void trigger_partitions_udev_change(struct udev_device *dev,
+ const char *action, int len)
{
struct udev_enumerate *part_enum;
struct udev_list_entry *item;
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
index 0e33bf40..81090dd4 100644
--- a/libmultipath/configure.h
+++ b/libmultipath/configure.h
@@ -57,3 +57,5 @@ int get_refwwid (enum mpath_cmds cmd, char * dev, enum devtypes dev_type,
int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh, int is_daemon);
struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type);
void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath);
+void trigger_partitions_udev_change(struct udev_device *dev, const char *action,
+ int len);
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
index 52fe05b9..f1cb000d 100644
--- a/libmultipath/defaults.h
+++ b/libmultipath/defaults.h
@@ -50,6 +50,7 @@
#define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10
#define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1
#define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF
+#define DEFAULT_RECHECK_WWID RECHECK_WWID_OFF
/* Enable all foreign libraries by default */
#define DEFAULT_ENABLE_FOREIGN ""
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
index 8fd91d8c..13698b76 100644
--- a/libmultipath/dict.c
+++ b/libmultipath/dict.c
@@ -1413,6 +1413,14 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef)
declare_def_handler(marginal_pathgroups, set_yes_no)
declare_def_snprint(marginal_pathgroups, print_yes_no)
+declare_def_handler(recheck_wwid, set_yes_no_undef)
+declare_def_snprint_defint(recheck_wwid, print_yes_no_undef, DEFAULT_RECHECK_WWID)
+declare_ovr_handler(recheck_wwid, set_yes_no_undef)
+declare_ovr_snprint(recheck_wwid, print_yes_no_undef)
+declare_hw_handler(recheck_wwid, set_yes_no_undef)
+declare_hw_snprint(recheck_wwid, print_yes_no_undef)
+
+
static int
def_uxsock_timeout_handler(struct config *conf, vector strvec)
{
@@ -1824,6 +1832,7 @@ init_keywords(vector keywords)
install_keyword("enable_foreign", &def_enable_foreign_handler,
&snprint_def_enable_foreign);
install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups);
+ install_keyword("recheck_wwid", &def_recheck_wwid_handler, &snprint_def_recheck_wwid);
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
@@ -1913,6 +1922,7 @@ init_keywords(vector keywords)
install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay);
install_keyword("all_tg_pt", &hw_all_tg_pt_handler, &snprint_hw_all_tg_pt);
install_keyword("vpd_vendor", &hw_vpd_vendor_handler, &snprint_hw_vpd_vendor);
+ install_keyword("recheck_wwid", &hw_recheck_wwid_handler, &snprint_hw_recheck_wwid);
install_sublevel_end();
install_keyword_root("overrides", &overrides_handler);
@@ -1954,6 +1964,7 @@ init_keywords(vector keywords)
install_keyword("max_sectors_kb", &ovr_max_sectors_kb_handler, &snprint_ovr_max_sectors_kb);
install_keyword("ghost_delay", &ovr_ghost_delay_handler, &snprint_ovr_ghost_delay);
install_keyword("all_tg_pt", &ovr_all_tg_pt_handler, &snprint_ovr_all_tg_pt);
+ install_keyword("recheck_wwid", &ovr_recheck_wwid_handler, &snprint_ovr_recheck_wwid);
install_keyword_root("multipaths", &multipaths_handler);
install_keyword_multi("multipath", &multipath_handler, NULL);
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 126a70b3..bc267609 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -2040,7 +2040,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state,
return len;
}
-static bool has_uid_fallback(struct path *pp)
+bool has_uid_fallback(struct path *pp)
{
/*
* Falling back to direct WWID determination is dangerous
@@ -2072,6 +2072,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev,
conf = get_multipath_config();
pthread_cleanup_push(put_multipath_config, conf);
select_getuid(conf, pp);
+ select_recheck_wwid(conf, pp);
pthread_cleanup_pop(1);
}
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
index d3193daf..a5446b4d 100644
--- a/libmultipath/discovery.h
+++ b/libmultipath/discovery.h
@@ -54,6 +54,7 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev,
unsigned char *buff, size_t len);
int sysfs_get_asymmetric_access_state(struct path *pp,
char *buff, int buflen);
+bool has_uid_fallback(struct path *pp);
int get_uid(struct path * pp, int path_state, struct udev_device *udev,
int allow_fallback);
bool is_vpd_page_supported(int fd, int pg);
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
index 1150cfe8..127b3370 100644
--- a/libmultipath/propsel.c
+++ b/libmultipath/propsel.c
@@ -581,6 +581,27 @@ out:
return 0;
}
+/* must be called after select_getuid */
+int select_recheck_wwid(struct config *conf, struct path * pp)
+{
+ const char *origin;
+
+ pp_set_ovr(recheck_wwid);
+ pp_set_hwe(recheck_wwid);
+ pp_set_conf(recheck_wwid);
+ pp_set_default(recheck_wwid, DEFAULT_RECHECK_WWID);
+out:
+ if (pp->recheck_wwid == RECHECK_WWID_ON &&
+ (pp->bus != SYSFS_BUS_SCSI || pp->getuid != NULL ||
+ !has_uid_fallback(pp))) {
+ pp->recheck_wwid = RECHECK_WWID_OFF;
+ origin = "(setting: unsupported by device type/config)";
+ }
+ condlog(3, "%s: recheck_wwid = %i %s", pp->dev, pp->recheck_wwid,
+ origin);
+ return 0;
+}
+
void
detect_prio(struct config *conf, struct path * pp)
{
diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h
index a68bacf0..72a7e33c 100644
--- a/libmultipath/propsel.h
+++ b/libmultipath/propsel.h
@@ -7,6 +7,7 @@ int select_features (struct config *conf, struct multipath * mp);
int select_hwhandler (struct config *conf, struct multipath * mp);
int select_checker(struct config *conf, struct path *pp);
int select_getuid (struct config *conf, struct path * pp);
+int select_recheck_wwid(struct config *conf, struct path * pp);
int select_prio (struct config *conf, struct path * pp);
int select_find_multipaths_timeout(struct config *conf, struct path *pp);
int select_no_path_retry(struct config *conf, struct multipath *mp);
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index 65542dea..a5dbad5b 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -252,6 +252,12 @@ enum eh_deadline_states {
EH_DEADLINE_ZERO = UOZ_ZERO,
};
+enum recheck_wwid_states {
+ RECHECK_WWID_UNDEF = YNU_UNDEF,
+ RECHECK_WWID_OFF = YNU_NO,
+ RECHECK_WWID_ON = YNU_YES,
+};
+
struct vpd_vendor_page {
int pg;
const char *name;
@@ -326,6 +332,7 @@ struct path {
int find_multipaths_timeout;
int marginal;
int vpd_vendor_id;
+ int recheck_wwid;
/* configlet pointers */
vector hwe;
struct gen_path generic_path;
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index a5686090..6da15aad 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -1256,6 +1256,20 @@ The default is: \fB\(dq\(dq\fR (the empty regular expression)
.RE
.
.
+.TP
+.B recheck_wwid
+If set to \fIyes\fR, when a failed path is restored, its wwid is rechecked. If
+the wwid has changed, the path is removed from the current multipath device,
+and re-added as a new path. Multipathd will also recheck a path's wwid if it is
+manually re-added. This option only works for SCSI devices that are configured
+to use the default uid_attribute, \fIID_SERIAL\fR, or sysfs for getting their
+wwid.
+.RS
+.TP
+The default is \fBno\fR
+.RE
+.
+.
.
.\" ----------------------------------------------------------------------------
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index 782bb003..8b4bd187 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -715,6 +715,15 @@ cli_add_path (void * v, char ** reply, int * len, void * data)
pp = find_path_by_dev(vecs->pathvec, param);
if (pp) {
condlog(2, "%s: path already in pathvec", param);
+
+ if (pp->recheck_wwid == RECHECK_WWID_ON &&
+ check_path_wwid_change(pp)) {
+ condlog(0, "%s: wwid changed. Removing device",
+ pp->dev);
+ handle_path_wwid_change(pp, vecs);
+ return 1;
+ }
+
if (pp->mpp)
return 0;
} else {
diff --git a/multipathd/main.c b/multipathd/main.c
index cc1aeea2..1fbc31eb 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -822,6 +822,73 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs)
return flush_map(mpp, vecs, 0);
}
+static void
+rescan_path(struct udev_device *parent)
+{
+ while(parent) {
+ const char *subsys = udev_device_get_subsystem(parent);
+ if (subsys && !strncmp(subsys, "scsi", 4))
+ break;
+ parent = udev_device_get_parent(parent);
+ }
+ if (parent)
+ sysfs_attr_set_value(parent, "rescan", "1", strlen("1"));
+}
+
+void
+handle_path_wwid_change(struct path *pp, struct vectors *vecs)
+{
+ struct udev_device *udd;
+
+ if (!pp || !pp->udev)
+ return;
+
+ udd = udev_device_ref(pp->udev);
+ if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) {
+ pp->dmstate = PSTATE_FAILED;
+ dm_fail_path(pp->mpp->alias, pp->dev_t);
+ }
+ rescan_path(udd);
+ sysfs_attr_set_value(udd, "uevent", "add", strlen("add"));
+ trigger_partitions_udev_change(udd, "add", strlen("add"));
+ udev_device_unref(udd);
+}
+
+bool
+check_path_wwid_change(struct path *pp)
+{
+ char wwid[WWID_SIZE];
+ int len = 0;
+ size_t i;
+
+ if (!strlen(pp->wwid))
+ return false;
+
+ /* Get the real fresh device wwid by sgio. sysfs still has old
+ * data, so only get_vpd_sgio will work to get the new wwid */
+ len = get_vpd_sgio(pp->fd, 0x83, 0, wwid, WWID_SIZE);
+
+ if (len <= 0) {
+ condlog(2, "%s: failed to check wwid by sgio: len = %d",
+ pp->dev, len);
+ return false;
+ }
+
+ /*Strip any trailing blanks */
+ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--);
+ /* no-op */
+ pp->wwid[i] = '\0';
+ condlog(4, "%s: Got wwid %s by sgio", pp->dev, wwid);
+
+ if (strncmp(wwid, pp->wwid, WWID_SIZE)) {
+ condlog(0, "%s: wwid '%s' doesn't match wwid '%s' from device",
+ pp->dev, pp->wwid, wwid);
+ return true;
+ }
+
+ return false;
+}
+
static int
uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
{
@@ -1241,6 +1308,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
condlog(0, "%s: path wwid changed from '%s' to '%s'",
uev->kernel, wwid, pp->wwid);
ev_remove_path(pp, vecs, 1);
+ rescan_path(uev->udev);
needs_reinit = 1;
goto out;
} else {
@@ -2101,6 +2169,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
return 0;
set_no_path_retry(pp->mpp);
+ if (pp->recheck_wwid == RECHECK_WWID_ON &&
+ (newstate == PATH_UP || newstate == PATH_GHOST) &&
+ ((pp->state != PATH_UP && pp->state != PATH_GHOST) ||
+ pp->dmstate == PSTATE_FAILED) &&
+ check_path_wwid_change(pp)) {
+ condlog(0, "%s: path wwid change detected. Removing", pp->dev);
+ handle_path_wwid_change(pp, vecs);
+ return 0;
+ }
+
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
(san_path_check_enabled(pp->mpp) ||
marginal_path_check_enabled(pp->mpp))) {
diff --git a/multipathd/main.h b/multipathd/main.h
index 5dff17e5..8f0028a9 100644
--- a/multipathd/main.h
+++ b/multipathd/main.h
@@ -49,4 +49,6 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset);
int update_path_groups(struct multipath *mpp, struct vectors *vecs,
int refresh);
+void handle_path_wwid_change(struct path *pp, struct vectors *vecs);
+bool check_path_wwid_change(struct path *pp);
#endif /* MAIN_H */
--
2.17.2

View File

@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 25 Mar 2021 19:52:43 -0500
Subject: [PATCH] libmultipath: avoid infinite loop with bad vpd page 83
identifier
If a device with a scsi name identifier has an unknown prefix,
parse_vpd_pg83() needs to advance to the next identifier, instead of
simply trying the same one again in an infinite loop.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
libmultipath/discovery.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index bc267609..8c2ab073 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -1101,7 +1101,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
if (memcmp(d + 4, "eui.", 4) &&
memcmp(d + 4, "naa.", 4) &&
memcmp(d + 4, "iqn.", 4))
- continue;
+ break;
if (prio < 4) {
prio = 4;
vpd = d;
--
2.17.2

View File

@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 25 Mar 2021 19:52:44 -0500
Subject: [PATCH] libmultipath: fix priorities in parse_vpd_pg83
The priorities for the EUI-64 (0x02) and NAME (0x08) scsi identifiers in
parse_vpd_pg83() don't match their priorities in 55-scsi-sg3_id.rules.
Switch them so that they match.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
libmultipath/discovery.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 8c2ab073..5e988631 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -1096,19 +1096,19 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
vpd = d;
}
break;
- case 0x8:
- /* SCSI Name: Prio 4 */
- if (memcmp(d + 4, "eui.", 4) &&
- memcmp(d + 4, "naa.", 4) &&
- memcmp(d + 4, "iqn.", 4))
- break;
+ case 0x2:
+ /* EUI-64: Prio 4 */
if (prio < 4) {
prio = 4;
vpd = d;
}
break;
- case 0x2:
- /* EUI-64: Prio 3 */
+ case 0x8:
+ /* SCSI Name: Prio 3 */
+ if (memcmp(d + 4, "eui.", 4) &&
+ memcmp(d + 4, "naa.", 4) &&
+ memcmp(d + 4, "iqn.", 4))
+ break;
if (prio < 3) {
prio = 3;
vpd = d;
--
2.17.2

View File

@ -0,0 +1,54 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 25 Mar 2021 13:05:10 -0500
Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output
Red Hat sets ID_SERIAL based on the result of scsi_id, instead of using
the result of sg_inq and 55-scsi-sg3_id.rules. Make parse_vpd_pg83 match
that.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/discovery.c | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 5e988631..2404cb87 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -1079,12 +1079,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
naa_prio = 7;
break;
case 2:
- /* IEEE Extended: Prio 6 */
- naa_prio = 6;
- break;
case 3:
- /* IEEE Locally assigned: Prio 1 */
- naa_prio = 1;
+ /* IEEE Extended or Locally assigned: Prio 6 */
+ naa_prio = 6;
break;
default:
/* Default: no priority */
@@ -1103,17 +1100,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
vpd = d;
}
break;
- case 0x8:
- /* SCSI Name: Prio 3 */
- if (memcmp(d + 4, "eui.", 4) &&
- memcmp(d + 4, "naa.", 4) &&
- memcmp(d + 4, "iqn.", 4))
- break;
- if (prio < 3) {
- prio = 3;
- vpd = d;
- }
- break;
case 0x1:
/* T-10 Vendor ID: Prio 2 */
if (prio < 2) {
--
2.17.2

View File

@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 25 Mar 2021 19:52:45 -0500
Subject: [PATCH] multipathd: improve getting parent udevice in rescan_path
Instead of looping through parents and checking, just call
udev_device_get_parent_with_subsystem_devtype() to get the
right one.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
multipathd/main.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/multipathd/main.c b/multipathd/main.c
index 1fbc31eb..4598d354 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -823,16 +823,12 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs)
}
static void
-rescan_path(struct udev_device *parent)
+rescan_path(struct udev_device *ud)
{
- while(parent) {
- const char *subsys = udev_device_get_subsystem(parent);
- if (subsys && !strncmp(subsys, "scsi", 4))
- break;
- parent = udev_device_get_parent(parent);
- }
- if (parent)
- sysfs_attr_set_value(parent, "rescan", "1", strlen("1"));
+ ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi",
+ "scsi_device");
+ if (ud)
+ sysfs_attr_set_value(ud, "rescan", "1", strlen("1"));
}
void
--
2.17.2

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 25 Mar 2021 19:52:46 -0500
Subject: [PATCH] multipathd: don't trigger uevent for partitions on wwid
change
If the wwid changed, the device is no longer the same, so sending add
events to the devices partitions doesn't make any sense.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
multipathd/main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/multipathd/main.c b/multipathd/main.c
index 4598d354..e6c19ab2 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -846,7 +846,6 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs)
}
rescan_path(udd);
sysfs_attr_set_value(udd, "uevent", "add", strlen("add"));
- trigger_partitions_udev_change(udd, "add", strlen("add"));
udev_device_unref(udd);
}
--
2.17.2

View File

@ -0,0 +1,165 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Fri, 9 Jul 2021 14:30:10 -0500
Subject: [PATCH] RH: mpathconf: correctly handle spaces after option names
mpathconf was either accepting any number of spaces, including zero,
after option names, or it was only accepting one space. It should
accept one or more spaces.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipath/mpathconf | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/multipath/mpathconf b/multipath/mpathconf
index 2f4f3eaf..5f2285ab 100644
--- a/multipath/mpathconf
+++ b/multipath/mpathconf
@@ -240,7 +240,7 @@ function validate_args
echo "--enable_foreign must be either 'y' or 'n'"
exit 1
fi
- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then
SHOW_STATUS=1
fi
if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
@@ -315,36 +315,36 @@ if [ "$MULTIPATHD" = "y" ]; then
fi
if [ "$HAVE_BLACKLIST" = "1" ]; then
- if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then
HAVE_DISABLE=1
- elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then
HAVE_DISABLE=0
fi
fi
if [ "$HAVE_BLACKLIST" = "1" ]; then
- if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then
HAVE_WWID_DISABLE=1
- elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then
HAVE_WWID_DISABLE=0
fi
fi
if [ "$HAVE_DEFAULTS" = "1" ]; then
- HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p`
+ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p`
if [ "$HAVE_FIND" = "1" ]; then
HAVE_FIND="yes"
elif [ "$HAVE_FIND" = "0" ]; then
HAVE_FIND="no"
fi
- if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then
HAVE_FRIENDLY=1
- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then
HAVE_FRIENDLY=0
fi
if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then
HAVE_FOREIGN=0
- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\^\$\"" ; then
HAVE_FOREIGN=1
elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then
HAVE_FOREIGN=2
@@ -352,9 +352,9 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then
fi
if [ "$HAVE_EXCEPTIONS" = "1" ]; then
- if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
HAVE_PROPERTY=1
- elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
HAVE_PROPERTY=0
fi
fi
@@ -427,14 +427,14 @@ fi
if [ "$ENABLE" = 2 ]; then
if [ "$HAVE_DISABLE" = 1 ]; then
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE
fi
if [ -z "$HAVE_WWID_DISABLE" ]; then
sed -i '/^blacklist[[:space:]]*{/ a\
wwid ".*"
' $TMPFILE
elif [ "$HAVE_WWID_DISABLE" = 0 ]; then
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"/ wwid ".*"/' $TMPFILE
fi
if [ "$HAVE_EXCEPTIONS" = 1 ]; then
sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE
@@ -448,7 +448,7 @@ _EOF_
add_blacklist_exceptions
elif [ "$ENABLE" = 1 ]; then
if [ "$HAVE_DISABLE" = 1 ]; then
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE
fi
elif [ "$ENABLE" = 0 ]; then
if [ -z "$HAVE_DISABLE" ]; then
@@ -456,7 +456,7 @@ elif [ "$ENABLE" = 0 ]; then
devnode ".*"
' $TMPFILE
elif [ "$HAVE_DISABLE" = 0 ]; then
- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE
fi
fi
@@ -467,14 +467,14 @@ if [ -n "$FIND" ]; then
' $TMPFILE
CHANGED_CONFIG=1
elif [ "$FIND" != "$HAVE_FIND" ]; then
- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE
CHANGED_CONFIG=1
fi
fi
if [ "$FRIENDLY" = "n" ]; then
if [ "$HAVE_FRIENDLY" = 1 ]; then
- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
CHANGED_CONFIG=1
fi
elif [ "$FRIENDLY" = "y" ]; then
@@ -484,14 +484,14 @@ elif [ "$FRIENDLY" = "y" ]; then
' $TMPFILE
CHANGED_CONFIG=1
elif [ "$HAVE_FRIENDLY" = 0 ]; then
- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
CHANGED_CONFIG=1
fi
fi
if [ "$PROPERTY" = "n" ]; then
if [ "$HAVE_PROPERTY" = 1 ]; then
- sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
CHANGED_CONFIG=1
fi
elif [ "$PROPERTY" = "y" ]; then
@@ -501,7 +501,7 @@ elif [ "$PROPERTY" = "y" ]; then
' $TMPFILE
CHANGED_CONFIG=1
elif [ "$HAVE_PROPERTY" = 0 ]; then
- sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
CHANGED_CONFIG=1
fi
fi
--
2.30.2

View File

@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 15 Jul 2021 14:48:15 -0500
Subject: [PATCH] multipath.conf: fix typo in checker_timeout description
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipath/multipath.conf.5 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index 6da15aad..0c04c7e4 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -638,7 +638,7 @@ Specify the timeout to use for path checkers and prioritizers, in seconds.
Only prioritizers that issue scsi commands use checker_timeout. Checkers
that support an asynchronous mode (\fItur\fR and \fIdirectio\fR), will
return shortly after being called by multipathd, regardless of whether the
-storage array responds. If the storage array hasn't responded, mulitpathd will
+storage array responds. If the storage array hasn't responded, multipathd will
check for a response every second, until \fIchecker_timeout\fR seconds have
elapsed.
.RS

View File

@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 22 Jul 2021 17:48:06 -0500
Subject: [PATCH] mpathpersist: fail commands when no usable paths exist
"mpathpersist -oCK <reservation_key> <device>" will return success if it
is run on devices with no usable paths, but nothing is actually done.
The -L command will fail, but it should give up sooner, and with a more
helpful error message.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmpathpersist/mpath_persist.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
index 07a5f17f..d0744773 100644
--- a/libmpathpersist/mpath_persist.c
+++ b/libmpathpersist/mpath_persist.c
@@ -629,7 +629,8 @@ int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope,
return ret ;
}
}
- return MPATH_PR_SUCCESS;
+ condlog (0, "%s: no path available", mpp->wwid);
+ return MPATH_PR_DMMP_ERROR;
}
int send_prout_activepath(char * dev, int rq_servact, int rq_scope,
@@ -688,6 +689,11 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST);
+ if (active_pathcount == 0) {
+ condlog (0, "%s: no path available", mpp->wwid);
+ return MPATH_PR_DMMP_ERROR;
+ }
+
struct threadinfo thread[active_pathcount];
memset(thread, 0, sizeof(thread));
for (i = 0; i < active_pathcount; i++){

View File

@ -0,0 +1,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Fri, 16 Jul 2021 12:39:17 -0500
Subject: [PATCH] multipath: print warning if multipathd is not running.
If multipath notices that multipath devices exist or were created, and
multipathd is not running, it now prints a warning message, so users are
notified of the issue.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/configure.c | 13 +++++++++++--
libmultipath/configure.h | 1 +
multipath/main.c | 5 +++++
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
index f24d9283..9c8d3e34 100644
--- a/libmultipath/configure.c
+++ b/libmultipath/configure.c
@@ -1043,7 +1043,8 @@ deadmap (struct multipath * mpp)
return 1; /* dead */
}
-int check_daemon(void)
+extern int
+check_daemon(void)
{
int fd;
char *reply;
@@ -1097,6 +1098,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
struct config *conf;
int allow_queueing;
uint64_t *size_mismatch_seen;
+ bool map_processed = false;
+ bool no_daemon = false;
/* ignore refwwid if it's empty */
if (refwwid && !strlen(refwwid))
@@ -1239,7 +1242,9 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
conf = get_multipath_config();
allow_queueing = conf->allow_queueing;
put_multipath_config(conf);
- if (!is_daemon && !allow_queueing && !check_daemon()) {
+ if (!is_daemon && !allow_queueing &&
+ (no_daemon || !check_daemon())) {
+ no_daemon = true;
if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
mpp->no_path_retry != NO_PATH_RETRY_FAIL)
condlog(3, "%s: multipathd not running, unset "
@@ -1267,6 +1272,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
else
remove_map(mpp, vecs, 0);
}
+ map_processed = true;
}
/*
* Flush maps with only dead paths (ie not in sysfs)
@@ -1292,6 +1298,9 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
condlog(2, "%s: remove (dead)", alias);
}
}
+ if (map_processed && !is_daemon && (no_daemon || !check_daemon()))
+ condlog(2, "multipath devices exist, but multipathd service is not running");
+
ret = CP_OK;
out:
free(size_mismatch_seen);
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
index 81090dd4..8a266d31 100644
--- a/libmultipath/configure.h
+++ b/libmultipath/configure.h
@@ -59,3 +59,4 @@ struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type);
void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath);
void trigger_partitions_udev_change(struct udev_device *dev, const char *action,
int len);
+int check_daemon(void);
diff --git a/multipath/main.c b/multipath/main.c
index 607cada2..14d045c9 100644
--- a/multipath/main.c
+++ b/multipath/main.c
@@ -254,6 +254,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid)
int i;
struct multipath * mpp;
char params[PARAMS_SIZE], status[PARAMS_SIZE];
+ bool maps_present = false;
if (dm_get_maps(curmp))
return 1;
@@ -302,6 +303,8 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid)
if (cmd == CMD_CREATE)
reinstate_paths(mpp);
+
+ maps_present = true;
}
if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) {
@@ -311,6 +314,8 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid)
put_multipath_config(conf);
}
+ if (maps_present && !check_daemon())
+ condlog(2, "multipath devices exist, but multipathd service is not running");
return 0;
}

View File

@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Fri, 23 Jul 2021 14:10:06 -0500
Subject: [PATCH] multipathd: don't access path if it was deleted
ev_remove_path() could fail and still delete the path. This could cause
problems for handle_path_wwid_change(), which expected that a failure
meant that the path still existed. ev_remove_path now returns a
different error code for failure to reload the multipath device, so that
it can be differentiated from cases where the path was no removed.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
multipathd/main.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/multipathd/main.c b/multipathd/main.c
index e6c19ab2..823b53a2 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -86,6 +86,9 @@
#define FILE_NAME_SIZE 256
#define CMDSIZE 160
+#define PATH_REMOVE_FAILED 1
+#define MAP_RELOAD_FAILED 2
+
#define LOG_MSG(lvl, verb, pp) \
do { \
if (pp->mpp && checker_selected(&pp->checker) && \
@@ -840,7 +843,7 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs)
return;
udd = udev_device_ref(pp->udev);
- if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) {
+ if (ev_remove_path(pp, vecs, 1) == PATH_REMOVE_FAILED && pp->mpp) {
pp->dmstate = PSTATE_FAILED;
dm_fail_path(pp->mpp->alias, pp->dev_t);
}
@@ -1226,13 +1229,13 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
condlog(0, "%s: failed in domap for "
"removal of path %s",
mpp->alias, pp->dev);
- retval = 1;
+ retval = MAP_RELOAD_FAILED;
} else {
/*
* update our state from kernel
*/
if (setup_multipath(vecs, mpp))
- return 1;
+ return PATH_REMOVE_FAILED;
sync_map_state(mpp);
condlog(2, "%s [%s]: path removed from map %s",
@@ -1250,7 +1253,7 @@ out:
fail:
remove_map_and_stop_waiter(mpp, vecs);
- return 1;
+ return PATH_REMOVE_FAILED;
}
static int

View File

@ -1,7 +1,7 @@
Summary: Tools to manage multipath devices using device-mapper
Name: device-mapper-multipath
Version: 0.8.4
Release: 10%{?dist}
Release: 17%{?dist}
License: GPLv2
Group: System Environment/Base
URL: http://christophe.varoqui.free.fr/
@ -74,6 +74,19 @@ Patch00060: 0060-kpartx-free-loop-device-after-listing-partitions.patch
Patch00061: 0061-RH-fix-find_multipaths-in-mpathconf.patch
Patch00062: 0062-libmultipath-select_action-don-t-drop-map-if-alias-c.patch
Patch00063: 0063-libmultipath-check-if-user_friendly_name-is-in-use.patch
Patch00064: 0064-libmultipath-check-udev_device_get_-return-value-to-.patch
Patch00065: 0065-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch
Patch00066: 0066-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch
Patch00067: 0067-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch
Patch00068: 0068-libmultipath-fix-priorities-in-parse_vpd_pg83.patch
Patch00069: 0069-RH-make-parse_vpd_pg83-match-scsi_id-output.patch
Patch00070: 0070-multipathd-improve-getting-parent-udevice-in-rescan_.patch
Patch00071: 0071-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch
Patch00072: 0072-RH-mpathconf-correctly-handle-spaces-after-option-na.patch
Patch00073: 0073-multipath.conf-fix-typo-in-checker_timeout-descripti.patch
Patch00074: 0074-mpathpersist-fail-commands-when-no-usable-paths-exis.patch
Patch00075: 0075-multipath-print-warning-if-multipathd-is-not-running.patch
Patch00076: 0076-multipathd-don-t-access-path-if-it-was-deleted.patch
# runtime
Requires: %{name}-libs = %{version}-%{release}
@ -275,14 +288,53 @@ fi
%{_pkgconfdir}/libdmmp.pc
%changelog
* Sun Mar 7 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-10
* Fri Jul 23 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-17
- Add 0074-mpathpersist-fail-commands-when-no-usable-paths-exis.patch
* Fixes bz #1984723
- Add 0075-multipath-print-warning-if-multipathd-is-not-running.patch
* Fixes bz #1973592
- Add 0076-multipathd-don-t-access-path-if-it-was-deleted.patch
* Found by coverity
- Resolves: bz #1973592, #1984723
* Thu Jul 22 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-16
- Add missing patch
- Related: bz #1982598
* Thu Jul 22 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-15
- Add 0073-multipath.conf-fix-typo-in-checker_timeout-descripti.patch
- Resolves: bz #1982598
* Mon Jul 12 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-14
- Add 0072-RH-mpathconf-correctly-handle-spaces-after-option-na.patch
- Resolves: bz #1979470
* Wed Apr 28 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-13
- Add 0065-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch
- Add 0066-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch
- Add 0067-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch
- Add 0068-libmultipath-fix-priorities-in-parse_vpd_pg83.patch
- Add 0069-RH-make-parse_vpd_pg83-match-scsi_id-output.patch
- Add 0070-multipathd-improve-getting-parent-udevice-in-rescan_.patch
- Add 0071-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch
* add recheck_wwid option
* Fixes bz #1907904
- Resolves: bz #1907904
* Wed Apr 21 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-12
- Add 0064-libmultipath-check-udev_device_get_-return-value-to-.patch
* Fixes bz #1946940
- Resolves: bz #1946940
* Fri Mar 12 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-11
- Add 0062-libmultipath-select_action-don-t-drop-map-if-alias-c.patch
* Fall back to WWID names instead of removing existing device
- Add 0063-libmultipath-check-if-user_friendly_name-is-in-use.patch
* make sure to choose a user_friendly_name that isn't in use
* Fixes bz #1923777
* Fixes bz #1937832
- Add alias_clash CI test
- Resolves: bz #1923777
- Remove unused multipath.conf
- Resolves: bz #1937832
* Wed Feb 10 2021 Benjamin Marzinski <bmarzins@redhat.com> 0.8.4-9
- Add 0060-kpartx-free-loop-device-after-listing-partitions.patch
@ -561,7 +613,7 @@ fi
* mpathpersist now accepts --param-alltgpt
- Add 0005-libmutipath-remove-unused-IDE-bus-type.patch
- Add 0006-multipathd-add-new-protocol-path-wildcard.patch
* multipathd show paths format now accepts %P for the path protocol/transport
* multipathd show paths format now accepts %%P for the path protocol/transport
- Add 0007-libmultipath-add-protocol-blacklist-option.patch
* You can now use the "protocol" blacklist section parameter to blacklist
by protocol/transport