Hello community, here is the log from the commit of package multipath-tools for openSUSE:Factory checked in at 2019-05-06 13:17:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/multipath-tools (Old) and /work/SRC/openSUSE:Factory/.multipath-tools.new.5148 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "multipath-tools" Mon May 6 13:17:19 2019 rev:113 rq:699729 version:0.8.1+8+suse.8c11498 Changes: -------- --- /work/SRC/openSUSE:Factory/multipath-tools/multipath-tools.changes 2019-04-21 09:02:11.818466807 +0200 +++ /work/SRC/openSUSE:Factory/.multipath-tools.new.5148/multipath-tools.changes 2019-05-06 13:17:25.135967185 +0200 @@ -1,0 +2,21 @@ +Tue Apr 30 14:48:40 UTC 2019 - mwilck@suse.com + +- Disable kmod() style dependencies again (bsc#1119414) + * For TW, dependencies will be autogenerated + (gh#openSUSE/rpm-config-SUSE#3) + * For SLE, feature is currently rejected (jsc#SLE-3853) +- Update to version 0.8.1+8+suse.8c11498: + * Avoid deadlock situation during udev settle + (bsc#1131789, bsc#1125145) + - multipath -u: test socket connection in non-blocking mode + * Fix priority handling for offline paths + (bsc#1118495) +- Update to upstream 0.8.1 + * Avoid device IO in "multipath -u" (bsc#1125145) + * multipathd: protect all access to running_state + (bsc##1110060, bsc#1110439) + * Improve handling of changed WWIDs and temporary failure + to obtain WWID. Option "disable_changed_wwids" is now ignored. + * Fixes for PATH_PENDING state handling (bsc#1125043) + +------------------------------------------------------------------- Old: ---- multipath-tools-0.8.0+17+suse.a28893f.tar.xz New: ---- multipath-tools-0.8.1+8+suse.8c11498.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ multipath-tools.spec ++++++ --- /var/tmp/diff_new_pack.Jd9hIc/_old 2019-05-06 13:17:26.511970463 +0200 +++ /var/tmp/diff_new_pack.Jd9hIc/_new 2019-05-06 13:17:26.511970463 +0200 @@ -49,7 +49,7 @@ %define _sysdir usr/lib Name: multipath-tools -Version: 0.8.0+17+suse.a28893f +Version: 0.8.1+8+suse.8c11498 Release: 0 Summary: Tools to Manage Multipathed Devices with the device-mapper License: GPL-2.0-only @@ -82,14 +82,6 @@ Requires: device-mapper >= 1.2.78 Requires: kpartx Requires: sg3_utils -# Generate kmod(xyz)-style dependencies for modules that we put -# in modules-load.d. Use the modules.d file (Source1) as input to avoid -# maintaining these dependencies in several places. -# This feature is to be enabled for SLE15-SP1, and some time in the -# near future, for Factory. -%if 0%{?sle_version} >= 150100 -%(sed 's/^\s*//;s/\s*$//;/^#/d;/^$/d;s/^/Requires: kmod(/;s/$/)/;' %{S:1}) -%endif Obsoletes: multipath-tools-rbd <= %{version} PreReq: coreutils grep @@ -107,11 +99,11 @@ # and it loads prioritizers (to be fixed) and checkers. %package -n libmpath0 Summary: Libraries for multipath-tools +License: GPL-2.0-only AND LGPL-2.1-only AND LGPL-2.0-or-later +Group: System/Libraries # This is for libmpathcmd, which is useless without multipathd. # No hard dependency here - we don't want to pull in all dependencies # of multipath-tools. -License: GPL-2.0-only AND LGPL-2.1-only AND LGPL-2.0-or-later -Group: System/Libraries Recommends: multipath-tools Conflicts: multipath-tools < 0.8.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Jd9hIc/_old 2019-05-06 13:17:26.531970511 +0200 +++ /var/tmp/diff_new_pack.Jd9hIc/_new 2019-05-06 13:17:26.531970511 +0200 @@ -8,7 +8,7 @@ are have been added to factory before upstream will be counted. Determine patch offset manually! It should be the number of patches which are _really_ not upstream (yet). --> - <param name="versionformat">@PARENT_TAG@+17+suse.%h</param> + <param name="versionformat">@PARENT_TAG@+8+suse.%h</param> <param name="revision">factory</param> <param name="match-tag">0.[0-9].[0-9]</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.Jd9hIc/_old 2019-05-06 13:17:26.543970540 +0200 +++ /var/tmp/diff_new_pack.Jd9hIc/_new 2019-05-06 13:17:26.543970540 +0200 @@ -1,6 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/openSUSE/multipath-tools.git</param> - <param name="changesrevision">a28893f67c7ca0009b9ef8b85732348b3c3092f1</param></service><service name="tar_scm"> - <param name="url">https://github.com/mwilck/multipath-tools.git</param> - <param name="changesrevision">08a969b7fce0db769b63bdbfead2a452dc417d58</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">8c114985f9fd7eb142ddec9737870f99ff28d5ba</param></service></servicedata> \ No newline at end of file ++++++ multipath-tools-0.8.0+17+suse.a28893f.tar.xz -> multipath-tools-0.8.1+8+suse.8c11498.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmpathcmd/mpath_cmd.c new/multipath-tools-0.8.1+8+suse.8c11498/libmpathcmd/mpath_cmd.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmpathcmd/mpath_cmd.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmpathcmd/mpath_cmd.c 2019-04-24 11:43:52.000000000 +0200 @@ -26,6 +26,7 @@ #include <poll.h> #include <string.h> #include <errno.h> +#include <fcntl.h> #include "mpath_cmd.h" @@ -93,10 +94,11 @@ /* * connect to a unix domain socket */ -int mpath_connect(void) +int __mpath_connect(int nonblocking) { int fd, len; struct sockaddr_un addr; + int flags = 0; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_LOCAL; @@ -108,14 +110,34 @@ if (fd == -1) return -1; + if (nonblocking) { + flags = fcntl(fd, F_GETFL, 0); + if (flags != -1) + (void)fcntl(fd, F_SETFL, flags|O_NONBLOCK); + } + if (connect(fd, (struct sockaddr *)&addr, len) == -1) { + int err = errno; + close(fd); + errno = err; return -1; } + if (nonblocking && flags != -1) + (void)fcntl(fd, F_SETFL, flags); + return fd; } +/* + * connect to a unix domain socket + */ +int mpath_connect(void) +{ + return __mpath_connect(0); +} + int mpath_disconnect(int fd) { return close(fd); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmpathcmd/mpath_cmd.h new/multipath-tools-0.8.1+8+suse.8c11498/libmpathcmd/mpath_cmd.h --- old/multipath-tools-0.8.0+17+suse.a28893f/libmpathcmd/mpath_cmd.h 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmpathcmd/mpath_cmd.h 2019-04-24 11:43:52.000000000 +0200 @@ -36,6 +36,21 @@ /* * DESCRIPTION: + * Same as mpath_connect() (see below) except for the "nonblocking" + * parameter. + * If "nonblocking" is set, connects in non-blocking mode. This is + * useful to avoid blocking if the listening socket's backlog is + * exceeded. In this case, errno will be set to EAGAIN. + * In case of success, the returned file descriptor is in in blocking + * mode, even if "nonblocking" was true. + * + * RETURNS: + * A file descriptor on success. -1 on failure (with errno set). + */ +int __mpath_connect(int nonblocking); + +/* + * DESCRIPTION: * Connect to the running multipathd daemon. On systems with the * multipathd.socket systemd unit file installed, this command will * start multipathd if it is not already running. This function diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/config.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/config.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/config.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/config.c 2019-04-24 11:43:52.000000000 +0200 @@ -716,7 +716,6 @@ conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT; - conf->disable_changed_wwids = DEFAULT_DISABLE_CHANGED_WWIDS; conf->remove_retries = 0; conf->ghost_delay = DEFAULT_GHOST_DELAY; conf->all_tg_pt = DEFAULT_ALL_TG_PT; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/config.h new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/config.h --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/config.h 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/config.h 2019-04-24 11:43:52.000000000 +0200 @@ -182,7 +182,6 @@ int delayed_reconfig; int uev_wait_timeout; int skip_kpartx; - int disable_changed_wwids; int remove_retries; int max_sectors_kb; int ghost_delay; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/devmapper.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/devmapper.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/devmapper.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/devmapper.c 2019-04-24 11:43:52.000000000 +0200 @@ -746,7 +746,7 @@ dm_task_destroy(dmt); out: if (r < 0) - condlog(2, "%s: dm command failed in %s", name, __FUNCTION__); + condlog(3, "%s: dm command failed in %s: %s", name, __FUNCTION__, strerror(errno)); return r; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/dict.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/dict.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/dict.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/dict.c 2019-04-24 11:43:52.000000000 +0200 @@ -157,6 +157,12 @@ } static int +print_ignored (char *buff, int len) +{ + return snprintf(buff, len, "ignored"); +} + +static int print_yes_no (char *buff, int len, long v) { return snprintf(buff, len, "\"%s\"", @@ -548,9 +554,15 @@ declare_hw_snprint(skip_kpartx, print_yes_no_undef) declare_mp_handler(skip_kpartx, set_yes_no_undef) declare_mp_snprint(skip_kpartx, print_yes_no_undef) - -declare_def_handler(disable_changed_wwids, set_yes_no) -declare_def_snprint(disable_changed_wwids, print_yes_no) +static int def_disable_changed_wwids_handler(struct config *conf, vector strvec) +{ + return 0; +} +static int snprint_def_disable_changed_wwids(struct config *conf, char *buff, + int len, const void *data) +{ + return print_ignored(buff, len); +} declare_def_handler(remove_retries, set_int) declare_def_snprint(remove_retries, print_int) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/discovery.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/discovery.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/discovery.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/discovery.c 2019-04-24 11:43:52.000000000 +0200 @@ -218,12 +218,11 @@ declare_sysfs_get_str(model); declare_sysfs_get_str(rev); -ssize_t -sysfs_get_vpd (struct udev_device * udev, int pg, - unsigned char * buff, size_t len) +static ssize_t +sysfs_get_binary (struct udev_device * udev, const char *attrname, + unsigned char *buff, size_t len) { ssize_t attr_len; - char attrname[9]; const char * devname; if (!udev) { @@ -232,7 +231,6 @@ } devname = udev_device_get_sysname(udev); - sprintf(attrname, "vpd_pg%02x", pg); attr_len = sysfs_bin_attr_get_value(udev, attrname, buff, len); if (attr_len < 0) { condlog(3, "%s: attribute %s not found in sysfs", @@ -242,8 +240,23 @@ return attr_len; } +ssize_t sysfs_get_vpd(struct udev_device * udev, unsigned char pg, + unsigned char *buff, size_t len) +{ + char attrname[9]; + + snprintf(attrname, sizeof(attrname), "vpd_pg%02x", pg); + return sysfs_get_binary(udev, attrname, buff, len); +} + +ssize_t sysfs_get_inquiry(struct udev_device * udev, + unsigned char *buff, size_t len) +{ + return sysfs_get_binary(udev, "inquiry", buff, len); +} + int -sysfs_get_timeout(struct path *pp, unsigned int *timeout) +sysfs_get_timeout(const struct path *pp, unsigned int *timeout) { const char *attr = NULL; const char *subsys; @@ -820,24 +833,34 @@ } static void -detect_alua(struct path * pp, struct config *conf) +detect_alua(struct path * pp) { int ret; int tpgs; - unsigned int timeout = conf->checker_timeout; + unsigned int timeout; - if ((tpgs = get_target_port_group_support(pp->fd, timeout)) <= 0) { + if (sysfs_get_timeout(pp, &timeout) <= 0) + timeout = DEF_TIMEOUT; + + if ((tpgs = get_target_port_group_support(pp, timeout)) <= 0) { pp->tpgs = TPGS_NONE; return; } ret = get_target_port_group(pp, timeout); - if (ret < 0 || get_asymmetric_access_state(pp->fd, ret, timeout) < 0) { + if (ret < 0 || get_asymmetric_access_state(pp, ret, timeout) < 0) { pp->tpgs = TPGS_NONE; return; } pp->tpgs = tpgs; } +int path_get_tpgs(struct path *pp) +{ + if (pp->tpgs == TPGS_UNDEF) + detect_alua(pp); + return pp->tpgs; +} + #define DEFAULT_SGIO_LEN 254 /* Query VPD page @pg. Returns number of INQUIRY bytes @@ -1505,9 +1528,6 @@ struct udev_device *parent; const char *attr_path = NULL; - if (pp->tpgs == TPGS_UNDEF) - detect_alua(pp, conf); - if (!(mask & DI_SERIAL)) return; @@ -1625,8 +1645,17 @@ old_prio = pp->priority; pp->priority = prio_getprio(p, pp, checker_timeout); if (pp->priority < 0) { - condlog(3, "%s: %s prio error", pp->dev, prio_name(p)); - pp->priority = PRIO_UNDEF; + /* this changes pp->offline, but why not */ + int state = path_offline(pp); + + if (state == PATH_DOWN || state == PATH_PENDING) + condlog(3, "%s: %s prio error in state %d, keeping prio = %d", + pp->dev, prio_name(p), state, pp->priority); + else { + condlog(3, "%s: %s prio error in state %d", + pp->dev, prio_name(p), state); + pp->priority = PRIO_UNDEF; + } return 1; } condlog((old_prio == pp->priority ? 4 : 3), "%s: %s prio = %u", @@ -1754,21 +1783,15 @@ return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE); } -static ssize_t scsi_uid_fallback(struct path *pp, int path_state, - const char **origin) +static ssize_t uid_fallback(struct path *pp, int path_state, + const char **origin) { - ssize_t len = 0; - int retrigger; - struct config *conf; + ssize_t len = -1; - conf = get_multipath_config(); - retrigger = conf->retrigger_tries; - put_multipath_config(conf); - if (pp->retriggers >= retrigger && + if (pp->bus == SYSFS_BUS_SCSI && !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) { len = get_vpd_uid(pp); *origin = "sysfs"; - pp->uid_attribute = NULL; if (len < 0 && path_state == PATH_UP) { condlog(1, "%s: failed to get sysfs uid: %s", pp->dev, strerror(-len)); @@ -1776,17 +1799,42 @@ WWID_SIZE); *origin = "sgio"; } + } else if (pp->bus == SYSFS_BUS_NVME) { + char value[256]; + len = sysfs_attr_get_value(pp->udev, "wwid", value, + sizeof(value)); + if (len <= 0) + return -1; + len = strlcpy(pp->wwid, value, WWID_SIZE); + if (len >= WWID_SIZE) { + len = fix_broken_nvme_wwid(pp, value, + WWID_SIZE); + if (len > 0) + return len; + condlog(0, "%s: wwid overflow", pp->dev); + len = WWID_SIZE; + } + *origin = "sysfs"; } return len; } +static int has_uid_fallback(struct path *pp) +{ + return ((pp->bus == SYSFS_BUS_SCSI && + !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) || + pp->bus == SYSFS_BUS_NVME); +} + int -get_uid (struct path * pp, int path_state, struct udev_device *udev) +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; if (!pp->uid_attribute && !pp->getuid) { conf = get_multipath_config(); @@ -1827,8 +1875,10 @@ len = get_vpd_uid(pp); origin = "sysfs"; } - if (len <= 0 && pp->bus == SYSFS_BUS_SCSI) - len = scsi_uid_fallback(pp, path_state, &origin); + if (len <= 0 && allow_fallback && has_uid_fallback(pp)) { + used_fallback = 1; + len = uid_fallback(pp, path_state, &origin); + } } if ( len < 0 ) { condlog(1, "%s: failed to get %s uid: %s", @@ -1844,7 +1894,7 @@ c--; } } - condlog(3, "%s: uid = %s (%s)", pp->dev, + condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev, *pp->wwid == '\0' ? "<empty>" : pp->wwid, origin); return 0; } @@ -1961,14 +2011,12 @@ } else { condlog(3, "%s: path inaccessible", pp->dev); pp->chkrstate = pp->state = path_state; - if (path_state == PATH_PENDING || - path_state == PATH_DOWN) - pp->priority = 0; } } if ((mask & DI_WWID) && !strlen(pp->wwid)) { - get_uid(pp, path_state, pp->udev); + get_uid(pp, path_state, pp->udev, + (pp->retriggers >= conf->retrigger_tries)); if (!strlen(pp->wwid)) { if (pp->bus == SYSFS_BUS_UNDEF) return PATHINFO_SKIPPED; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/discovery.h new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/discovery.h --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/discovery.h 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/discovery.h 2019-04-24 11:43:52.000000000 +0200 @@ -31,7 +31,7 @@ struct config; int path_discovery (vector pathvec, int flag); - +int path_get_tpgs(struct path *pp); /* This function never returns TPGS_UNDEF */ int do_tur (char *); int path_offline (struct path *); int get_state (struct path * pp, struct config * conf, int daemon, int state); @@ -43,16 +43,19 @@ struct udev_device *udevice, int flag, struct path **pp_ptr); int sysfs_set_scsi_tmo (struct multipath *mpp, int checkint); -int sysfs_get_timeout(struct path *pp, unsigned int *timeout); +int sysfs_get_timeout(const struct path *pp, unsigned int *timeout); int sysfs_get_host_pci_name(const struct path *pp, char *pci_name); int sysfs_get_iscsi_ip_address(const struct path *pp, char *ip_address); int sysfs_get_host_adapter_name(const struct path *pp, char *adapter_name); -ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff, - size_t len); +ssize_t sysfs_get_vpd (struct udev_device *udev, unsigned char pg, + unsigned char *buff, size_t len); +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); -int get_uid(struct path * pp, int path_state, struct udev_device *udev); +int get_uid(struct path * pp, int path_state, struct udev_device *udev, + int allow_fallback); /* * discovery bitmask diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/hwtable.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/hwtable.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/hwtable.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/hwtable.c 2019-04-24 11:43:52.000000000 +0200 @@ -604,7 +604,7 @@ .pgpolicy = MULTIBUS, }, { - /* Storwize family / SAN Volume Controller / Flex System V7000 / FlashSystem V840/V9000 */ + /* Storwize family / SAN Volume Controller / Flex System V7000 / FlashSystem V840/V9000/9100 */ .vendor = "IBM", .product = "^2145", .no_path_retry = NO_PATH_RETRY_QUEUE, @@ -701,6 +701,26 @@ .no_path_retry = (300 / DEFAULT_CHECKINT), .prio_name = PRIO_ALUA, }, + /* + * Lenovo + */ + { + /* + * DE Series + * + * Maintainer: ng-eseries-upstream-maintainers@netapp.com + */ + .vendor = "LENOVO", + .product = "DE_Series", + .bl_product = "Universal Xport", + .pgpolicy = GROUP_BY_PRIO, + .checker_name = RDAC, + .features = "2 pg_init_retries 50", + .hwhandler = "1 rdac", + .prio_name = PRIO_RDAC, + .pgfailback = -FAILBACK_IMMEDIATE, + .no_path_retry = 30, + }, /* * NetApp */ @@ -1100,31 +1120,7 @@ .no_path_retry = 30, }, /* - * Xiotech - */ - { - /* Intelligent Storage Elements family */ - .vendor = "(XIOTECH|XIOtech)", - .product = "ISE", - .pgpolicy = MULTIBUS, - .no_path_retry = 12, - }, - { - /* iglu blaze family */ - .vendor = "(XIOTECH|XIOtech)", - .product = "IGLU DISK", - .pgpolicy = MULTIBUS, - .no_path_retry = 30, - }, - { - /* Magnitude family */ - .vendor = "(XIOTECH|XIOtech)", - .product = "Magnitude", - .pgpolicy = MULTIBUS, - .no_path_retry = 30, - }, - /* - * Violin Memory + * Violin Systems */ { /* 3000 / 6000 Series */ @@ -1150,6 +1146,28 @@ .pgpolicy = MULTIBUS, .no_path_retry = 30, }, + /* Xiotech */ + { + /* Intelligent Storage Elements family */ + .vendor = "(XIOTECH|XIOtech)", + .product = "ISE", + .pgpolicy = MULTIBUS, + .no_path_retry = 12, + }, + { + /* iglu blaze family */ + .vendor = "(XIOTECH|XIOtech)", + .product = "IGLU DISK", + .pgpolicy = MULTIBUS, + .no_path_retry = 30, + }, + { + /* Magnitude family */ + .vendor = "(XIOTECH|XIOtech)", + .product = "Magnitude", + .pgpolicy = MULTIBUS, + .no_path_retry = 30, + }, /* * Promise Technology */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/pgpolicies.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/pgpolicies.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/pgpolicies.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/pgpolicies.c 2019-04-24 11:43:52.000000000 +0200 @@ -312,7 +312,7 @@ int group_by_prio(struct multipath *mp) { int i; - unsigned int prio; + int prio; struct path * pp; struct pathgroup * pgp; vector pathvec = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/Makefile new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/Makefile --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/Makefile 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/Makefile 2019-04-24 11:43:52.000000000 +0200 @@ -28,9 +28,6 @@ all: $(LIBS) -libprioalua.so: alua.o alua_rtpg.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ - libpriopath_latency.so: path_latency.o ../checkers/libsg.o $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/alua.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/alua.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/alua.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/alua.c 2019-04-24 11:43:52.000000000 +0200 @@ -58,7 +58,7 @@ tpg = get_target_port_group(pp, timeout); if (tpg < 0) { - rc = get_target_port_group_support(pp->fd, timeout); + rc = get_target_port_group_support(pp, timeout); if (rc < 0) return -ALUA_PRIO_TPGS_FAILED; if (rc == TPGS_NONE) @@ -66,7 +66,7 @@ return -ALUA_PRIO_RTPG_FAILED; } condlog(3, "%s: reported target port group is %i", pp->dev, tpg); - rc = get_asymmetric_access_state(pp->fd, tpg, timeout); + rc = get_asymmetric_access_state(pp, tpg, timeout); if (rc < 0) { condlog(2, "%s: get_asymmetric_access_state returned %d", __func__, rc); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/alua_rtpg.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/alua_rtpg.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/alua_rtpg.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/alua_rtpg.c 2019-04-24 11:43:52.000000000 +0200 @@ -135,9 +135,9 @@ /* * Helper function to setup and run a SCSI inquiry command. */ -int -do_inquiry(int fd, int evpd, unsigned int codepage, - void *resp, int resplen, unsigned int timeout) +static int +do_inquiry_sg(int fd, int evpd, unsigned int codepage, + void *resp, int resplen, unsigned int timeout) { struct inquiry_command cmd; struct sg_io_hdr hdr; @@ -185,18 +185,41 @@ return 0; } +int do_inquiry(const struct path *pp, int evpd, unsigned int codepage, + void *resp, int resplen, unsigned int timeout) +{ + struct udev_device *ud; + + ud = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", + "scsi_device"); + if (ud != NULL) { + int rc; + + if (!evpd) + rc = sysfs_get_inquiry(ud, resp, resplen); + else + rc = sysfs_get_vpd(ud, codepage, resp, resplen); + + if (rc >= 0) { + PRINT_HEX((unsigned char *) resp, resplen); + return 0; + } + } + return do_inquiry_sg(pp->fd, evpd, codepage, resp, resplen, timeout); +} + /* * This function returns the support for target port groups by evaluating the * data returned by the standard inquiry command. */ int -get_target_port_group_support(int fd, unsigned int timeout) +get_target_port_group_support(const struct path *pp, unsigned int timeout) { struct inquiry_data inq; int rc; memset((unsigned char *)&inq, 0, sizeof(inq)); - rc = do_inquiry(fd, 0, 0x00, &inq, sizeof(inq), timeout); + rc = do_inquiry(pp, 0, 0x00, &inq, sizeof(inq), timeout); if (!rc) { rc = inquiry_data_get_tpgs(&inq); } @@ -205,7 +228,7 @@ } static int -get_sysfs_pg83(struct path *pp, unsigned char *buff, int buflen) +get_sysfs_pg83(const struct path *pp, unsigned char *buff, int buflen) { struct udev_device *parent = pp->udev; @@ -224,7 +247,7 @@ } int -get_target_port_group(struct path * pp, unsigned int timeout) +get_target_port_group(const struct path * pp, unsigned int timeout) { unsigned char *buf; struct vpd83_data * vpd83; @@ -245,7 +268,7 @@ rc = get_sysfs_pg83(pp, buf, buflen); if (rc < 0) { - rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen, timeout); + rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); if (rc < 0) goto out; @@ -263,7 +286,7 @@ } buflen = scsi_buflen; memset(buf, 0, buflen); - rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen, timeout); + rc = do_inquiry(pp, 1, 0x83, buf, buflen, timeout); if (rc < 0) goto out; } @@ -341,7 +364,8 @@ } int -get_asymmetric_access_state(int fd, unsigned int tpg, unsigned int timeout) +get_asymmetric_access_state(const struct path *pp, unsigned int tpg, + unsigned int timeout) { unsigned char *buf; struct rtpg_data * tpgd; @@ -349,6 +373,7 @@ int rc; int buflen; uint64_t scsi_buflen; + int fd = pp->fd; buflen = 4096; buf = (unsigned char *)malloc(buflen); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/alua_rtpg.h new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/alua_rtpg.h --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/alua_rtpg.h 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/alua_rtpg.h 2019-04-24 11:43:52.000000000 +0200 @@ -22,8 +22,9 @@ #define RTPG_RTPG_FAILED 3 #define RTPG_TPG_NOT_FOUND 4 -int get_target_port_group_support(int fd, unsigned int timeout); -int get_target_port_group(struct path * pp, unsigned int timeout); -int get_asymmetric_access_state(int fd, unsigned int tpg, unsigned int timeout); +int get_target_port_group_support(const struct path *pp, unsigned int timeout); +int get_target_port_group(const struct path *pp, unsigned int timeout); +int get_asymmetric_access_state(const struct path *pp, + unsigned int tpg, unsigned int timeout); #endif /* __RTPG_H__ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/ana.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/ana.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/prioritizers/ana.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/prioritizers/ana.c 2019-04-24 11:43:52.000000000 +0200 @@ -164,7 +164,7 @@ ana_log, ana_log_len); pthread_cleanup_pop(1); if (rc >= 0) - condlog(3, "%s: ana state = %02x [%s]", pp->dev, rc, + condlog(4, "%s: ana state = %02x [%s]", pp->dev, rc, aas_print_string(rc)); return rc; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/propsel.c new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/propsel.c --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/propsel.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/propsel.c 2019-04-24 11:43:52.000000000 +0200 @@ -45,22 +45,30 @@ } \ } while(0) -#define do_set_from_vec(type, var, src, dest, msg) \ -do { \ +#define __do_set_from_vec(type, var, src, dest) \ +({ \ type *_p; \ + bool _found = false; \ int i; \ \ vector_foreach_slot(src, _p, i) { \ if (_p->var) { \ dest = _p->var; \ - origin = msg; \ - goto out; \ + _found = true; \ + break; \ } \ } \ -} while (0) + _found; \ +}) -#define do_set_from_hwe(var, src, dest, msg) \ - do_set_from_vec(struct hwentry, var, src->hwe, dest, msg) +#define __do_set_from_hwe(var, src, dest) \ + __do_set_from_vec(struct hwentry, var, (src)->hwe, dest) + +#define do_set_from_hwe(var, src, dest, msg) \ + if (__do_set_from_hwe(var, src, dest)) { \ + origin = msg; \ + goto out; \ + } static const char default_origin[] = "(setting: multipath internal)"; static const char hwe_origin[] = @@ -440,7 +448,7 @@ dh_state = &handler[2]; vector_foreach_slot(mp->paths, pp, i) - all_tpgs = all_tpgs && (pp->tpgs > 0); + all_tpgs = all_tpgs && (path_get_tpgs(pp) > 0); if (mp->retain_hwhandler != RETAIN_HWHANDLER_OFF) { vector_foreach_slot(mp->paths, pp, i) { if (get_dh_state(pp, dh_state, sizeof(handler) - 2) > 0 @@ -485,9 +493,14 @@ { int len; char buff[44]; + const char *checker_name; if (pp->bus != SYSFS_BUS_SCSI) return 0; + /* Avoid ioctl if this is likely not an RDAC array */ + if (__do_set_from_hwe(checker_name, pp, checker_name) && + strcmp(checker_name, RDAC)) + return 0; len = get_vpd_sgio(pp->fd, 0xC9, buff, 44); if (len <= 0) return 0; @@ -505,7 +518,7 @@ if (check_rdac(pp)) { ckr_name = RDAC; goto out; - } else if (pp->tpgs > 0) { + } else if (path_get_tpgs(pp) != TPGS_NONE) { ckr_name = TUR; goto out; } @@ -567,6 +580,7 @@ struct prio *p = &pp->prio; char buff[512]; char *default_prio; + int tpgs; switch(pp->bus) { case SYSFS_BUS_NVME: @@ -575,9 +589,10 @@ default_prio = PRIO_ANA; break; case SYSFS_BUS_SCSI: - if (pp->tpgs <= 0) + tpgs = path_get_tpgs(pp); + if (tpgs == TPGS_NONE) return; - if ((pp->tpgs == 2 || !check_rdac(pp)) && + if ((tpgs == TPGS_EXPLICIT || !check_rdac(pp)) && sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0) default_prio = PRIO_SYSFS; else @@ -622,6 +637,7 @@ const char *origin; struct mpentry * mpe; struct prio * p = &pp->prio; + int log_prio = 3; if (pp->detect_prio == DETECT_PRIO_ON) { detect_prio(conf, pp); @@ -643,14 +659,16 @@ * fetch tpgs mode for alua, if its not already obtained */ if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) { - int tpgs = 0; - unsigned int timeout = conf->checker_timeout; + int tpgs = path_get_tpgs(pp); - if(!pp->tpgs && - (tpgs = get_target_port_group_support(pp->fd, timeout)) >= 0) - pp->tpgs = tpgs; + if (tpgs == TPGS_NONE) { + prio_get(conf->multipath_dir, + p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS); + origin = "(setting: emergency fallback - alua failed)"; + log_prio = 1; + } } - condlog(3, "%s: prio = %s %s", pp->dev, prio_name(p), origin); + condlog(log_prio, "%s: prio = %s %s", pp->dev, prio_name(p), origin); condlog(3, "%s: prio args = \"%s\" %s", pp->dev, prio_args(p), origin); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/structs.h new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/structs.h --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/structs.h 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/structs.h 2019-04-24 11:43:52.000000000 +0200 @@ -280,7 +280,6 @@ int fd; int initialized; int retriggers; - int wwid_changed; unsigned int path_failures; time_t dis_reinstate_time; int disable_reinstate; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/version.h new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/version.h --- old/multipath-tools-0.8.0+17+suse.a28893f/libmultipath/version.h 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/libmultipath/version.h 2019-04-24 11:43:52.000000000 +0200 @@ -20,8 +20,8 @@ #ifndef _VERSION_H #define _VERSION_H -#define VERSION_CODE 0x000800 -#define DATE_CODE 0x020e13 +#define VERSION_CODE 0x000801 +#define DATE_CODE 0x041213 #define PROG "multipath-tools" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/multipath/main.c new/multipath-tools-0.8.1+8+suse.8c11498/multipath/main.c --- old/multipath-tools-0.8.0+17+suse.a28893f/multipath/main.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/multipath/main.c 2019-04-24 11:43:52.000000000 +0200 @@ -850,6 +850,32 @@ return r; } +static int test_multipathd_socket(void) +{ + int fd; + /* + * "multipath -u" may be run before the daemon is started. In this + * case, systemd might own the socket but might delay multipathd + * startup until some other unit (udev settle!) has finished + * starting. With many LUNs, the listen backlog may be exceeded, which + * would cause connect() to block. This causes udev workers calling + * "multipath -u" to hang, and thus creates a deadlock, until "udev + * settle" times out. To avoid this, call connect() in non-blocking + * mode here, and take EAGAIN as indication for a filled-up systemd + * backlog. + */ + + fd = __mpath_connect(1); + if (fd == -1) { + if (errno == EAGAIN) + condlog(3, "daemon backlog exceeded"); + else + return 0; + } else + close(fd); + return 1; +} + int main (int argc, char *argv[]) { @@ -1028,17 +1054,13 @@ } if (cmd == CMD_VALID_PATH && dev_type == DEV_UEVENT) { - int fd; - - fd = mpath_connect(); - if (fd == -1) { + if (!test_multipathd_socket()) { condlog(3, "%s: daemon is not running", dev); if (!systemd_service_enabled(dev)) { r = print_cmd_valid(RTVL_NO, NULL, conf); goto out; } - } else - mpath_disconnect(fd); + } } if (cmd == CMD_REMOVE_WWID && !dev) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/multipath/multipath.conf.5 new/multipath-tools-0.8.1+8+suse.8c11498/multipath/multipath.conf.5 --- old/multipath-tools-0.8.0+17+suse.a28893f/multipath/multipath.conf.5 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/multipath/multipath.conf.5 2019-04-24 11:43:52.000000000 +0200 @@ -260,11 +260,11 @@ The udev attribute providing a unique path identifier. .RS .TP -The default is: for SCSI devices \fBID_SERIAL\fR +The default is: \fBID_SERIAL\fR, for SCSI devices .TP -The default is: for DASD devices \fBID_UID\fR +The default is: \fBID_UID\fR, for DASD devices .TP -The default is: for NVME devices \fBID_WWN\fR +The default is: \fBID_WWN\fR, for NVMe devices .RE . . @@ -677,7 +677,7 @@ will disable the timeout. .RS .TP -The default is: in \fB5\fR +The default is: \fB5\fR .RE . . @@ -725,7 +725,7 @@ \fIreservation_key\fR is set to \fBfile\fR. .RS .TP -The default is \fB/etc/multipath/prkeys\fR +The default is: \fB/etc/multipath/prkeys\fR .RE . . @@ -1155,12 +1155,8 @@ . .TP .B disable_changed_wwids -If set to \fIyes\fR, multipathd will check the path wwid on change events, and -if it has changed from the wwid of the multipath device, multipathd will -disable access to the path until the wwid changes back. -.RS -.TP -The default is: \fBno\fR +This option is deprecated and ignored. If the WWID of a path suddenly changes, +multipathd handles it as if it was removed and then added again. .RE . . @@ -1193,7 +1189,7 @@ makes multipath immediately mark a device with only ghost paths as ready. .RS .TP -The default is \fBno\fR +The default is: \fBno\fR .RE . . @@ -1475,6 +1471,8 @@ .TP .B uid_attribute .TP +.B getuid_callout +.TP .B path_selector .TP .B path_checker @@ -1501,6 +1499,8 @@ .TP .B flush_on_last_del .TP +.B user_friendly_names +.TP .B retain_attached_hw_handler .TP .B detect_prio @@ -1532,6 +1532,8 @@ .B max_sectors_kb .TP .B ghost_delay +.TP +.B all_tg_pt .RE .PD .LP @@ -1611,7 +1613,11 @@ .TP .B skip_kpartx .TP +.B max_sectors_kb +.TP .B ghost_delay +.TP +.B all_tg_pt .RE .PD .LP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/multipath-tools-0.8.0+17+suse.a28893f/multipathd/main.c new/multipath-tools-0.8.1+8+suse.8c11498/multipathd/main.c --- old/multipath-tools-0.8.0+17+suse.a28893f/multipathd/main.c 2019-03-15 13:27:19.000000000 +0100 +++ new/multipath-tools-0.8.1+8+suse.8c11498/multipathd/main.c 2019-04-24 11:43:52.000000000 +0200 @@ -127,11 +127,22 @@ #else int poll_dmevents = 1; #endif +/* Don't access this variable without holding config_lock */ enum daemon_status running_state = DAEMON_INIT; pid_t daemon_pid; pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t config_cond; +static inline enum daemon_status get_running_state(void) +{ + enum daemon_status st; + + pthread_mutex_lock(&config_lock); + st = running_state; + pthread_mutex_unlock(&config_lock); + return st; +} + /* * global copy of vecs for use in sig handlers */ @@ -149,7 +160,7 @@ const char * daemon_status(void) { - switch (running_state) { + switch (get_running_state()) { case DAEMON_INIT: return "init"; case DAEMON_START: @@ -169,10 +180,10 @@ /* * I love you too, systemd ... */ -const char * -sd_notify_status(void) +static const char * +sd_notify_status(enum daemon_status state) { - switch (running_state) { + switch (state) { case DAEMON_INIT: return "STATUS=init"; case DAEMON_START: @@ -189,17 +200,18 @@ } #ifdef USE_SYSTEMD -static void do_sd_notify(enum daemon_status old_state) +static void do_sd_notify(enum daemon_status old_state, + enum daemon_status new_state) { /* * Checkerloop switches back and forth between idle and running state. * No need to tell systemd each time. * These notifications cause a lot of overhead on dbus. */ - if ((running_state == DAEMON_IDLE || running_state == DAEMON_RUNNING) && + if ((new_state == DAEMON_IDLE || new_state == DAEMON_RUNNING) && (old_state == DAEMON_IDLE || old_state == DAEMON_RUNNING)) return; - sd_notify(0, sd_notify_status()); + sd_notify(0, sd_notify_status(new_state)); } #endif @@ -208,6 +220,7 @@ pthread_mutex_unlock(&config_lock); } +/* must be called with config_lock held */ static void __post_config_state(enum daemon_status state) { if (state != running_state && running_state != DAEMON_SHUTDOWN) { @@ -216,7 +229,7 @@ running_state = state; pthread_cond_broadcast(&config_cond); #ifdef USE_SYSTEMD - do_sd_notify(old_state); + do_sd_notify(old_state, state); #endif } } @@ -253,7 +266,7 @@ running_state = state; pthread_cond_broadcast(&config_cond); #ifdef USE_SYSTEMD - do_sd_notify(old_state); + do_sd_notify(old_state, state); #endif } } @@ -937,7 +950,8 @@ } if (mpp && mpp->wait_for_udev && (pathcount(mpp, PATH_UP) > 0 || - (pathcount(mpp, PATH_GHOST) > 0 && pp->tpgs != TPGS_IMPLICIT && + (pathcount(mpp, PATH_GHOST) > 0 && + path_get_tpgs(pp) != TPGS_IMPLICIT && mpp->ghost_delay_tick <= 0))) { /* if wait_for_udev is set and valid paths exist */ condlog(3, "%s: delaying path addition until %s is fully initialized", @@ -1191,7 +1205,6 @@ int ro, retval = 0, rc; struct path * pp; struct config *conf; - int disable_changed_wwids; int needs_reinit = 0; switch ((rc = change_foreign(uev->udev))) { @@ -1209,12 +1222,6 @@ break; } - conf = get_multipath_config(); - disable_changed_wwids = conf->disable_changed_wwids; - put_multipath_config(conf); - - ro = uevent_get_disk_ro(uev); - pthread_cleanup_push(cleanup_lock, &vecs->lock); lock(&vecs->lock); pthread_testcancel(); @@ -1234,25 +1241,17 @@ goto out; strcpy(wwid, pp->wwid); - get_uid(pp, pp->state, uev->udev); + rc = get_uid(pp, pp->state, uev->udev, 0); - if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { - condlog(0, "%s: path wwid changed from '%s' to '%s'. %s", - uev->kernel, wwid, pp->wwid, - (disable_changed_wwids ? "disallowing" : - "continuing")); + if (rc != 0) strcpy(pp->wwid, wwid); - if (disable_changed_wwids) { - if (!pp->wwid_changed) { - pp->wwid_changed = 1; - pp->tick = 1; - if (pp->mpp) - dm_fail_path(pp->mpp->alias, pp->dev_t); - } - goto out; - } + else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { + condlog(0, "%s: path wwid changed from '%s' to '%s'", + uev->kernel, wwid, pp->wwid); + ev_remove_path(pp, vecs, 1); + needs_reinit = 1; + goto out; } else { - pp->wwid_changed = 0; udev_device_unref(pp->udev); pp->udev = udev_device_ref(uev->udev); conf = get_multipath_config(); @@ -1263,6 +1262,7 @@ pthread_cleanup_pop(1); } + ro = uevent_get_disk_ro(uev); if (mpp && ro >= 0) { condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro); @@ -1411,17 +1411,20 @@ int r = 0; struct vectors * vecs; struct uevent *merge_uev, *tmp; + enum daemon_status state; vecs = (struct vectors *)trigger_data; pthread_cleanup_push(config_cleanup, NULL); pthread_mutex_lock(&config_lock); - if (running_state != DAEMON_IDLE && - running_state != DAEMON_RUNNING) + while (running_state != DAEMON_IDLE && + running_state != DAEMON_RUNNING && + running_state != DAEMON_SHUTDOWN) pthread_cond_wait(&config_cond, &config_lock); + state = running_state; pthread_cleanup_pop(1); - if (running_state == DAEMON_SHUTDOWN) + if (state == DAEMON_SHUTDOWN) return 0; /* @@ -2015,12 +2018,6 @@ if (newstate == PATH_REMOVED) newstate = PATH_DOWN; - if (pp->wwid_changed) { - condlog(2, "%s: path wwid has changed. Refusing to use", - pp->dev); - newstate = PATH_DOWN; - } - if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) { condlog(2, "%s: unusable path (%s) - checker failed", pp->dev, checker_state_name(newstate)); @@ -2112,8 +2109,8 @@ * paths if there are no other active paths in map. */ disable_reinstate = (newstate == PATH_GHOST && - pp->mpp->nr_active == 0 && - pp->tpgs == TPGS_IMPLICIT) ? 1 : 0; + pp->mpp->nr_active == 0 && + path_get_tpgs(pp) == TPGS_IMPLICIT) ? 1 : 0; pp->chkrstate = newstate; if (newstate != pp->state) { @@ -2775,6 +2772,7 @@ struct config *conf; char *envp; int queue_without_daemon; + enum daemon_status state; mlockall(MCL_CURRENT | MCL_FUTURE); signal_init(); @@ -2872,6 +2870,7 @@ /* Wait for uxlsnr startup */ while (running_state == DAEMON_IDLE) pthread_cond_wait(&config_cond, &config_lock); + state = running_state; } pthread_cleanup_pop(1); @@ -2879,7 +2878,7 @@ condlog(0, "failed to create cli listener: %d", rc); goto failed; } - else if (running_state != DAEMON_CONFIGURE) { + else if (state != DAEMON_CONFIGURE) { condlog(0, "cli listener failed to start"); goto failed; } @@ -2919,15 +2918,17 @@ } pthread_attr_destroy(&misc_attr); - while (running_state != DAEMON_SHUTDOWN) { + while (1) { pthread_cleanup_push(config_cleanup, NULL); pthread_mutex_lock(&config_lock); - if (running_state != DAEMON_CONFIGURE && - running_state != DAEMON_SHUTDOWN) { + while (running_state != DAEMON_CONFIGURE && + running_state != DAEMON_SHUTDOWN) pthread_cond_wait(&config_cond, &config_lock); - } + state = running_state; pthread_cleanup_pop(1); - if (running_state == DAEMON_CONFIGURE) { + if (state == DAEMON_SHUTDOWN) + break; + if (state == DAEMON_CONFIGURE) { pthread_cleanup_push(cleanup_lock, &vecs->lock); lock(&vecs->lock); pthread_testcancel(); @@ -3097,8 +3098,6 @@ ANNOTATE_BENIGN_RACE_SIZED(&multipath_conf, sizeof(multipath_conf), "Manipulated through RCU"); - ANNOTATE_BENIGN_RACE_SIZED(&running_state, sizeof(running_state), - "Suppress complaints about unprotected running_state reads"); ANNOTATE_BENIGN_RACE_SIZED(&uxsock_timeout, sizeof(uxsock_timeout), "Suppress complaints about this scalar variable");