From c0050816c16d25f8143a791d1bb74e16af67c272 Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Fri, 14 Jan 2022 13:50:17 +0900 Subject: [PATCH] Imported Upstream version 0.7.1 --- libmultipath/devmapper.c | 14 +++++++++++++- libmultipath/discovery.c | 2 +- libmultipath/discovery.h | 1 + libmultipath/propsel.c | 36 ++++++++++++++++++++++++++++-------- libmultipath/version.h | 4 ++-- multipathd/main.c | 2 +- 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c index 026418f..5fb9d9a 100644 --- a/libmultipath/devmapper.c +++ b/libmultipath/devmapper.c @@ -761,6 +761,12 @@ out: } static int +has_partmap(const char *name, void *data) +{ + return 1; +} + +static int partmap_in_use(const char *name, void *data) { int part_count, *ret_count = (int *)data; @@ -785,12 +791,18 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, { int r; int queue_if_no_path = 0; + int udev_flags = 0; unsigned long long mapsize; char params[PARAMS_SIZE] = {0}; if (!dm_is_mpath(mapname)) return 0; /* nothing to do */ + /* if the device currently has no partitions, do not + run kpartx on it if you fail to delete it */ + if (do_foreach_partmaps(mapname, has_partmap, NULL) == 0) + udev_flags |= MPATH_UDEV_NO_KPARTX_FLAG; + /* If you aren't doing a deferred remove, make sure that no * devices are in use */ if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL)) @@ -834,7 +846,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, mapname); if (need_suspend && queue_if_no_path != -1) { dm_simplecmd_noflush(DM_DEVICE_RESUME, - mapname, 0); + mapname, udev_flags); } } if (retries) diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c index 8c51254..663c8ea 100644 --- a/libmultipath/discovery.c +++ b/libmultipath/discovery.c @@ -1092,7 +1092,7 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) return len; } -static int +int get_vpd_sgio (int fd, int pg, char * str, int maxlen) { int len, buff_len; diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h index 0563bfd..51c23d6 100644 --- a/libmultipath/discovery.h +++ b/libmultipath/discovery.h @@ -35,6 +35,7 @@ int path_discovery (vector pathvec, int flag); int do_tur (char *); int path_offline (struct path *); int get_state (struct path * pp, struct config * conf, int daemon); +int get_vpd_sgio (int fd, int pg, char * str, int maxlen); int pathinfo (struct path * pp, struct config * conf, int mask); int alloc_path_with_pathinfo (struct config *conf, struct udev_device *udevice, char *wwid, int flag, struct path **pp_ptr); diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c index dd10ceb..09fe728 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c @@ -162,7 +162,7 @@ int select_pgpolicy(struct config *conf, struct multipath * mp) if (conf->pgpolicy_flag > 0) { mp->pgpolicy = conf->pgpolicy_flag; - origin = "(cmd line flag)"; + origin = "(setting: multipath command line [-p] flag)"; goto out; } mp_set_mpe(pgpolicy); @@ -251,18 +251,18 @@ int select_alias(struct config *conf, struct multipath * mp) mp->alias_old, mp->alias_prefix, conf->bindings_read_only); memset (mp->alias_old, 0, WWID_SIZE); - origin = "(using existing alias)"; + origin = "(setting: using existing alias)"; } if (mp->alias == NULL) { mp->alias = get_user_friendly_alias(mp->wwid, conf->bindings_file, mp->alias_prefix, conf->bindings_read_only); - origin = "(user_friendly_name)"; + origin = "(setting: user_friendly_name)"; } out: if (mp->alias == NULL) { mp->alias = STRDUP(mp->wwid); - origin = "(default to wwid)"; + origin = "(setting: default to WWID)"; } if (mp->alias) condlog(3, "%s: alias = %s %s", mp->wwid, mp->alias, origin); @@ -370,6 +370,24 @@ out: return 0; } +/* + * Current RDAC (NetApp E-Series) firmware relies + * on periodic REPORT TARGET PORT GROUPS for + * internal load balancing. + * Using the sysfs priority checker defeats this purpose. + */ +static int +check_rdac(struct path * pp) +{ + int len; + char buff[44]; + + len = get_vpd_sgio(pp->fd, 0xC9, buff, 44); + if (len <= 0) + return 0; + return !(memcmp(buff + 4, "vac1", 4)); +} + void detect_prio(struct config *conf, struct path * pp) { @@ -379,8 +397,10 @@ detect_prio(struct config *conf, struct path * pp) if (pp->tpgs <= 0) return; - if (sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0) - default_prio = PRIO_SYSFS; + if (pp->tpgs == 2 && !check_rdac(pp)) { + if (sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0) + default_prio = PRIO_SYSFS; + } prio_get(conf->multipath_dir, p, default_prio, DEFAULT_PRIO_ARGS); } @@ -565,7 +585,7 @@ int select_retain_hwhandler(struct config *conf, struct multipath *mp) if (!VERSION_GE(conf->version, minv_dm_retain)) { mp->retain_hwhandler = RETAIN_HWHANDLER_OFF; - origin = "(requires kernel version >= 1.5.0)"; + origin = "(setting: WARNING, requires kernel version >= 1.5.0)"; goto out; } mp_set_ovr(retain_hwhandler); @@ -614,7 +634,7 @@ int select_deferred_remove(struct config *conf, struct multipath *mp) #ifndef LIBDM_API_DEFERRED mp->deferred_remove = DEFERRED_REMOVE_OFF; - origin = "(not compiled with support)"; + origin = "(setting: WARNING, not compiled with support)"; goto out; #endif if (mp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) { diff --git a/libmultipath/version.h b/libmultipath/version.h index 4b7c32a..5d45932 100644 --- a/libmultipath/version.h +++ b/libmultipath/version.h @@ -20,8 +20,8 @@ #ifndef _VERSION_H #define _VERSION_H -#define VERSION_CODE 0x000700 -#define DATE_CODE 0x040b11 +#define VERSION_CODE 0x000701 +#define DATE_CODE 0x040d11 #define PROG "multipath-tools" diff --git a/multipathd/main.c b/multipathd/main.c index 0c61caa..b167cb4 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -1087,7 +1087,7 @@ uxsock_trigger (char * str, char ** reply, int * len, bool is_root, return 1; } - r = parse_cmd(str, reply, len, vecs, uxsock_timeout); + r = parse_cmd(str, reply, len, vecs, uxsock_timeout / 1000); if (r > 0) { if (r == ETIMEDOUT) -- 2.7.4