###############################################################################
name = multipath-tools
-version = %{rel_ver}.%{rel_date}
+version = 0.6.3
release = 1
-thisapp = %{name}-%{rel_date}
-rel_ver = 0.4.9
-rel_date = 130222
-
groups = System/Base
url = http://christophe.varoqui.free.fr/
license = GPL+
instructing the device-mapper multipath kernel module what to do.
end
-sources = %{thisapp}.tgz
+# git archive 0.6.3 --prefix=multipath-tools-0.6.3/ --format=tar | gzip --best > multipath-tools-0.6.3.tar.gz
+sources = %{thisapp}.tar.gz
build
requires
readline-devel
end
- make_build_targets += LIB=%{lib}
+ make_build_targets += -C kpartx LIB=%{lib} LDFLAGS="%{LDFLAGS} -ldevmapper"
# Install everything to the correct locations.
make_install_targets += \
+ -C kpartx \
bindir=%{sbindir} \
syslibdir=%{libdir} \
libdir=%{libdir}/multipath \
unitdir=%{unitdir}
-
- install_cmds
- # Remove old SysV init script and folder.
- rm -rf %{BUILDROOT}/etc/rc.d
-
- # Install configuration file.
- install -m 0664 %{DIR_SOURCE}/multipath.conf %{BUILDROOT}%{sysconfdir}/multipath.conf
- end
end
packages
- package %{name}
- configfiles
- /etc/multipath.conf
- end
-
- script postin
- /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || :
- end
-
- script preun
- /usr/bin/systemctl --no-reload disable multipathd.service >/dev/null 2>&1 || :
- /usr/bin/systemctl stop multipathd.service >/dev/null 2>&1 || :
- end
-
- script postun
- /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || :
- end
-
- script postup
- /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || :
- /usr/bin/systemctl try-restart multipathd.service >/dev/null 2>&1 || :
- end
- end
-
package kpartx
summary = Partition manager for device-mapper devices.
description
end
end
- package %{name}-devel
- template DEVEL
- end
-
package %{name}-debuginfo
template DEBUGINFO
end
+++ /dev/null
----
- multipathd/multipathd.service | 1 +
- 1 file changed, 1 insertion(+)
-
-Index: multipath-tools-130222/multipathd/multipathd.service
-===================================================================
---- multipath-tools-130222.orig/multipathd/multipathd.service
-+++ multipath-tools-130222/multipathd/multipathd.service
-@@ -2,6 +2,7 @@
- Description=Device-Mapper Multipath Device Controller
- Before=iscsi.service iscsid.service lvm2-activation-early.service
- After=syslog.target
-+ConditionPathExists=/etc/multipath.conf
- DefaultDependencies=no
- Conflicts=shutdown.target
-
+++ /dev/null
----
- multipath/Makefile | 3 +++
- multipath/multipath.rules | 24 ++++++++++++++++++++++++
- 2 files changed, 27 insertions(+)
-
-Index: multipath-tools-130222/multipath/multipath.rules
-===================================================================
---- /dev/null
-+++ multipath-tools-130222/multipath/multipath.rules
-@@ -0,0 +1,24 @@
-+# multipath wants the devmaps presented as meaninglful device names
-+# so name them after their devmap name
-+SUBSYSTEM!="block", GOTO="end_mpath"
-+
-+ENV{MPATH_SBIN_PATH}="/sbin"
-+TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
-+
-+ACTION=="add", ENV{DEVTYPE}!="partition", \
-+ ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
-+ TEST=="/etc/multipath.conf", \
-+ PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
-+ ENV{DM_MULTIPATH_DEVICE_PATH}="1"
-+
-+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
-+ RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
-+
-+KERNEL!="dm-*", GOTO="end_mpath"
-+ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
-+ACTION!="change", GOTO="end_mpath"
-+ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
-+ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
-+ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
-+RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
-+LABEL="end_mpath"
-Index: multipath-tools-130222/multipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipath/Makefile
-+++ multipath-tools-130222/multipath/Makefile
-@@ -21,12 +21,15 @@ $(EXEC): $(OBJS)
- install:
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
-+ $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
-+ $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
-
- uninstall:
-+ rm $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
- rm $(DESTDIR)$(bindir)/$(EXEC)
- rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
- rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
+++ /dev/null
-From f5e11246063b07d6dce6d37d3b74662475baa981 Mon Sep 17 00:00:00 2001
-From: Fabio M. Di Nitto <fdinitto@redhat.com>
-Date: Thu, 15 Oct 2009 04:39:27 +0200
-Subject: [PATCH 08/12] RH: Make build system RH/Fedora friendly
-
-Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
----
-:100644 100644 7ec25d5... 06fb625... M Makefile.inc
-:100644 100644 21e4ad4... 06d79c0... M kpartx/Makefile
-:100644 100644 32d9ef5... 25e1483... M multipathd/Makefile
- Makefile.inc | 2 +-
- kpartx/Makefile | 10 +++++-----
- libmpathpersist/Makefile | 7 ++-----
- libmultipath/Makefile | 2 ++
- multipathd/Makefile | 1 +
- 5 files changed, 11 insertions(+), 11 deletions(-)
-
-Index: multipath-tools-130222/Makefile.inc
-===================================================================
---- multipath-tools-130222.orig/Makefile.inc
-+++ multipath-tools-130222/Makefile.inc
-@@ -29,7 +29,7 @@ multipathdir = $(TOPDIR)/libmultipath
- mandir = $(prefix)/usr/share/man/man8
- man5dir = $(prefix)/usr/share/man/man5
- man3dir = $(prefix)/usr/share/man/man3
--rcdir = $(prefix)/etc/init.d
-+rcdir = $(prefix)/etc/rc.d/init.d
- syslibdir = $(prefix)/$(LIB)
- libdir = $(prefix)/$(LIB)/multipath
- unitdir = $(prefix)/lib/systemd/system
-Index: multipath-tools-130222/kpartx/Makefile
-===================================================================
---- multipath-tools-130222.orig/kpartx/Makefile
-+++ multipath-tools-130222/kpartx/Makefile
-@@ -26,17 +26,17 @@ $(EXEC): $(OBJS)
- install: $(EXEC) $(EXEC).8
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
-- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)
-- $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir)
-- $(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d
-- $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)/etc/udev/rules.d/
-+# $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)
-+# $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir)
-+# $(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d
-+# $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)/etc/udev/rules.d/
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
-
- uninstall:
- rm -f $(DESTDIR)$(bindir)/$(EXEC)
- rm -f $(DESTDIR)$(mandir)/$(EXEC).8.gz
-- rm -f $(DESTDIR)$(libudevdir)/kpartx_id
-+# rm -f $(DESTDIR)$(libudevdir)/kpartx_id
-
- clean:
- rm -f core *.o $(EXEC) *.gz
-Index: multipath-tools-130222/multipathd/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipathd/Makefile
-+++ multipath-tools-130222/multipathd/Makefile
-@@ -35,6 +35,7 @@ install:
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(rcdir)
-+ $(INSTALL_PROGRAM) -m 755 multipathd.init.redhat $(DESTDIR)$(rcdir)/$(EXEC)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
-Index: multipath-tools-130222/libmultipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/libmultipath/Makefile
-+++ multipath-tools-130222/libmultipath/Makefile
-@@ -46,9 +46,11 @@ install:
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir)
-+ ln -sf $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
-
- uninstall:
- rm -f $(DESTDIR)$(syslibdir)/$(LIBS)
-+ rm -f $(DESTDIR)$(syslibdir)/$(DEVLIB)
-
- clean:
- rm -f core *.a *.o *.gz *.so *.so.*
-Index: multipath-tools-130222/libmpathpersist/Makefile
-===================================================================
---- multipath-tools-130222.orig/libmpathpersist/Makefile
-+++ multipath-tools-130222/libmpathpersist/Makefile
-@@ -28,17 +28,14 @@ $(LIBS):
- install: $(LIBS)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
-- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir)
- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(man3dir)
-- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)/usr/include/
-- $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)/usr/share/doc/mpathpersist/
-- ln -sf $(DESTDIR)$(syslibdir)/$(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
-+ ln -sf $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
- install -m 644 mpath_persistent_reserve_in.3.gz $(DESTDIR)$(man3dir)
- install -m 644 mpath_persistent_reserve_out.3.gz $(DESTDIR)$(man3dir)
-- install -m 644 mpath_persist.h $(DESTDIR)/usr/include/
-
- uninstall:
- rm -f $(DESTDIR)$(syslibdir)/$(LIBS)
-+ rm -f $(DESTDIR)$(syslibdir)/$(DEVLIB)
- rm $(DESTDIR)$(mandir)/mpath_persistent_reserve_in.3.gz
- rm $(DESTDIR)$(mandir)/mpath_persistent_reserve_out.3.gz
-
+++ /dev/null
-From 61b2002c6b2752c15b431e400cd614edc8c5b039 Mon Sep 17 00:00:00 2001
-From: Fabio M. Di Nitto <fdinitto@redhat.com>
-Date: Mon, 19 Oct 2009 07:05:45 +0200
-Subject: [PATCH 09/12] RH: multipathd blacklist all by default
-
-If there is no configuration installed on the system, blacklist
-everything by default.
-
-BZ#528059
-
-Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
----
-:100644 100644 e7e962e... 5aa1ab0... M libmultipath/config.c
-:100644 100644 86b1320... 7e90e75... M libmultipath/config.h
- libmultipath/config.c | 16 ++++++++++++++++
- libmultipath/config.h | 1 +
- 2 files changed, 17 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -21,6 +21,7 @@
- #include "defaults.h"
- #include "prio.h"
- #include "devmapper.h"
-+#include "version.h"
-
- static int
- hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2)
-@@ -585,6 +586,21 @@ load_config (char * file)
-
- } else {
- init_keywords();
-+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
-+ condlog(0, "A default multipath.conf file is located at");
-+ condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
-+ if (conf->blist_devnode == NULL) {
-+ conf->blist_devnode = vector_alloc();
-+ if (!conf->blist_devnode) {
-+ condlog(0, "cannot allocate blacklist\n");
-+ goto out;
-+ }
-+ }
-+ if (store_ble(conf->blist_devnode, strdup(".*"),
-+ ORIGIN_NO_CONFIG)) {
-+ condlog(0, "cannot store default no-config blacklist\n");
-+ goto out;
-+ }
- }
-
- /*
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -6,6 +6,7 @@
-
- #define ORIGIN_DEFAULT 0
- #define ORIGIN_CONFIG 1
-+#define ORIGIN_NO_CONFIG 2
-
- /*
- * In kernel, fast_io_fail == 0 means immediate failure on rport delete.
+++ /dev/null
----
- libmultipath/config.c | 1
- multipath/Makefile | 5
- multipath/main.c | 4
- multipath/mpathconf | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++
- multipath/mpathconf.8 | 103 ++++++++++++++++
- 5 files changed, 423 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -589,6 +589,7 @@ load_config (char * file)
- condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
- condlog(0, "A default multipath.conf file is located at");
- condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
-+ condlog(0, "You can run /sbin/mpathconf to create or modify /etc/multipath.conf");
- if (conf->blist_devnode == NULL) {
- conf->blist_devnode = vector_alloc();
- if (!conf->blist_devnode) {
-Index: multipath-tools-130222/multipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipath/Makefile
-+++ multipath-tools-130222/multipath/Makefile
-@@ -17,22 +17,27 @@ $(EXEC): $(OBJS)
- $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS)
- $(GZIP) $(EXEC).8 > $(EXEC).8.gz
- $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
-+ $(GZIP) mpathconf.8 > mpathconf.8.gz
-
- install:
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
-+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
- $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
-+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(mandir)
-
- uninstall:
- rm $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
- rm $(DESTDIR)$(bindir)/$(EXEC)
-+ rm $(DESTDIR)$(bindir)/mpathconf
- rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
- rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
-+ rm $(DESTDIR)$(mandir)/mpathconf.8.gz
-
- clean:
- rm -f core *.o $(EXEC) *.gz
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -433,10 +433,10 @@ main (int argc, char *argv[])
- exit(1);
- }
-
-- if (dm_prereq())
-+ if (load_config(DEFAULT_CONFIGFILE))
- exit(1);
-
-- if (load_config(DEFAULT_CONFIGFILE))
-+ if (dm_prereq())
- exit(1);
-
- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) {
-Index: multipath-tools-130222/multipath/mpathconf
-===================================================================
---- /dev/null
-+++ multipath-tools-130222/multipath/mpathconf
-@@ -0,0 +1,312 @@
-+#!/bin/sh
-+#
-+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
-+#
-+# This file is part of the device-mapper-multipath package.
-+#
-+# This copyrighted material is made available to anyone wishing to use,
-+# modify, copy, or redistribute it subject to the terms and conditions
-+# of the GNU General Public License v.2.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program; if not, write to the Free Software Foundation,
-+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+#
-+# Simple editting of /etc/multipath.conf
-+# This program was largely ripped off from lvmconf
-+#
-+
-+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE SHOW_STATUS CHANGED_CONFIG
-+
-+DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf"
-+CONFIGFILE="/etc/multipath.conf"
-+MULTIPATHDIR="/etc/multipath"
-+TMPFILE=/etc/multipath/.multipath.conf.tmp
-+
-+function usage
-+{
-+ echo "usage: $0 <command>"
-+ echo ""
-+ echo "Commands:"
-+ echo "Enable: --enable "
-+ echo "Disable: --disable"
-+ echo "Set user_friendly_names (Default n): --user_friendly_names <y|n>"
-+ echo "Set find_multipaths (Default n): --find_multipaths <y|n>"
-+ echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
-+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
-+ echo ""
-+}
-+
-+function parse_args
-+{
-+ while [ -n "$1" ]; do
-+ case $1 in
-+ --enable)
-+ ENABLE=1
-+ shift
-+ ;;
-+ --disable)
-+ ENABLE=0
-+ shift
-+ ;;
-+ --user_friendly_names)
-+ if [ -n "$2" ]; then
-+ FRIENDLY=$2
-+ shift 2
-+ else
-+ usage
-+ exit 1
-+ fi
-+ ;;
-+ --find_multipaths)
-+ if [ -n "$2" ]; then
-+ FIND=$2
-+ shift 2
-+ else
-+ usage
-+ exit 1
-+ fi
-+ ;;
-+ --with_module)
-+ if [ -n "$2" ]; then
-+ MODULE=$2
-+ shift 2
-+ else
-+ usage
-+ exit 1
-+ fi
-+ ;;
-+ --with_multipathd)
-+ if [ -n "$2" ]; then
-+ MULTIPATHD=$2
-+ shift 2
-+ else
-+ usage
-+ exit 1
-+ fi
-+ ;;
-+ *)
-+ usage
-+ exit
-+ esac
-+ done
-+}
-+
-+function validate_args
-+{
-+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then
-+ echo "ignoring extra parameters on disable"
-+ FRIENDLY=""
-+ FIND=""
-+ MODULE=""
-+ fi
-+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
-+ echo "--user_friendly_names must be either 'y' or 'n'"
-+ exit 1
-+ fi
-+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then
-+ echo "--find_multipaths must be either 'y' or 'n'"
-+ exit 1
-+ fi
-+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
-+ SHOW_STATUS=1
-+ fi
-+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
-+ echo "--with_module must be either 'y' or 'n'"
-+ exit 1
-+ fi
-+ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then
-+ echo "--with_multipathd must be either 'y' or 'n'"
-+ exit 1
-+ fi
-+}
-+
-+umask 0077
-+
-+parse_args "$@"
-+
-+validate_args
-+
-+if [ ! -d "$MULTIPATHDIR" ]; then
-+ echo "/etc/multipath/ does not exist. failing"
-+ exit 1
-+fi
-+
-+rm $TMPFILE 2> /dev/null
-+if [ -f "$CONFIGFILE" ]; then
-+ cp $CONFIGFILE $TMPFILE
-+elif [ -f "$DEFAULT_CONFIGFILE" ]; then
-+ cp $DEFAULT_CONFIGFILE $TMPFILE
-+else
-+ touch $TMPFILE
-+fi
-+
-+if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
-+ HAVE_BLACKLIST=1
-+fi
-+
-+if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then
-+ HAVE_DEFAULTS=1
-+fi
-+
-+if [ -z "$MODULE" -o "$MODULE" = "y" ]; then
-+ if lsmod | grep -q "dm_multipath" ; then
-+ HAVE_MODULE=1
-+ else
-+ HAVE_MODULE=0
-+ fi
-+fi
-+
-+if [ "$MULTIPATHD" = "y" ]; then
-+ if service multipathd status > /dev/null ; then
-+ HAVE_MULTIPATHD=1
-+ else
-+ HAVE_MULTIPATHD=0
-+ fi
-+fi
-+
-+if [ "$HAVE_BLACKLIST" = "1" ]; then
-+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
-+ HAVE_DISABLE=1
-+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"" ; then
-+ HAVE_DISABLE=0
-+ fi
-+fi
-+
-+if [ "$HAVE_DEFAULTS" = "1" ]; then
-+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then
-+ HAVE_FIND=1
-+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then
-+ HAVE_FIND=0
-+ fi
-+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
-+ HAVE_FRIENDLY=1
-+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
-+ HAVE_FRIENDLY=0
-+ fi
-+fi
-+
-+if [ -n "$SHOW_STATUS" ]; then
-+ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
-+ echo "multipath is enabled"
-+ else
-+ echo "multipath is disabled"
-+ fi
-+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then
-+ echo "find_multipaths is disabled"
-+ else
-+ echo "find_multipaths is enabled"
-+ fi
-+ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
-+ echo "user_friendly_names is disabled"
-+ else
-+ echo "user_friendly_names is enabled"
-+ fi
-+ if [ -n "$HAVE_MODULE" ]; then
-+ if [ "$HAVE_MODULE" = 1 ]; then
-+ echo "dm_multipath module is loaded"
-+ else
-+ echo "dm_multipath module is not loaded"
-+ fi
-+ fi
-+ if [ -n "$HAVE_MULTIPATHD" ]; then
-+ service multipathd status
-+ fi
-+ exit 0
-+fi
-+
-+if [ -z "$HAVE_BLACKLIST" ]; then
-+ cat >> $TMPFILE <<- _EOF_
-+
-+blacklist {
-+}
-+_EOF_
-+fi
-+
-+if [ -z "$HAVE_DEFAULTS" ]; then
-+ cat >> $TMPFILE <<- _EOF_
-+
-+defaults {
-+}
-+_EOF_
-+fi
-+
-+if [ "$ENABLE" = 1 ]; then
-+ if [ "$HAVE_DISABLE" = 1 ]; then
-+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
-+ fi
-+elif [ "$ENABLE" = 0 ]; then
-+ if [ -z "$HAVE_DISABLE" ]; then
-+ sed -i '/^blacklist[[:space:]]*{/ a\
-+ devnode "*"
-+' $TMPFILE
-+ elif [ "$HAVE_DISABLE" = 0 ]; then
-+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
-+ fi
-+fi
-+
-+if [ "$FIND" = "n" ]; then
-+ if [ "$HAVE_FIND" = 1 ]; then
-+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE
-+ CHANGED_CONFIG=1
-+ fi
-+elif [ "$FIND" = "y" ]; then
-+ if [ -z "$HAVE_FIND" ]; then
-+ sed -i '/^defaults[[:space:]]*{/ a\
-+ find_multipaths yes
-+' $TMPFILE
-+ CHANGED_CONFIG=1
-+ elif [ "$HAVE_FIND" = 0 ]; then
-+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $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
-+ CHANGED_CONFIG=1
-+ fi
-+elif [ "$FRIENDLY" = "y" ]; then
-+ if [ -z "$HAVE_FRIENDLY" ]; then
-+ sed -i '/^defaults[[:space:]]*{/ a\
-+ user_friendly_names yes
-+' $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
-+ CHANGED_CONFIG=1
-+ fi
-+fi
-+
-+if [ -f "$CONFIGFILE" ]; then
-+ cp $CONFIGFILE $CONFIGFILE.old
-+ if [ $? != 0 ]; then
-+ echo "failed to backup old config file, $CONFIGFILE not updated"
-+ exit 1
-+ fi
-+fi
-+
-+cp $TMPFILE $CONFIGFILE
-+if [ $? != 0 ]; then
-+ echo "failed to copy new config file into place, check $CONFIGFILE is still OK"
-+ exit 1
-+fi
-+
-+rm -f $TMPFILE
-+
-+if [ "$ENABLE" = 1 ]; then
-+ if [ "$HAVE_MODULE" = 0 ]; then
-+ modprobe dm_multipath
-+ fi
-+ if [ "$HAVE_MULTIPATHD" = 0 ]; then
-+ service multipathd start
-+ fi
-+elif [ "$ENABLE" = 0 ]; then
-+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
-+ service multipathd stop
-+ fi
-+elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
-+ service multipathd reload
-+fi
-Index: multipath-tools-130222/multipath/mpathconf.8
-===================================================================
---- /dev/null
-+++ multipath-tools-130222/multipath/mpathconf.8
-@@ -0,0 +1,103 @@
-+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
-+.SH NAME
-+mpathconf - A tool for configuring device-mapper-multipath
-+.SH SYNOPSIS
-+.B mpathconf
-+.RB [\| commands \|]
-+.RB [\| options \|]
-+.SH DESCRIPTION
-+.B mpathconf
-+is a utility that creates or modifies
-+.B /etc/multipath.conf.
-+It can enable or disable multipathing and configure some common options.
-+.B mpathconf
-+can also load the
-+.B dm_multipath
-+module, start and stop the
-+.B multipathd
-+daemon, and configure the
-+.B multipathd
-+service to start automatically or not. If
-+.B mpathconf
-+is called with no commands, it will display the current configuration.
-+
-+The default options for mpathconf are
-+.B --with_module
-+The
-+.B --with_multipathd
-+option is not set by default. Enabling multipathing will load the
-+.B dm_multipath
-+module but it will not immediately start it. This is so
-+that users can manually edit their config file if necessary, before starting
-+.B multipathd.
-+
-+If
-+.B /etc/multipath.conf
-+already exists, mpathconf will edit it. If it does not exist, mpathconf will
-+use
-+.B /usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf
-+as the starting file. This file has
-+.B user_friendly_names
-+set. If this file does not exist, mpathconf will create
-+.B /etc/multipath.conf
-+from scratch. For most users, this means that
-+.B user_friendly_names
-+will be set by default, unless they use the
-+.B --user_friendly_names n
-+command.
-+.SH COMMANDS
-+.TP
-+.B --enable
-+Removes any line that blacklists all device nodes from the
-+.B /etc/multipath.conf
-+blacklist section.
-+.TP
-+.B --disable
-+Adds a line that blacklists all device nodes to the
-+.B /etc/multipath.conf
-+blacklist section. If no blacklist section exists, it will create one.
-+.TP
-+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP }
-+If set to \fBy\fP, this adds the line
-+.B user_friendly_names yes
-+to the
-+.B /etc/multipath.conf
-+defaults section. If set to \fBn\fP, this removes the line, if present. This
-+command can be used along with any other command.
-+.TP
-+.B --find_multipaths\fP { \fBy\fP | \fBn\fP }
-+If set to \fBy\fP, this adds the line
-+.B find_multipaths yes
-+to the
-+.B /etc/multipath.conf
-+defaults section. If set to \fBn\fP, this removes the line, if present. This
-+command can be used aldong with any other command.
-+.SH OPTIONS
-+.TP
-+.B --with_module\fP { \fBy\fP | \fBn\fP }
-+If set to \fBy\fP, this runs
-+.B modprobe dm_multipath
-+to install the multipath modules. This option only works with the
-+.B --enable
-+command. This option is set to \fBy\fP by default.
-+.TP
-+.B --with_multipathd { \fBy\fP | \fBn\fP }
-+If set to \fBy\fP, this runs
-+.B service multipathd start
-+to start the multipathd daemon on \fB--enable\fP,
-+.B service multipathd stop
-+to start the multipathd daemon on \fB--disable\fP, and
-+.B service multipathd reload
-+to reconfigure multipathd on \fB--user_frindly_names\fP and
-+\fB--find_multipaths\fP.
-+This option is set to \fBn\fP by default.
-+.SH FILES
-+.BR /etc/multipath.conf
-+.SH "SEE ALSO"
-+.BR multipath.conf (5),
-+.BR modprobe (8),
-+.BR multipath (8),
-+.BR multipathd (8),
-+.BR service (8),
-+.SH AUTHOR
-+Benjamin Marzinski <bmarzins@redhat.com>
+++ /dev/null
----
- libmultipath/config.c | 1 +
- libmultipath/config.h | 1 +
- libmultipath/configure.c | 11 +++++++++++
- libmultipath/defaults.h | 1 +
- libmultipath/dict.c | 34 ++++++++++++++++++++++++++++++++++
- libmultipath/wwids.c | 26 ++++++++++++++++++++++++++
- libmultipath/wwids.h | 1 +
- multipath/main.c | 2 +-
- multipathd/main.c | 6 ++++++
- 9 files changed, 82 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -547,6 +547,7 @@ load_config (char * file)
- conf->reassign_maps = DEFAULT_REASSIGN_MAPS;
- conf->checkint = DEFAULT_CHECKINT;
- conf->max_checkint = MAX_CHECKINT(conf->checkint);
-+ conf->find_multipaths = DEFAULT_FIND_MULTIPATHS;
- conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
- conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
- conf->detect_prio = DEFAULT_DETECT_PRIO;
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -508,6 +508,10 @@ coalesce_paths (struct vectors * vecs, v
-
- memset(empty_buff, 0, WWID_SIZE);
-
-+ /* ignore refwwid if it's empty */
-+ if (refwwid && !strlen(refwwid))
-+ refwwid = NULL;
-+
- if (force_reload) {
- vector_foreach_slot (pathvec, pp1, k) {
- pp1->mpp = NULL;
-@@ -537,6 +541,13 @@ coalesce_paths (struct vectors * vecs, v
- if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
- continue;
-
-+ /* If find_multipaths was selected check if the path is valid */
-+ if (conf->find_multipaths && !refwwid &&
-+ !should_multipath(pp1, pathvec)) {
-+ orphan_path(pp1);
-+ continue;
-+ }
-+
- /*
- * at this point, we know we really got a new mp
- */
-Index: multipath-tools-130222/libmultipath/defaults.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/defaults.h
-+++ multipath-tools-130222/libmultipath/defaults.h
-@@ -15,6 +15,7 @@
- #define DEFAULT_USER_FRIENDLY_NAMES 0
- #define DEFAULT_VERBOSITY 2
- #define DEFAULT_REASSIGN_MAPS 1
-+#define DEFAULT_FIND_MULTIPATHS 0
- #define DEFAULT_FAST_IO_FAIL 5
- #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
- #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -585,6 +585,27 @@ def_reservation_key_handler(vector strve
- }
-
- static int
-+def_find_multipaths_handler(vector strvec)
-+{
-+ char * buff;
-+
-+ buff = set_value(strvec);
-+
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ conf->find_multipaths = 0;
-+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "1")))
-+ conf->find_multipaths = 1;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
-+static int
- def_names_handler(vector strvec)
- {
- char * buff;
-@@ -2700,6 +2721,18 @@ snprint_def_log_checker_err (char * buff
- }
-
- static int
-+snprint_def_find_multipaths (char * buff, int len, void * data)
-+{
-+ if (conf->find_multipaths == DEFAULT_FIND_MULTIPATHS)
-+ return 0;
-+ if (!conf->find_multipaths)
-+ return snprintf(buff, len, "no");
-+
-+ return snprintf(buff, len, "yes");
-+}
-+
-+
-+static int
- snprint_def_user_friendly_names (char * buff, int len, void * data)
- {
- if (conf->user_friendly_names == USER_FRIENDLY_NAMES_ON)
-@@ -2833,6 +2866,7 @@ init_keywords(void)
- install_keyword("wwids_file", &wwids_file_handler, &snprint_def_wwids_file);
- install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
- install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
-+ install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
- install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
- install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
- __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
-Index: multipath-tools-130222/libmultipath/wwids.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.c
-+++ multipath-tools-130222/libmultipath/wwids.c
-@@ -125,6 +125,32 @@ out:
- }
-
- int
-+should_multipath(struct path *pp1, vector pathvec)
-+{
-+ int i;
-+ struct path *pp2;
-+
-+ condlog(4, "checking if %s should be multipathed", pp1->dev);
-+ vector_foreach_slot(pathvec, pp2, i) {
-+ if (pp1->dev == pp2->dev)
-+ continue;
-+ if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
-+ condlog(3, "found multiple paths with wwid %s, "
-+ "multipathing %s", pp1->wwid, pp1->dev);
-+ return 1;
-+ }
-+ }
-+ if (check_wwids_file(pp1->wwid, 0) < 0) {
-+ condlog(3, "wwid %s not in wwids file, skipping %s",
-+ pp1->wwid, pp1->dev);
-+ return 0;
-+ }
-+ condlog(3, "found wwid %s in wwids file, multipathing %s", pp1->wwid,
-+ pp1->dev);
-+ return 1;
-+}
-+
-+int
- remember_wwid(char *wwid)
- {
- int ret = check_wwids_file(wwid, 1);
-Index: multipath-tools-130222/libmultipath/wwids.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.h
-+++ multipath-tools-130222/libmultipath/wwids.h
-@@ -12,6 +12,7 @@
- "#\n" \
- "# Valid WWIDs:\n"
-
-+int should_multipath(struct path *pp, vector pathvec);
- int remember_wwid(char *wwid);
- int check_wwids_file(char *wwid, int write_wwid);
-
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -333,7 +333,7 @@ configure (void)
- /*
- * core logic entry point
- */
-- r = coalesce_paths(&vecs, NULL, NULL, conf->force_reload);
-+ r = coalesce_paths(&vecs, NULL, refwwid, conf->force_reload);
-
- out:
- if (refwwid)
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -49,6 +49,7 @@
- #include <print.h>
- #include <configure.h>
- #include <prio.h>
-+#include <wwids.h>
- #include <pgpolicies.h>
- #include <uevent.h>
-
-@@ -471,6 +472,11 @@ rescan:
- return 1;
- }
-
-+ if (conf->find_multipaths &&
-+ !should_multipath(pp, vecs->pathvec)) {
-+ orphan_path(pp);
-+ return 0;
-+ }
- condlog(4,"%s: creating new map", pp->dev);
- if ((mpp = add_map_with_path(vecs, pp, 1))) {
- mpp->action = ACT_CREATE;
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -106,6 +106,7 @@ struct config {
- unsigned int dev_loss;
- int log_checker_err;
- int allow_queueing;
-+ int find_multipaths;
- uid_t uid;
- gid_t gid;
- mode_t mode;
+++ /dev/null
----
- libmultipath/checkers.h | 3 +
- libmultipath/checkers/Makefile | 4 +
- libmultipath/checkers/tur.c | 123 +++++++++++++++++++++++++++++++++++++++--
- multipath.conf.annotated | 5 +
- 4 files changed, 128 insertions(+), 7 deletions(-)
-
-Index: multipath-tools-120613/libmultipath/checkers.h
-===================================================================
---- multipath-tools-120613.orig/libmultipath/checkers.h
-+++ multipath-tools-120613/libmultipath/checkers.h
-@@ -60,6 +60,7 @@ enum path_check_state {
-
- #define DIRECTIO "directio"
- #define TUR "tur"
-+#define HP_TUR "hp_tur"
- #define HP_SW "hp_sw"
- #define RDAC "rdac"
- #define EMC_CLARIION "emc_clariion"
-@@ -77,6 +78,7 @@ enum path_check_state {
- #define CHECKER_MSG_LEN 256
- #define CHECKER_DEV_LEN 256
- #define LIB_CHECKER_NAMELEN 256
-+#define WWID_SIZE 128
-
- struct checker {
- struct list_head node;
-@@ -88,6 +90,7 @@ struct checker {
- int disable;
- char name[CHECKER_NAME_LEN];
- char message[CHECKER_MSG_LEN]; /* comm with callers */
-+ char wwid[WWID_SIZE]; /* LUN wwid */
- void * context; /* store for persistent data */
- void ** mpcontext; /* store for persistent data shared
- multipath-wide. Use MALLOC if
-Index: multipath-tools-120613/libmultipath/checkers/Makefile
-===================================================================
---- multipath-tools-120613.orig/libmultipath/checkers/Makefile
-+++ multipath-tools-120613/libmultipath/checkers/Makefile
-@@ -8,6 +8,7 @@ LIBS= \
- libcheckcciss_tur.so \
- libcheckreadsector0.so \
- libchecktur.so \
-+ libcheckhp_tur.so \
- libcheckdirectio.so \
- libcheckemc_clariion.so \
- libcheckhp_sw.so \
-@@ -23,6 +24,9 @@ libcheckdirectio.so: libsg.o directio.o
- libcheck%.so: libsg.o %.o
- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^
-
-+hp_tur.o: tur.c
-+ $(CC) $(CFLAGS) -DCHECK_WWID -c -o $@ $<
-+
- install:
- $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir)
-
-Index: multipath-tools-120613/libmultipath/checkers/tur.c
-===================================================================
---- multipath-tools-120613.orig/libmultipath/checkers/tur.c
-+++ multipath-tools-120613/libmultipath/checkers/tur.c
-@@ -24,12 +24,101 @@
- #define TUR_CMD_LEN 6
- #define HEAVY_CHECK_COUNT 10
-
-+#ifdef CHECK_WWID
-+#define MSG_TUR_UP "HP tur checker reports path is up"
-+#define MSG_TUR_DOWN "HP tur checker reports path is down"
-+#define MSG_TUR_GHOST "HP tur checker reports path is in standby state"
-+#define MSG_TUR_RUNNING "HP tur checker still running"
-+#define MSG_TUR_TIMEOUT "HP tur checker timed out"
-+#define MSG_TUR_FAILED "HP tur checker failed to initialize"
-+#define EVPD 0x01
-+#define PAGE_83 0x83
-+#define INQUIRY_CMD 0x12
-+#define INQUIRY_CMDLEN 6
-+#define SCSI_INQ_BUFF_LEN 96
-+#else
- #define MSG_TUR_UP "tur checker reports path is up"
- #define MSG_TUR_DOWN "tur checker reports path is down"
- #define MSG_TUR_GHOST "tur checker reports path is in standby state"
- #define MSG_TUR_RUNNING "tur checker still running"
- #define MSG_TUR_TIMEOUT "tur checker timed out"
- #define MSG_TUR_FAILED "tur checker failed to initialize"
-+#endif
-+
-+#ifdef CHECK_WWID
-+static int
-+do_inq(int fd, unsigned int timeout, char * wwid)
-+{
-+ int ret = -1;
-+ unsigned char inq_cmd[INQUIRY_CMDLEN] =
-+ {INQUIRY_CMD, EVPD, PAGE_83, 0, SCSI_INQ_BUFF_LEN, 0 };
-+ unsigned char sense_buffer[32];
-+ unsigned char resp_buffer[SCSI_INQ_BUFF_LEN];
-+ char *pbuff;
-+
-+ int m,k;
-+ int retry_tur = 5;
-+ struct sg_io_hdr io_hdr;
-+
-+retry:
-+ memset(resp_buffer, 0, sizeof(resp_buffer));
-+ memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
-+
-+ io_hdr.interface_id = 'S';
-+ io_hdr.cmd_len = sizeof(inq_cmd);
-+ io_hdr.mx_sb_len = sizeof(sense_buffer);
-+ io_hdr.dxfer_direction = -3; // Data transfer from the device.
-+ io_hdr.dxfer_len = sizeof(resp_buffer);
-+ io_hdr.dxferp = (unsigned char *)resp_buffer;
-+ io_hdr.cmdp = inq_cmd;
-+ io_hdr.sbp = sense_buffer;
-+ io_hdr.timeout = timeout; // IOCTL timeout value.
-+
-+ if (ioctl(fd, SG_IO, &io_hdr) < 0) {
-+ condlog(0, "SG_IO ioctl failed: %s", strerror(errno));
-+ return ret;
-+ }
-+ if (io_hdr.info & SG_INFO_OK_MASK){
-+ int key = 0, asc, ascq;
-+
-+ if (io_hdr.host_status == DID_BUS_BUSY ||
-+ io_hdr.host_status == DID_ERROR ||
-+ io_hdr.host_status == DID_TRANSPORT_DISRUPTED) {
-+ if (--retry_tur)
-+ goto retry;
-+ }
-+ if (io_hdr.sb_len_wr > 3) {
-+ if (io_hdr.sbp[0] == 0x72 || io_hdr.sbp[0] == 0x73) {
-+ key = io_hdr.sbp[1] & 0x0f;
-+ asc = io_hdr.sbp[2];
-+ ascq = io_hdr.sbp[3];
-+ } else if (io_hdr.sb_len_wr > 13 &&
-+ ((io_hdr.sbp[0] & 0x7f) == 0x70 ||
-+ (io_hdr.sbp[0] & 0x7f) == 0x71)) {
-+ key = io_hdr.sbp[2] & 0x0f;
-+ asc = io_hdr.sbp[12];
-+ ascq = io_hdr.sbp[13];
-+ }
-+ }
-+ if (key == 0x6) {
-+ /* Unit Attention, retry */
-+ if (--retry_tur)
-+ goto retry;
-+ }
-+ return ret;
-+ }
-+
-+ pbuff = (char *) resp_buffer;
-+
-+ wwid[0] = '3';
-+ for (m = 8, k = 1; m < 11; ++m, k+=2)
-+ sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff);
-+ for (m = 11; m < 24; ++m, k+=2)
-+ sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff);
-+
-+ return (ret = 0);
-+}
-+#endif
-
- struct tur_checker_context {
- dev_t devt;
-@@ -43,6 +132,7 @@ struct tur_checker_context {
- pthread_cond_t active;
- pthread_spinlock_t hldr_lock;
- int holders;
-+ char wwid[WWID_SIZE];
- char message[CHECKER_MSG_LEN];
- };
-
-@@ -100,12 +190,15 @@ void libcheck_free (struct checker * c)
- #define TUR_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args);
-
- int
--tur_check(int fd, unsigned int timeout, char *msg)
-+tur_check (int fd, unsigned int timeout, char *msg, char *wwid)
- {
- struct sg_io_hdr io_hdr;
- unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
- unsigned char sense_buffer[32];
- int retry_tur = 5;
-+#ifdef CHECK_WWID
-+ char new_wwid[WWID_SIZE];
-+#endif
-
- retry:
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
-@@ -179,6 +272,24 @@ tur_check(int fd, unsigned int timeout,
- TUR_MSG(msg, MSG_TUR_DOWN);
- return PATH_DOWN;
- }
-+#ifdef CHECK_WWID
-+ if (!do_inq(fd, timeout, new_wwid)) {
-+
-+ if(!strcmp(wwid, "\0")) {
-+ strcpy(wwid, new_wwid);
-+ goto up;
-+ }
-+
-+ if (strcmp(wwid , new_wwid)) {
-+ condlog(0,
-+ "hp_tur: Lun collided. new_wwid %s old_wwid %s",
-+ new_wwid, wwid);
-+ TUR_MSG(msg, MSG_TUR_DOWN);
-+ return PATH_DOWN;
-+ }
-+ }
-+up:
-+#endif
- TUR_MSG(msg, MSG_TUR_UP);
- return PATH_UP;
- }
-@@ -215,7 +326,7 @@ void *tur_thread(void *ctx)
- ct->state = PATH_PENDING;
- pthread_mutex_unlock(&ct->lock);
-
-- state = tur_check(ct->fd, ct->timeout, ct->message);
-+ state = tur_check(ct->fd, ct->timeout, ct->message, ct->wwid);
-
- /* TUR checker done */
- pthread_mutex_lock(&ct->lock);
-@@ -275,7 +386,7 @@ libcheck_check (struct checker * c)
- ct->devt = sb.st_rdev;
-
- if (c->sync)
-- return tur_check(c->fd, c->timeout, c->message);
-+ return tur_check(c->fd, c->timeout, c->message, ct->wwid);
-
- /*
- * Async mode
-@@ -319,7 +430,8 @@ libcheck_check (struct checker * c)
- pthread_mutex_unlock(&ct->lock);
- condlog(3, "%d:%d: tur thread not responding, "
- "using sync mode", TUR_DEVT(ct));
-- return tur_check(c->fd, c->timeout, c->message);
-+ return tur_check(c->fd, c->timeout, c->message,
-+ ct->wwid);
- }
- /* Start new TUR checker */
- ct->state = PATH_UNCHECKED;
-@@ -337,7 +449,8 @@ libcheck_check (struct checker * c)
- ct->holders--;
- condlog(3, "%d:%d: failed to start tur thread, using"
- " sync mode", TUR_DEVT(ct));
-- return tur_check(c->fd, c->timeout, c->message);
-+ return tur_check(c->fd, c->timeout, c->message,
-+ ct->wwid);
- }
- pthread_attr_destroy(&attr);
- tur_timeout(&tsp);
-Index: multipath-tools-120613/multipath.conf.annotated
-===================================================================
---- multipath-tools-120613.orig/multipath.conf.annotated
-+++ multipath-tools-120613/multipath.conf.annotated
-@@ -96,7 +96,8 @@
- # # name : path_checker, checker
- # # scope : multipath & multipathd
- # # desc : the default method used to determine the paths' state
--# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|cciss_tur
-+# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|
-+# cciss_tur|hp_tur
- # # default : directio
- # #
- # path_checker directio
-@@ -493,7 +494,7 @@
- # # scope : multipathd & multipathd
- # # desc : path checking algorithm to use to check path state
- # # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|
--# # cciss_tur
-+# # cciss_tur|hp_tur
- # #
- # path_checker directio
- #
+++ /dev/null
----
- kpartx/dos.c | 2 --
- kpartx/kpartx.c | 9 ++++++---
- 2 files changed, 6 insertions(+), 5 deletions(-)
-
-Index: multipath-tools-130222/kpartx/dos.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/dos.c
-+++ multipath-tools-130222/kpartx/dos.c
-@@ -98,8 +98,6 @@ read_dos_pt(int fd, struct slice all, st
- break;
- }
- if (is_extended(p.sys_type)) {
-- sp[i].size = 2; /* extended partitions only get two
-- sectors mapped for LILO to install */
- n += read_extended_partition(fd, &p, i, sp+n, ns-n);
- }
- }
-Index: multipath-tools-130222/kpartx/kpartx.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.c
-+++ multipath-tools-130222/kpartx/kpartx.c
-@@ -516,6 +516,7 @@ main(int argc, char **argv){
- d = c;
- while (c) {
- for (j = 0; j < n; j++) {
-+ uint64_t start;
- int k = slices[j].container - 1;
-
- if (slices[j].size == 0)
-@@ -541,9 +542,11 @@ main(int argc, char **argv){
- }
- strip_slash(partname);
-
-- if (safe_sprintf(params, "%s %" PRIu64,
-- device,
-- slices[j].start)) {
-+ start = slices[j].start - slices[k].start;
-+ if (safe_sprintf(params, "%d:%d %" PRIu64,
-+ slices[k].major,
-+ slices[k].minor,
-+ start)) {
- fprintf(stderr, "params too small\n");
- exit(1);
- }
+++ /dev/null
----
- kpartx/bsd.c | 35 ---------------
- kpartx/dos.c | 7 +--
- kpartx/kpartx.c | 123 +++++++-------------------------------------------------
- kpartx/kpartx.h | 1
- kpartx/sun.c | 35 ---------------
- 5 files changed, 24 insertions(+), 177 deletions(-)
-
-Index: multipath-tools-130222/kpartx/bsd.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/bsd.c
-+++ multipath-tools-130222/kpartx/bsd.c
-@@ -50,10 +50,10 @@ int
- read_bsd_pt(int fd, struct slice all, struct slice *sp, int ns) {
- struct bsd_disklabel *l;
- struct bsd_partition *p;
-- unsigned int offset = all.start, end;
-+ unsigned int offset = all.start;
- int max_partitions;
- char *bp;
-- int n = 0, i, j;
-+ int n = 0;
-
- bp = getblock(fd, offset+1); /* 1 sector suffices */
- if (bp == NULL)
-@@ -79,36 +79,5 @@ read_bsd_pt(int fd, struct slice all, st
- break;
- }
- }
-- /*
-- * Convention has it that the bsd disklabel will always have
-- * the 'c' partition spanning the entire disk.
-- * So we have to check for contained slices.
-- */
-- for(i = 0; i < n; i++) {
-- if (sp[i].size == 0)
-- continue;
--
-- end = sp[i].start + sp[i].size;
-- for(j = 0; j < n; j ++) {
-- if ( i == j )
-- continue;
-- if (sp[j].size == 0)
-- continue;
--
-- if (sp[i].start < sp[j].start) {
-- if (end > sp[j].start &&
-- end < sp[j].start + sp[j].size) {
-- /* Invalid slice */
-- fprintf(stderr,
-- "bsd_disklabel: slice %d overlaps with %d\n", i , j);
-- sp[i].size = 0;
-- }
-- } else {
-- if (end <= sp[j].start + sp[j].size) {
-- sp[i].container = j + 1;
-- }
-- }
-- }
-- }
- return n;
- }
-Index: multipath-tools-130222/kpartx/dos.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/dos.c
-+++ multipath-tools-130222/kpartx/dos.c
-@@ -16,7 +16,7 @@ is_extended(int type) {
- }
-
- static int
--read_extended_partition(int fd, struct partition *ep, int en,
-+read_extended_partition(int fd, struct partition *ep,
- struct slice *sp, int ns)
- {
- struct partition p;
-@@ -53,7 +53,6 @@ read_extended_partition(int fd, struct p
- if (n < ns) {
- sp[n].start = here + le32_to_cpu(p.start_sect);
- sp[n].size = le32_to_cpu(p.nr_sects);
-- sp[n].container = en + 1;
- n++;
- } else {
- fprintf(stderr,
-@@ -98,7 +97,9 @@ read_dos_pt(int fd, struct slice all, st
- break;
- }
- if (is_extended(p.sys_type)) {
-- n += read_extended_partition(fd, &p, i, sp+n, ns-n);
-+ n += read_extended_partition(fd, &p, sp+n, ns-n);
-+ /* hide the extended partition itself */
-+ sp[i].size = 2;
- }
- }
- return n;
-Index: multipath-tools-130222/kpartx/kpartx.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.c
-+++ multipath-tools-130222/kpartx/kpartx.c
-@@ -192,7 +192,7 @@ get_hotplug_device(void)
-
- int
- main(int argc, char **argv){
-- int i, j, m, n, op, off, arg, c, d, ro=0;
-+ int i, j, m, n, op, off, arg, ro=0;
- int fd = -1;
- struct slice all;
- struct pt *ptp;
-@@ -381,49 +381,30 @@ main(int argc, char **argv){
- else
- continue;
-
-+ /*
-+ * test for overlap, as in the case of an extended partition
-+ * zero their size to avoid mapping
-+ */
-+ for (j = 0; j < n; j++) {
-+ for (m = j + 1; m < n; m++) {
-+ if (slices[m].start > slices[j].start &&
-+ slices[m].start < slices[j].start +
-+ slices[j].size)
-+ slices[j].size = 0;
-+ }
-+ }
-+
- switch(what) {
- case LIST:
-- for (j = 0, c = 0, m = 0; j < n; j++) {
-+ for (j = 0; j < n; j++) {
- if (slices[j].size == 0)
- continue;
-- if (slices[j].container > 0) {
-- c++;
-- continue;
-- }
--
-- slices[j].minor = m++;
-
- printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n",
- mapname, delim, j+1,
- slices[j].size, device,
- slices[j].start);
- }
-- /* Loop to resolve contained slices */
-- d = c;
-- while (c) {
-- for (j = 0; j < n; j++) {
-- uint64_t start;
-- int k = slices[j].container - 1;
--
-- if (slices[j].size == 0)
-- continue;
-- if (slices[j].minor > 0)
-- continue;
-- if (slices[j].container == 0)
-- continue;
-- slices[j].minor = m++;
--
-- start = slices[j].start - slices[k].start;
-- printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n",
-- mapname, delim, j+1,
-- slices[j].size,
-- slices[k].minor, start);
-- c--;
-- }
-- /* Terminate loop if nothing more to resolve */
-- if (d == c)
-- break;
-- }
-
- break;
-
-@@ -462,16 +443,10 @@ main(int argc, char **argv){
- case ADD:
- case UPDATE:
- /* ADD and UPDATE share the same code that adds new partitions. */
-- for (j = 0, c = 0; j < n; j++) {
-+ for (j = 0; j < n; j++) {
- if (slices[j].size == 0)
- continue;
-
-- /* Skip all contained slices */
-- if (slices[j].container > 0) {
-- c++;
-- continue;
-- }
--
- if (safe_sprintf(partname, "%s%s%d",
- mapname, delim, j+1)) {
- fprintf(stderr, "partname too small\n");
-@@ -512,72 +487,6 @@ main(int argc, char **argv){
- slices[j].minor, slices[j].size,
- DM_TARGET, params);
- }
-- /* Loop to resolve contained slices */
-- d = c;
-- while (c) {
-- for (j = 0; j < n; j++) {
-- uint64_t start;
-- int k = slices[j].container - 1;
--
-- if (slices[j].size == 0)
-- continue;
--
-- /* Skip all existing slices */
-- if (slices[j].minor > 0)
-- continue;
--
-- /* Skip all simple slices */
-- if (slices[j].container == 0)
-- continue;
--
-- /* Check container slice */
-- if (slices[k].size == 0)
-- fprintf(stderr, "Invalid slice %d\n",
-- k);
--
-- if (safe_sprintf(partname, "%s%s%d",
-- mapname, delim, j+1)) {
-- fprintf(stderr, "partname too small\n");
-- exit(1);
-- }
-- strip_slash(partname);
--
-- start = slices[j].start - slices[k].start;
-- if (safe_sprintf(params, "%d:%d %" PRIu64,
-- slices[k].major,
-- slices[k].minor,
-- start)) {
-- fprintf(stderr, "params too small\n");
-- exit(1);
-- }
--
-- op = (dm_map_present(partname) ?
-- DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
--
-- dm_addmap(op, partname, DM_TARGET, params,
-- slices[j].size, ro, uuid, j+1,
-- buf.st_mode & 0777,
-- buf.st_uid, buf.st_gid,
-- &cookie);
--
-- if (op == DM_DEVICE_RELOAD)
-- dm_simplecmd(DM_DEVICE_RESUME,
-- partname, 1,
-- &cookie);
--
-- dm_devn(partname, &slices[j].major,
-- &slices[j].minor);
--
-- if (verbose)
-- printf("add map %s : 0 %" PRIu64 " %s %s\n",
-- partname, slices[j].size,
-- DM_TARGET, params);
-- c--;
-- }
-- /* Terminate loop */
-- if (d == c)
-- break;
-- }
-
- if (what == ADD) {
- /* Skip code that removes devmappings for deleted partitions */
-Index: multipath-tools-130222/kpartx/kpartx.h
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.h
-+++ multipath-tools-130222/kpartx/kpartx.h
-@@ -24,7 +24,6 @@
- struct slice {
- uint64_t start;
- uint64_t size;
-- int container;
- int major;
- int minor;
- };
-Index: multipath-tools-130222/kpartx/sun.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/sun.c
-+++ multipath-tools-130222/kpartx/sun.c
-@@ -62,8 +62,8 @@ int
- read_sun_pt(int fd, struct slice all, struct slice *sp, int ns) {
- struct sun_disk_label *l;
- struct sun_raw_part *s;
-- unsigned int offset = all.start, end;
-- int i, j, n;
-+ unsigned int offset = all.start;
-+ int i, n;
- char *bp;
-
- bp = getblock(fd, offset);
-@@ -95,37 +95,6 @@ read_sun_pt(int fd, struct slice all, st
- break;
- }
- }
-- /*
-- * Convention has it that the SUN disklabel will always have
-- * the 'c' partition spanning the entire disk.
-- * So we have to check for contained slices.
-- */
-- for(i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
-- if (sp[i].size == 0)
-- continue;
--
-- end = sp[i].start + sp[i].size;
-- for(j = 0; j < SUN_DISK_MAXPARTITIONS; j ++) {
-- if ( i == j )
-- continue;
-- if (sp[j].size == 0)
-- continue;
--
-- if (sp[i].start < sp[j].start) {
-- if (end > sp[j].start &&
-- end < sp[j].start + sp[j].size) {
-- /* Invalid slice */
-- fprintf(stderr,
-- "sun_disklabel: slice %d overlaps with %d\n", i , j);
-- sp[i].size = 0;
-- }
-- } else {
-- if (end <= sp[j].start + sp[j].size) {
-- sp[i].container = j + 1;
-- }
-- }
-- }
-- }
- return n;
- }
-
+++ /dev/null
----
- multipathd/main.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -990,7 +990,8 @@ mpvec_garbage_collector (struct vectors
- return;
-
- vector_foreach_slot (vecs->mpvec, mpp, i) {
-- if (mpp && mpp->alias && !dm_map_present(mpp->alias)) {
-+ if (mpp && mpp->alias && !dm_map_present(mpp->alias) &&
-+ errno != ENOMEM) {
- condlog(2, "%s: remove dead map", mpp->alias);
- remove_map_and_stop_waiter(mpp, vecs, 1);
- i--;
+++ /dev/null
----
- multipath.conf.annotated | 53 -----------------------------------------------
- multipath.conf.synthetic | 3 --
- 2 files changed, 56 deletions(-)
-
-Index: multipath-tools-120123/multipath.conf.annotated
-===================================================================
---- multipath-tools-120123.orig/multipath.conf.annotated
-+++ multipath-tools-120123/multipath.conf.annotated
-@@ -186,32 +186,6 @@
- # user_friendly_names no
- #
- # #
--# # name : mode
--# # scope : multipath & multipathd
--# # desc : The mode to use for the multipath device nodes, in octal.
--# # values : 0000 - 0777
--# # default : determined by the process
--# mode 0644
--#
--# #
--# # name : uid
--# # scope : multipath & multipathd
--# # desc : The user id to use for the multipath device nodes. You
--# # may use either the numeric or symbolic uid
--# # values : <user_id>
--# # default : determined by the process
--# uid 0
--#
--# #
--# # name : gid
--# # scope : multipath & multipathd
--# # desc : The group id to user for the multipath device nodes. You
--# # may use either the numeric or symbolic gid
--# # values : <group_id>
--# # default : determined by the process
--# gid disk
--#
--# #
- # # name : checker_timeout
- # # scope : multipath & multipathd
- # # desc : The timeout to use for path checkers that issue scsi
-@@ -388,33 +362,6 @@
- # #
- # flush_on_last_del yes
- #
--# #
--# # name : mode
--# # scope : multipath & multipathd
--# # desc : The mode to use for the multipath device nodes, in
--# # octal.
--# # values : 0000 - 0777
--# # default : determined by the process
--# mode 0644
--#
--# #
--# # name : uid
--# # scope : multipath & multipathd
--# # desc : The user id to use for the multipath device nodes.
--# # You may use either the numeric or symbolic uid
--# # values : <user_id>
--# # default : determined by the process
--# uid 0
--#
--# #
--# # name : gid
--# # scope : multipath & multipathd
--# # desc : The group id to user for the multipath device nodes.
--# # You may use either the numeric or symbolic gid
--# # values : <group_id>
--# # default : determined by the process
--# gid 0
--#
- # }
- # multipath {
- # wwid 1DEC_____321816758474
-Index: multipath-tools-120123/multipath.conf.synthetic
-===================================================================
---- multipath-tools-120123.orig/multipath.conf.synthetic
-+++ multipath-tools-120123/multipath.conf.synthetic
-@@ -18,9 +18,6 @@
- # no_path_retry fail
- # queue_without_daemon no
- # user_friendly_names no
--# mode 644
--# uid 0
--# gid disk
- #}
- #blacklist {
- # wwid 26353900f02796769
+++ /dev/null
----
- kpartx/lopart.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/kpartx/lopart.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/lopart.c
-+++ multipath-tools-130222/kpartx/lopart.c
-@@ -205,13 +205,13 @@ find_unused_loop_device (void)
- fprintf(stderr,
- "mount: Could not find any loop device, and, according to %s,\n"
- " this kernel does not know about the loop device.\n"
-- " (If so, then recompile or `insmod loop.o'.)",
-+ " (If so, then recompile or `modprobe loop'.)",
- PROC_DEVICES);
-
- else
- fprintf(stderr,
- "mount: Could not find any loop device. Maybe this kernel does not know\n"
-- " about the loop device (then recompile or `insmod loop.o'), or\n"
-+ " about the loop device (then recompile or `modprobe loop'), or\n"
- " maybe /dev/loop# has the wrong major number?");
-
- } else
+++ /dev/null
----
- Makefile.inc | 9 +++++----
- kpartx/Makefile | 2 +-
- libmpathpersist/Makefile | 4 ++--
- libmultipath/Makefile | 1 +
- libmultipath/checkers/Makefile | 2 +-
- libmultipath/prioritizers/Makefile | 2 +-
- multipath/Makefile | 2 +-
- multipathd/Makefile | 5 +++--
- 8 files changed, 15 insertions(+), 12 deletions(-)
-
-Index: multipath-tools-130222/Makefile.inc
-===================================================================
---- multipath-tools-130222.orig/Makefile.inc
-+++ multipath-tools-130222/Makefile.inc
-@@ -23,15 +23,15 @@ endif
-
- prefix =
- exec_prefix = $(prefix)
--bindir = $(exec_prefix)/sbin
-+bindir = $(exec_prefix)/usr/sbin
- libudevdir = ${prefix}/lib/udev
- multipathdir = $(TOPDIR)/libmultipath
- mandir = $(prefix)/usr/share/man/man8
- man5dir = $(prefix)/usr/share/man/man5
- man3dir = $(prefix)/usr/share/man/man3
- rcdir = $(prefix)/etc/rc.d/init.d
--syslibdir = $(prefix)/$(LIB)
--libdir = $(prefix)/$(LIB)/multipath
-+syslibdir = $(prefix)/usr/$(LIB)
-+libdir = $(prefix)/usr/$(LIB)/multipath
- unitdir = $(prefix)/lib/systemd/system
- mpathpersistdir = $(TOPDIR)/libmpathpersist
-
-@@ -42,8 +42,9 @@ ifndef RPM_OPT_FLAGS
- RPM_OPT_FLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4
- endif
-
-+LDFLAGS += -Wl,-z,relro
- OPTFLAGS = $(RPM_OPT_FLAGS) -Wunused -Wstrict-prototypes
--CFLAGS = $(OPTFLAGS) -fPIC -DLIB_STRING=\"${LIB}\"
-+CFLAGS = $(OPTFLAGS) -DLIB_STRING=\"${LIB}\"
- SHARED_FLAGS = -shared
-
- %.o: %.c
-Index: multipath-tools-130222/multipathd/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipathd/Makefile
-+++ multipath-tools-130222/multipathd/Makefile
-@@ -5,9 +5,10 @@ include ../Makefile.inc
- #
- # basic flags setting
- #
--CFLAGS += -I$(multipathdir) -I$(mpathpersistdir)
-+CFLAGS += -fPIE -DPIE -I$(multipathdir) -I$(mpathpersistdir)
- LDFLAGS += -lpthread -ldevmapper -lreadline -ludev -ldl \
-- -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist
-+ -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \
-+ -Wl,-z,now -pie
-
- #
- # debuging stuff
-Index: multipath-tools-130222/kpartx/Makefile
-===================================================================
---- multipath-tools-130222.orig/kpartx/Makefile
-+++ multipath-tools-130222/kpartx/Makefile
-@@ -4,7 +4,7 @@
- #
- include ../Makefile.inc
-
--CFLAGS += -I. -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS += -fPIC -I. -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-
- LIBDM_API_COOKIE = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_set_cookie' /usr/include/libdevmapper.h)
-
-Index: multipath-tools-130222/libmpathpersist/Makefile
-===================================================================
---- multipath-tools-130222.orig/libmpathpersist/Makefile
-+++ multipath-tools-130222/libmpathpersist/Makefile
-@@ -10,7 +10,7 @@ DEVLIB = libmpathpersist.so
- LIBS = $(DEVLIB).$(SONAME)
-
-
--CFLAGS += -I$(multipathdir) -I$(mpathpersistdir)
-+CFLAGS += -fPIC -I$(multipathdir) -I$(mpathpersistdir)
- LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
-
- OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o
-@@ -19,7 +19,7 @@ all: $(LIBS)
-
-
- $(LIBS):
-- $(CC) -Wall -fPIC -c $(CFLAGS) *.c
-+ $(CC) -Wall -c $(CFLAGS) *.c
- $(CC) -shared $(LIBDEPS) -Wl,-soname=$@ $(CFLAGS) -o $@ $(OBJS)
- ln -s $(LIBS) $(DEVLIB)
- $(GZIP) mpath_persistent_reserve_in.3 > mpath_persistent_reserve_in.3.gz
-Index: multipath-tools-130222/libmultipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/libmultipath/Makefile
-+++ multipath-tools-130222/libmultipath/Makefile
-@@ -8,6 +8,7 @@ SONAME=0
- DEVLIB = libmultipath.so
- LIBS = $(DEVLIB).$(SONAME)
- LIBDEPS = -lpthread -ldl -ldevmapper -ludev
-+CFLAGS += -fPIC
-
- OBJS = memory.o parser.o vector.o devmapper.o \
- hwtable.o blacklist.o util.o dmparser.o config.o \
-Index: multipath-tools-130222/libmultipath/checkers/Makefile
-===================================================================
---- multipath-tools-130222.orig/libmultipath/checkers/Makefile
-+++ multipath-tools-130222/libmultipath/checkers/Makefile
-@@ -14,7 +14,7 @@ LIBS= \
- libcheckhp_sw.so \
- libcheckrdac.so
-
--CFLAGS += -I..
-+CFLAGS += -fPIC -I..
-
- all: $(LIBS)
-
-Index: multipath-tools-130222/libmultipath/prioritizers/Makefile
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/Makefile
-+++ multipath-tools-130222/libmultipath/prioritizers/Makefile
-@@ -17,7 +17,7 @@ LIBS = \
- libprioweightedpath.so \
- libprioiet.so
-
--CFLAGS += -I..
-+CFLAGS += -fPIC -I..
-
- all: $(LIBS)
-
-Index: multipath-tools-130222/multipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipath/Makefile
-+++ multipath-tools-130222/multipath/Makefile
-@@ -6,7 +6,7 @@ include ../Makefile.inc
-
- OBJS = main.o
-
--CFLAGS += -I$(multipathdir)
-+CFLAGS += -fPIC -I$(multipathdir)
- LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
-
- EXEC = multipath
+++ /dev/null
----
- kpartx/gpt.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-120821/kpartx/gpt.c
-===================================================================
---- multipath-tools-120821.orig/kpartx/gpt.c
-+++ multipath-tools-120821/kpartx/gpt.c
-@@ -637,6 +637,7 @@ read_gpt_pt (int fd, struct slice all, s
- uint32_t i;
- int n = 0;
- int last_used_index=-1;
-+ int sector_size_mul = get_sector_size(fd)/512;
-
- if (!find_valid_gpt (fd, &gpt, &ptes) || !gpt || !ptes) {
- if (gpt)
-@@ -652,9 +653,11 @@ read_gpt_pt (int fd, struct slice all, s
- sp[n].size = 0;
- n++;
- } else {
-- sp[n].start = __le64_to_cpu(ptes[i].starting_lba);
-- sp[n].size = __le64_to_cpu(ptes[i].ending_lba) -
-- __le64_to_cpu(ptes[i].starting_lba) + 1;
-+ sp[n].start = sector_size_mul *
-+ __le64_to_cpu(ptes[i].starting_lba);
-+ sp[n].size = sector_size_mul *
-+ (__le64_to_cpu(ptes[i].ending_lba) -
-+ __le64_to_cpu(ptes[i].starting_lba) + 1);
- last_used_index=n;
- n++;
- }
+++ /dev/null
----
- libmultipath/print.c | 31 +++++++++++++++++++++++++++----
- 1 file changed, 27 insertions(+), 4 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/print.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/print.c
-+++ multipath-tools-130222/libmultipath/print.c
-@@ -8,6 +8,8 @@
- #include <sys/stat.h>
- #include <dirent.h>
- #include <unistd.h>
-+#include <string.h>
-+#include <errno.h>
-
- #include "checkers.h"
- #include "vector.h"
-@@ -24,6 +26,7 @@
- #include "switchgroup.h"
- #include "devmapper.h"
- #include "uevent.h"
-+#include "debug.h"
-
- #define MAX(x,y) (x > y) ? x : y
- #define TAIL (line + len - 1 - c)
-@@ -754,12 +757,32 @@ snprint_pathgroup (char * line, int len,
- extern void
- print_multipath_topology (struct multipath * mpp, int verbosity)
- {
-- char buff[MAX_LINE_LEN * MAX_LINES] = {};
-+ int resize;
-+ char *buff = NULL;
-+ char *old = NULL;
-+ int len, maxlen = MAX_LINE_LEN * MAX_LINES;
-
-- memset(&buff[0], 0, MAX_LINE_LEN * MAX_LINES);
-- snprint_multipath_topology(&buff[0], MAX_LINE_LEN * MAX_LINES,
-- mpp, verbosity);
-+ buff = MALLOC(maxlen);
-+ do {
-+ if (!buff) {
-+ if (old)
-+ FREE(old);
-+ condlog(0, "couldn't allocate memory for list: %s\n",
-+ strerror(errno));
-+ return;
-+ }
-+
-+ len = snprint_multipath_topology(buff, maxlen, mpp, verbosity);
-+ resize = (len == maxlen - 1);
-+
-+ if (resize) {
-+ maxlen *= 2;
-+ old = buff;
-+ buff = REALLOC(buff, maxlen);
-+ }
-+ } while (resize);
- printf("%s", buff);
-+ FREE(buff);
- }
-
- extern int
+++ /dev/null
----
- libmultipath/discovery.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -898,7 +898,8 @@ get_state (struct path * pp, int daemon)
- c->timeout = DEF_TIMEOUT;
- state = checker_check(c);
- condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
-- if (state != PATH_UP && strlen(checker_message(c)))
-+ if (state != PATH_UP && state != PATH_GHOST &&
-+ strlen(checker_message(c)))
- condlog(3, "%s: checker msg is \"%s\"",
- pp->dev, checker_message(c));
- return state;
+++ /dev/null
----
- libmultipath/config.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -437,6 +437,8 @@ restart:
- merge_hwe(hwe2, hwe1);
- if (hwe_strmatch(hwe2, hwe1) == 0) {
- vector_del_slot(hw, i);
-+ free_hwe(hwe1);
-+ n -= 1;
- /*
- * Play safe here; we have modified
- * the original vector so the outer
+++ /dev/null
----
- libmpathpersist/mpath_updatepr.c | 3 ++-
- libmultipath/uxsock.c | 4 ++--
- 2 files changed, 4 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/libmpathpersist/mpath_updatepr.c
-===================================================================
---- multipath-tools-130222.orig/libmpathpersist/mpath_updatepr.c
-+++ multipath-tools-130222/libmpathpersist/mpath_updatepr.c
-@@ -14,6 +14,7 @@
- #include <debug.h>
- #include "memory.h"
- #include "../libmultipath/uxsock.h"
-+#include "../libmultipath/defaults.h"
-
- unsigned long mem_allocated; /* Total memory used in Bytes */
-
-@@ -25,7 +26,7 @@ int update_prflag(char * arg1, char * ar
- size_t len;
- int ret = 0;
-
-- fd = ux_socket_connect("/var/run/multipathd.sock");
-+ fd = ux_socket_connect(DEFAULT_SOCKET);
- if (fd == -1) {
- condlog (0, "ux socket connect error");
- return 1 ;
-Index: multipath-tools-130222/libmultipath/uxsock.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/uxsock.c
-+++ multipath-tools-130222/libmultipath/uxsock.c
-@@ -31,7 +31,7 @@ int ux_socket_connect(const char *name)
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- addr.sun_path[0] = '\0';
-- len = strlen(name) + 1;
-+ len = strlen(name) + 1 + sizeof(sa_family_t);
- strncpy(&addr.sun_path[1], name, len);
-
- fd = socket(AF_LOCAL, SOCK_STREAM, 0);
-@@ -62,7 +62,7 @@ int ux_socket_listen(const char *name)
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- addr.sun_path[0] = '\0';
-- len = strlen(name) + 1;
-+ len = strlen(name) + 1 + sizeof(sa_family_t);
- strncpy(&addr.sun_path[1], name, len);
-
- if (bind(fd, (struct sockaddr *)&addr, len) == -1) {
+++ /dev/null
----
- libmultipath/uevent.c | 12 ++++--------
- 1 file changed, 4 insertions(+), 8 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/uevent.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/uevent.c
-+++ multipath-tools-130222/libmultipath/uevent.c
-@@ -53,8 +53,10 @@ typedef int (uev_trigger)(struct uevent
-
- pthread_t uevq_thr;
- LIST_HEAD(uevq);
--pthread_mutex_t uevq_lock, *uevq_lockp = &uevq_lock;
--pthread_cond_t uev_cond, *uev_condp = &uev_cond;
-+pthread_mutex_t uevq_lock = PTHREAD_MUTEX_INITIALIZER;
-+pthread_mutex_t *uevq_lockp = &uevq_lock;
-+pthread_cond_t uev_cond = PTHREAD_COND_INITIALIZER;
-+pthread_cond_t *uev_condp = &uev_cond;
- uev_trigger *my_uev_trigger;
- void * my_trigger_data;
- int servicing_uev;
-@@ -409,10 +411,6 @@ int uevent_listen(void)
- * thereby not getting to empty the socket's receive buffer queue
- * often enough.
- */
-- INIT_LIST_HEAD(&uevq);
--
-- pthread_mutex_init(uevq_lockp, NULL);
-- pthread_cond_init(uev_condp, NULL);
- pthread_cleanup_push(uevq_stop, NULL);
-
- monitor = udev_monitor_new_from_netlink(conf->udev, "udev");
-@@ -525,8 +523,6 @@ out:
- if (need_failback)
- err = failback_listen();
- pthread_cleanup_pop(1);
-- pthread_mutex_destroy(uevq_lockp);
-- pthread_cond_destroy(uev_condp);
- return err;
- }
-
+++ /dev/null
----
- multipath/multipath.rules | 2 ++
- multipathd/multipathd.service | 1 +
- 2 files changed, 3 insertions(+)
-
-Index: multipath-tools-130222/multipath/multipath.rules
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.rules
-+++ multipath-tools-130222/multipath/multipath.rules
-@@ -2,6 +2,8 @@
- # so name them after their devmap name
- SUBSYSTEM!="block", GOTO="end_mpath"
-
-+IMPORT{cmdline}="nompath"
-+ENV{nompath}=="?*", GOTO="end_mpath"
- ENV{MPATH_SBIN_PATH}="/sbin"
- TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
-
-Index: multipath-tools-130222/multipathd/multipathd.service
-===================================================================
---- multipath-tools-130222.orig/multipathd/multipathd.service
-+++ multipath-tools-130222/multipathd/multipathd.service
-@@ -3,6 +3,7 @@ Description=Device-Mapper Multipath Devi
- Before=iscsi.service iscsid.service lvm2-activation-early.service
- After=syslog.target
- ConditionPathExists=/etc/multipath.conf
-+ConditionKernelCommandLine=!nompath
- DefaultDependencies=no
- Conflicts=shutdown.target
-
+++ /dev/null
----
- multipathd/main.c | 1 +
- 1 file changed, 1 insertion(+)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -1363,6 +1363,7 @@ configure (struct vectors * vecs, int st
-
- sync_maps_state(mpvec);
- vector_foreach_slot(mpvec, mpp, i){
-+ remember_wwid(mpp->wwid);
- update_map_pr(mpp);
- }
-
+++ /dev/null
----
- libmultipath/discovery.c | 3 +
- libmultipath/wwids.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
- libmultipath/wwids.h | 1
- multipath/main.c | 26 ++++++++++++--
- multipath/multipath.8 | 5 ++
- 5 files changed, 115 insertions(+), 6 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -53,7 +53,8 @@ store_pathinfo (vector pathvec, vector h
- goto out;
- }
- pp->udev = udev_device_ref(udevice);
-- err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
-+ err = pathinfo(pp, hwtable,
-+ (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST));
- if (err)
- goto out;
-
-Index: multipath-tools-130222/libmultipath/wwids.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.c
-+++ multipath-tools-130222/libmultipath/wwids.c
-@@ -82,6 +82,92 @@ write_out_wwid(int fd, char *wwid) {
- }
-
- int
-+do_remove_wwid(int fd, char *str) {
-+ char buf[4097];
-+ char *ptr;
-+ off_t start = 0;
-+ int bytes;
-+
-+ while (1) {
-+ if (lseek(fd, start, SEEK_SET) < 0) {
-+ condlog(0, "wwid file read lseek failed : %s",
-+ strerror(errno));
-+ return -1;
-+ }
-+ bytes = read(fd, buf, 4096);
-+ if (bytes < 0) {
-+ if (errno == EINTR || errno == EAGAIN)
-+ continue;
-+ condlog(0, "failed to read from wwids file : %s",
-+ strerror(errno));
-+ return -1;
-+ }
-+ if (!bytes) /* didn't find wwid to remove */
-+ return 1;
-+ buf[bytes] = '\0';
-+ ptr = strstr(buf, str);
-+ if (ptr != NULL) {
-+ condlog(3, "found '%s'", str);
-+ if (lseek(fd, start + (ptr - buf), SEEK_SET) < 0) {
-+ condlog(0, "write lseek failed : %s",
-+ strerror(errno));
-+ return -1;
-+ }
-+ while (1) {
-+ if (write(fd, "#", 1) < 0) {
-+ if (errno == EINTR || errno == EAGAIN)
-+ continue;
-+ condlog(0, "failed to write to wwids file : %s", strerror(errno));
-+ return -1;
-+ }
-+ return 0;
-+ }
-+ }
-+ ptr = strrchr(buf, '\n');
-+ if (ptr == NULL) { /* shouldn't happen, assume it is EOF */
-+ condlog(4, "couldn't find newline, assuming end of file");
-+ return 1;
-+ }
-+ start = start + (ptr - buf) + 1;
-+ }
-+}
-+
-+
-+int
-+remove_wwid(char *wwid) {
-+ int fd, len, can_write;
-+ char *str;
-+ int ret = -1;
-+
-+ len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */
-+ str = malloc(len);
-+ if (str == NULL) {
-+ condlog(0, "can't allocate memory to remove wwid : %s",
-+ strerror(errno));
-+ return -1;
-+ }
-+ if (snprintf(str, len, "/%s/\n", wwid) >= len) {
-+ condlog(0, "string overflow trying to remove wwid");
-+ goto out;
-+ }
-+ condlog(3, "removing line '%s' from wwids file", str);
-+ fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
-+ if (fd < 0)
-+ goto out;
-+ if (!can_write) {
-+ condlog(0, "cannot remove wwid. wwids file is read-only");
-+ goto out_file;
-+ }
-+ ret = do_remove_wwid(fd, str);
-+
-+out_file:
-+ close(fd);
-+out:
-+ free(str);
-+ return ret;
-+}
-+
-+int
- check_wwids_file(char *wwid, int write_wwid)
- {
- int fd, can_write, found, ret;
-Index: multipath-tools-130222/libmultipath/wwids.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.h
-+++ multipath-tools-130222/libmultipath/wwids.h
-@@ -15,5 +15,6 @@
- int should_multipath(struct path *pp, vector pathvec);
- int remember_wwid(char *wwid);
- int check_wwids_file(char *wwid, int write_wwid);
-+int remove_wwid(char *wwid);
-
- #endif /* _WWIDS_H */
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -83,7 +83,7 @@ usage (char * progname)
- {
- fprintf (stderr, VERSION_STRING);
- fprintf (stderr, "Usage:\n");
-- fprintf (stderr, " %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
-+ fprintf (stderr, " %s [-c|-w] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
- fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
- fprintf (stderr, " %s -F [-v lvl]\n", progname);
- fprintf (stderr, " %s -t\n", progname);
-@@ -104,6 +104,7 @@ usage (char * progname)
- " -B treat the bindings file as read only\n" \
- " -p policy failover|multibus|group_by_serial|group_by_prio\n" \
- " -b fil bindings file location\n" \
-+ " -w remove a device from the wwids file\n" \
- " -p pol force all maps to specified path grouping policy :\n" \
- " . failover one path per priority group\n" \
- " . multibus all paths in one priority group\n" \
-@@ -212,7 +213,6 @@ get_dm_mpvec (vector curmp, vector pathv
-
- if (!conf->dry_run)
- reinstate_paths(mpp);
-- remember_wwid(mpp->wwid);
- }
- return 0;
- }
-@@ -262,7 +262,7 @@ configure (void)
- /*
- * if we have a blacklisted device parameter, exit early
- */
-- if (dev && conf->dev_type == DEV_DEVNODE &&
-+ if (dev && conf->dev_type == DEV_DEVNODE && conf->dry_run != 3 &&
- (filter_devnode(conf->blist_devnode,
- conf->elist_devnode, dev) > 0)) {
- if (conf->dry_run == 2)
-@@ -284,6 +284,17 @@ configure (void)
- condlog(3, "scope is nul");
- goto out;
- }
-+ if (conf->dry_run == 3) {
-+ r = remove_wwid(refwwid);
-+ if (r == 0)
-+ printf("wwid '%s' removed\n", refwwid);
-+ else if (r == 1) {
-+ printf("wwid '%s' not in wwids file\n",
-+ refwwid);
-+ r = 0;
-+ }
-+ goto out;
-+ }
- condlog(3, "scope limited to %s", refwwid);
- if (conf->dry_run == 2) {
- if (check_wwids_file(refwwid, 0) == 0){
-@@ -439,7 +450,7 @@ main (int argc, char *argv[])
- if (dm_prereq())
- exit(1);
-
-- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtqw")) != EOF ) {
- switch(arg) {
- case 1: printf("optarg : %s\n",optarg);
- break;
-@@ -504,6 +515,9 @@ main (int argc, char *argv[])
- case 'h':
- usage(argv[0]);
- exit(0);
-+ case 'w':
-+ conf->dry_run = 3;
-+ break;
- case ':':
- fprintf(stderr, "Missing option argument\n");
- usage(argv[0]);
-@@ -555,6 +569,10 @@ main (int argc, char *argv[])
- condlog(0, "the -c option requires a path to check");
- goto out;
- }
-+ if (conf->dry_run == 3 && !conf->dev) {
-+ condlog(0, "the -w option requires a device");
-+ goto out;
-+ }
- if (conf->remove == FLUSH_ONE) {
- if (conf->dev_type == DEV_DEVMAP) {
- r = dm_suspend_and_flush_map(conf->dev);
-Index: multipath-tools-130222/multipath/multipath.8
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.8
-+++ multipath-tools-130222/multipath/multipath.8
-@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
- .RB [\| \-b\ \c
- .IR bindings_file \|]
- .RB [\| \-d \|]
--.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r \|]
-+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w \|]
- .RB [\| \-p\ \c
- .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
- .RB [\| device \|]
-@@ -68,6 +68,9 @@ check if a block device should be a path
- .B \-q
- allow device tables with queue_if_no_path when multipathd is not running
- .TP
-+.B \-w
-+remove the wwid for the specified device from the wwids file
-+.TP
- .BI \-p " policy"
- force new maps to use the specified policy:
- .RS 1.2i
+++ /dev/null
----
- libmultipath/wwids.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
- libmultipath/wwids.h | 1 +
- multipath/main.c | 29 +++++++++++++++++++++++++++--
- multipath/multipath.8 | 5 ++++-
- 4 files changed, 76 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/wwids.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.c
-+++ multipath-tools-130222/libmultipath/wwids.c
-@@ -82,6 +82,50 @@ write_out_wwid(int fd, char *wwid) {
- }
-
- int
-+replace_wwids(vector mp)
-+{
-+ int i, fd, can_write;
-+ struct multipath * mpp;
-+ size_t len;
-+ int ret = -1;
-+
-+ fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
-+ if (fd < 0)
-+ goto out;
-+ if (!can_write) {
-+ condlog(0, "cannot replace wwids. wwids file is read-only");
-+ goto out_file;
-+ }
-+ if (ftruncate(fd, 0) < 0) {
-+ condlog(0, "cannot truncate wwids file : %s", strerror(errno));
-+ goto out_file;
-+ }
-+ len = strlen(WWIDS_FILE_HEADER);
-+ if (write_all(fd, WWIDS_FILE_HEADER, len) != len) {
-+ condlog(0, "Can't write wwid file header : %s",
-+ strerror(errno));
-+ /* cleanup partially written header */
-+ if (ftruncate(fd, 0) < 0)
-+ condlog(0, "Cannot truncate header : %s",
-+ strerror(errno));
-+ goto out_file;
-+ }
-+ if (!mp || !mp->allocated) {
-+ ret = 0;
-+ goto out_file;
-+ }
-+ vector_foreach_slot(mp, mpp, i) {
-+ if (write_out_wwid(fd, mpp->wwid) < 0)
-+ goto out_file;
-+ }
-+ ret = 0;
-+out_file:
-+ close(fd);
-+out:
-+ return ret;
-+}
-+
-+int
- do_remove_wwid(int fd, char *str) {
- char buf[4097];
- char *ptr;
-Index: multipath-tools-130222/libmultipath/wwids.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.h
-+++ multipath-tools-130222/libmultipath/wwids.h
-@@ -16,5 +16,6 @@ int should_multipath(struct path *pp, ve
- int remember_wwid(char *wwid);
- int check_wwids_file(char *wwid, int write_wwid);
- int remove_wwid(char *wwid);
-+int replace_wwids(vector mp);
-
- #endif /* _WWIDS_H */
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -83,7 +83,7 @@ usage (char * progname)
- {
- fprintf (stderr, VERSION_STRING);
- fprintf (stderr, "Usage:\n");
-- fprintf (stderr, " %s [-c|-w] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
-+ fprintf (stderr, " %s [-c|-w|-W] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
- fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
- fprintf (stderr, " %s -F [-v lvl]\n", progname);
- fprintf (stderr, " %s -t\n", progname);
-@@ -105,6 +105,7 @@ usage (char * progname)
- " -p policy failover|multibus|group_by_serial|group_by_prio\n" \
- " -b fil bindings file location\n" \
- " -w remove a device from the wwids file\n" \
-+ " -W reset the wwids file include only the current devices\n" \
- " -p pol force all maps to specified path grouping policy :\n" \
- " . failover one path per priority group\n" \
- " . multibus all paths in one priority group\n" \
-@@ -450,7 +451,7 @@ main (int argc, char *argv[])
- if (dm_prereq())
- exit(1);
-
-- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtqw")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtqwW")) != EOF ) {
- switch(arg) {
- case 1: printf("optarg : %s\n",optarg);
- break;
-@@ -518,6 +519,9 @@ main (int argc, char *argv[])
- case 'w':
- conf->dry_run = 3;
- break;
-+ case 'W':
-+ conf->dry_run = 4;
-+ break;
- case ':':
- fprintf(stderr, "Missing option argument\n");
- usage(argv[0]);
-@@ -573,6 +577,27 @@ main (int argc, char *argv[])
- condlog(0, "the -w option requires a device");
- goto out;
- }
-+ if (conf->dry_run == 4) {
-+ struct multipath * mpp;
-+ int i;
-+ vector curmp;
-+
-+ curmp = vector_alloc();
-+ if (!curmp) {
-+ condlog(0, "can't allocate memory for mp list");
-+ goto out;
-+ }
-+ if (dm_get_maps(curmp) == 0)
-+ r = replace_wwids(curmp);
-+ if (r == 0)
-+ printf("successfully reset wwids\n");
-+ vector_foreach_slot_backwards(curmp, mpp, i) {
-+ vector_del_slot(curmp, i);
-+ free_multipath(mpp, KEEP_PATHS);
-+ }
-+ vector_free(curmp);
-+ goto out;
-+ }
- if (conf->remove == FLUSH_ONE) {
- if (conf->dev_type == DEV_DEVMAP) {
- r = dm_suspend_and_flush_map(conf->dev);
-Index: multipath-tools-130222/multipath/multipath.8
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.8
-+++ multipath-tools-130222/multipath/multipath.8
-@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
- .RB [\| \-b\ \c
- .IR bindings_file \|]
- .RB [\| \-d \|]
--.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w \|]
-+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w | \-W \|]
- .RB [\| \-p\ \c
- .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
- .RB [\| device \|]
-@@ -71,6 +71,9 @@ allow device tables with queue_if_no_pat
- .B \-w
- remove the wwid for the specified device from the wwids file
- .TP
-+.B \-W
-+reset the wwids file to only include the current multipath devices
-+.TP
- .BI \-p " policy"
- force new maps to use the specified policy:
- .RS 1.2i
+++ /dev/null
----
- multipathd/main.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -537,7 +537,8 @@ rescan:
- goto fail_map;
-
- if (retries >= 0) {
-- condlog(2, "%s path added to devmap %s", pp->dev, mpp->alias);
-+ condlog(2, "%s [%s]: path added to devmap %s",
-+ pp->dev, pp->dev_t, mpp->alias);
- return 0;
- }
- else
-@@ -642,8 +643,8 @@ ev_remove_path (struct path *pp, struct
- }
- sync_map_state(mpp);
-
-- condlog(2, "%s: path removed from map %s",
-- pp->dev, mpp->alias);
-+ condlog(2, "%s [%s]: path removed from map %s",
-+ pp->dev, pp->dev_t, mpp->alias);
- }
- }
-
+++ /dev/null
----
- multipathd/main.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -1226,11 +1226,10 @@ check_path (struct vectors * vecs, struc
- pp->checkint = 2 * pp->checkint;
- else
- pp->checkint = conf->max_checkint;
--
-- pp->tick = pp->checkint;
-- condlog(4, "%s: delay next check %is",
-- pp->dev_t, pp->tick);
- }
-+ pp->tick = pp->checkint;
-+ condlog(4, "%s: delay next check %is",
-+ pp->dev_t, pp->tick);
- }
- }
- else if (newstate == PATH_DOWN) {
+++ /dev/null
----
- libmultipath/structs_vec.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/structs_vec.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs_vec.c
-+++ multipath-tools-130222/libmultipath/structs_vec.c
-@@ -106,7 +106,7 @@ orphan_paths (vector pathvec, struct mul
- static void
- set_multipath_wwid (struct multipath * mpp)
- {
-- if (mpp->wwid)
-+ if (strlen(mpp->wwid))
- return;
-
- dm_get_uuid(mpp->alias, mpp->wwid);
+++ /dev/null
----
- libmultipath/discovery.c | 2 +-
- multipathd/main.c | 19 ++++++++++++++++++-
- 2 files changed, 19 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -1034,7 +1034,7 @@ pathinfo (struct path *pp, vector hwtabl
- }
- }
-
-- if (path_state == PATH_UP && (mask & DI_WWID) && !strlen(pp->wwid))
-+ if ((mask & DI_WWID) && !strlen(pp->wwid))
- get_uid(pp);
- if (mask & DI_BLACKLIST && mask & DI_WWID) {
- if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -376,7 +376,7 @@ static int
- uev_add_path (struct uevent *uev, struct vectors * vecs)
- {
- struct path *pp;
-- int ret;
-+ int ret, i;
-
- condlog(2, "%s: add path (uevent)", uev->kernel);
- if (strstr(uev->kernel, "..") != NULL) {
-@@ -393,6 +393,23 @@ uev_add_path (struct uevent *uev, struct
- uev->kernel);
- if (pp->mpp)
- return 0;
-+ if (!strlen(pp->wwid)) {
-+ udev_device_unref(pp->udev);
-+ pp->udev = udev_device_ref(uev->udev);
-+ ret = pathinfo(pp, conf->hwtable,
-+ DI_ALL | DI_BLACKLIST);
-+ if (ret == 2) {
-+ i = find_slot(vecs->pathvec, (void *)pp);
-+ if (i != -1)
-+ vector_del_slot(vecs->pathvec, i);
-+ free_path(pp);
-+ return 0;
-+ } else if (ret == 1) {
-+ condlog(0, "%s: failed to reinitialize path",
-+ uev->kernel);
-+ return 1;
-+ }
-+ }
- } else {
- /*
- * get path vital state
+++ /dev/null
----
- libmultipath/prio.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/prio.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prio.c
-+++ multipath-tools-130222/libmultipath/prio.c
-@@ -162,7 +162,10 @@ void prio_put (struct prio * dst)
- if (!dst)
- return;
-
-- src = prio_lookup(dst->name);
-+ if (!strlen(dst->name))
-+ src = NULL;
-+ else
-+ src = prio_lookup(dst->name);
- memset(dst, 0x0, sizeof(struct prio));
- free_prio(src);
- }
+++ /dev/null
----
- libmultipath/dict.c | 10 ++++------
- libmultipath/structs.h | 2 +-
- multipathd/cli.c | 3 +++
- multipathd/cli.h | 2 ++
- multipathd/cli_handlers.c | 18 ++++++++++++++++++
- multipathd/cli_handlers.h | 2 ++
- multipathd/main.c | 2 ++
- multipathd/multipathd.init.redhat | 14 ++++++++++----
- 8 files changed, 42 insertions(+), 11 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -438,14 +438,11 @@ def_queue_without_daemon(vector strvec)
- if (!buff)
- return 1;
-
-- if (!strncmp(buff, "off", 3) || !strncmp(buff, "no", 2) ||
-- !strncmp(buff, "0", 1))
-- conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
-- else if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
-+ if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
- !strncmp(buff, "1", 1))
- conf->queue_without_daemon = QUE_NO_DAEMON_ON;
- else
-- conf->queue_without_daemon = QUE_NO_DAEMON_UNDEF;
-+ conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
-
- free(buff);
- return 0;
-@@ -2670,8 +2667,9 @@ snprint_def_queue_without_daemon (char *
- case QUE_NO_DAEMON_OFF:
- return snprintf(buff, len, "\"no\"");
- case QUE_NO_DAEMON_ON:
-- case QUE_NO_DAEMON_UNDEF:
- return snprintf(buff, len, "\"yes\"");
-+ case QUE_NO_DAEMON_FORCE:
-+ return snprintf(buff, len, "\"forced\"");
- }
- return 0;
- }
-Index: multipath-tools-130222/libmultipath/structs.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs.h
-+++ multipath-tools-130222/libmultipath/structs.h
-@@ -67,9 +67,9 @@ enum pgstates {
- };
-
- enum queue_without_daemon_states {
-- QUE_NO_DAEMON_UNDEF,
- QUE_NO_DAEMON_OFF,
- QUE_NO_DAEMON_ON,
-+ QUE_NO_DAEMON_FORCE,
- };
-
- enum pgtimeouts {
-Index: multipath-tools-130222/multipathd/cli.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli.c
-+++ multipath-tools-130222/multipathd/cli.c
-@@ -162,6 +162,7 @@ load_keys (void)
- r += add_key(keys, "resize", RESIZE, 0);
- r += add_key(keys, "reset", RESET, 0);
- r += add_key(keys, "reload", RELOAD, 0);
-+ r += add_key(keys, "forcequeueing", FORCEQ, 0);
- r += add_key(keys, "disablequeueing", DISABLEQ, 0);
- r += add_key(keys, "restorequeueing", RESTOREQ, 0);
- r += add_key(keys, "paths", PATHS, 0);
-@@ -459,6 +460,8 @@ cli_init (void) {
- add_handler(GETPRSTATUS+MAP, NULL);
- add_handler(SETPRSTATUS+MAP, NULL);
- add_handler(UNSETPRSTATUS+MAP, NULL);
-+ add_handler(FORCEQ+DAEMON, NULL);
-+ add_handler(RESTOREQ+DAEMON, NULL);
-
- return 0;
- }
-Index: multipath-tools-130222/multipathd/cli.h
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli.h
-+++ multipath-tools-130222/multipathd/cli.h
-@@ -10,6 +10,7 @@ enum {
- __RESIZE,
- __RESET,
- __RELOAD,
-+ __FORCEQ,
- __DISABLEQ,
- __RESTOREQ,
- __PATHS,
-@@ -45,6 +46,7 @@ enum {
- #define RESIZE (1 << __RESIZE)
- #define RESET (1 << __RESET)
- #define RELOAD (1 << __RELOAD)
-+#define FORCEQ (1 << __FORCEQ)
- #define DISABLEQ (1 << __DISABLEQ)
- #define RESTOREQ (1 << __RESTOREQ)
- #define PATHS (1 << __PATHS)
-Index: multipath-tools-130222/multipathd/cli_handlers.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli_handlers.c
-+++ multipath-tools-130222/multipathd/cli_handlers.c
-@@ -628,6 +628,24 @@ cli_resize(void *v, char **reply, int *l
- }
-
- int
-+cli_force_no_daemon_q(void * v, char ** reply, int * len, void * data)
-+{
-+ condlog(2, "force queue_without_daemon (operator)");
-+ if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF)
-+ conf->queue_without_daemon = QUE_NO_DAEMON_FORCE;
-+ return 0;
-+}
-+
-+int
-+cli_restore_no_daemon_q(void * v, char ** reply, int * len, void * data)
-+{
-+ condlog(2, "restore queue_without_daemon (operator)");
-+ if (conf->queue_without_daemon == QUE_NO_DAEMON_FORCE)
-+ conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
-+ return 0;
-+}
-+
-+int
- cli_restore_queueing(void *v, char **reply, int *len, void *data)
- {
- struct vectors * vecs = (struct vectors *)data;
-Index: multipath-tools-130222/multipathd/cli_handlers.h
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli_handlers.h
-+++ multipath-tools-130222/multipathd/cli_handlers.h
-@@ -28,6 +28,8 @@ int cli_suspend(void * v, char ** reply,
- int cli_resume(void * v, char ** reply, int * len, void * data);
- int cli_reinstate(void * v, char ** reply, int * len, void * data);
- int cli_fail(void * v, char ** reply, int * len, void * data);
-+int cli_force_no_daemon_q(void * v, char ** reply, int * len, void * data);
-+int cli_restore_no_daemon_q(void * v, char ** reply, int * len, void * data);
- int cli_quit(void * v, char ** reply, int * len, void * data);
- int cli_shutdown(void * v, char ** reply, int * len, void * data);
- int cli_reassign (void * v, char ** reply, int * len, void * data);
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -904,6 +904,8 @@ uxlsnrloop (void * ap)
- set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus);
- set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus);
- set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);
-+ set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q);
-+ set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q);
-
- umask(077);
- uxsock_listen(&uxsock_trigger, ap);
-Index: multipath-tools-130222/multipathd/multipathd.init.redhat
-===================================================================
---- multipath-tools-130222.orig/multipathd/multipathd.init.redhat
-+++ multipath-tools-130222/multipathd/multipathd.init.redhat
-@@ -81,23 +81,28 @@ force_stop() {
- echo
- }
-
--stop() {
-+check_root() {
- root_dev=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $1; }}' /etc/mtab)
- dm_num=`dmsetup info -c --noheadings -o minor $root_dev 2> /dev/null`
- if [ $? -eq 0 ]; then
- root_dm_device="dm-$dm_num"
- [ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
- fi
-+}
-
-- force_stop
-+force_queue_without_daemon() {
-+ $DAEMON forcequeueing daemon
- }
-
- restart() {
-- stop
-+ force_queue_without_daemon
-+ check_root
-+ force_stop
- start
- }
-
- force_restart() {
-+ force_queue_without_daemon
- force_stop
- start
- }
-@@ -115,7 +120,8 @@ start)
- start
- ;;
- stop)
-- stop
-+ check_root
-+ force_stop
- ;;
- force-stop)
- force_stop
+++ /dev/null
----
- kpartx/kpartx.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/kpartx/kpartx.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.c
-+++ multipath-tools-130222/kpartx/kpartx.c
-@@ -348,7 +348,7 @@ main(int argc, char **argv){
- if (delim == NULL) {
- delim = malloc(DELIM_SIZE);
- memset(delim, 0, DELIM_SIZE);
-- set_delimiter(device, delim);
-+ set_delimiter(mapname, delim);
- }
-
- fd = open(device, O_RDONLY);
+++ /dev/null
----
- multipath/mpathconf | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/multipath/mpathconf
-===================================================================
---- multipath-tools-130222.orig/multipath/mpathconf
-+++ multipath-tools-130222/multipath/mpathconf
-@@ -31,8 +31,8 @@ function usage
- echo "Commands:"
- echo "Enable: --enable "
- echo "Disable: --disable"
-- echo "Set user_friendly_names (Default n): --user_friendly_names <y|n>"
-- echo "Set find_multipaths (Default n): --find_multipaths <y|n>"
-+ echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>"
-+ echo "Set find_multipaths (Default y): --find_multipaths <y|n>"
- echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
- echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
- echo ""
+++ /dev/null
-This patch provides hwtable updates for NETAPP/LSI/ENGENIO E-Series arrays,
-utilizing new features to detect TPGS support, automatically.
-
-Signed-off-by: Sean Stewart <Sean.Stewart@netapp.com>
-
----
----
- libmultipath/hwtable.c | 12 +++++++++---
- 1 file changed, 9 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/hwtable.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/hwtable.c
-+++ multipath-tools-130222/libmultipath/hwtable.c
-@@ -1046,9 +1046,13 @@ static struct hwentry default_hw[] = {
- .checker_name = RDAC,
- .prio_name = PRIO_RDAC,
- },
-- /* LSI/Engenio/NetApp E-Series RDAC storage */
-+ /* LSI/Engenio/NetApp E-Series RDAC storage
-+ *
-+ * Maintainer : Sean Stewart
-+ * Mail : sean.stewart@netapp.com
-+ */
- {
-- .vendor = "(LSI|ENGENIO)",
-+ .vendor = "(NETAPP|LSI|ENGENIO)",
- .product = "INF-01-00",
- .bl_product = "Universal Xport",
- .features = "2 pg_init_retries 50",
-@@ -1056,10 +1060,12 @@ static struct hwentry default_hw[] = {
- .pgpolicy = GROUP_BY_PRIO,
- .pgfailback = -FAILBACK_IMMEDIATE,
- .rr_weight = RR_WEIGHT_NONE,
-- .no_path_retry = 15,
-+ .no_path_retry = 30,
- .checker_name = RDAC,
- .prio_name = PRIO_RDAC,
- .prio_args = NULL,
-+ .detect_prio = DETECT_PRIO_ON,
-+ .retain_hwhandler = RETAIN_HWHANDLER_ON,
- },
- {
- .vendor = "STK",
+++ /dev/null
----
- multipath/mpathconf | 21 +++++++++++++++------
- 1 file changed, 15 insertions(+), 6 deletions(-)
-
-Index: multipath-tools-130222/multipath/mpathconf
-===================================================================
---- multipath-tools-130222.orig/multipath/mpathconf
-+++ multipath-tools-130222/multipath/mpathconf
-@@ -159,7 +159,7 @@ if [ -z "$MODULE" -o "$MODULE" = "y" ];
- fi
-
- if [ "$MULTIPATHD" = "y" ]; then
-- if service multipathd status > /dev/null ; then
-+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
- HAVE_MULTIPATHD=1
- else
- HAVE_MULTIPATHD=0
-@@ -210,8 +210,17 @@ if [ -n "$SHOW_STATUS" ]; then
- echo "dm_multipath module is not loaded"
- fi
- fi
-- if [ -n "$HAVE_MULTIPATHD" ]; then
-- service multipathd status
-+ if [ -z "$HAVE_MULTIPATHD" ]; then
-+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
-+ HAVE_MULTIPATHD=1
-+ else
-+ HAVE_MULTIPATHD=0
-+ fi
-+ fi
-+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
-+ echo "multipathd is running"
-+ else
-+ echo "multipathd is not running"
- fi
- exit 0
- fi
-@@ -301,12 +310,12 @@ if [ "$ENABLE" = 1 ]; then
- modprobe dm_multipath
- fi
- if [ "$HAVE_MULTIPATHD" = 0 ]; then
-- service multipathd start
-+ systemctl start multipathd.service
- fi
- elif [ "$ENABLE" = 0 ]; then
- if [ "$HAVE_MULTIPATHD" = 1 ]; then
-- service multipathd stop
-+ systemctl stop multipathd.service
- fi
- elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
-- service multipathd reload
-+ systemctl reload multipathd.service
- fi
+++ /dev/null
----
- libmultipath/print.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/print.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/print.c
-+++ multipath-tools-130222/libmultipath/print.c
-@@ -422,6 +422,16 @@ snprint_path_serial (char * buff, size_t
- }
-
- static int
-+snprint_path_mpp (char * buff, size_t len, struct path * pp)
-+{
-+ if (!pp->mpp)
-+ return snprintf(buff, len, "[orphan]");
-+ if (!pp->mpp->alias)
-+ return snprintf(buff, len, "[unknown]");
-+ return snprint_str(buff, len, pp->mpp->alias);
-+}
-+
-+static int
- snprint_path_checker (char * buff, size_t len, struct path * pp)
- {
- struct checker * c = &pp->checker;
-@@ -464,6 +474,7 @@ struct path_data pd[] = {
- {'p', "pri", 0, snprint_pri},
- {'S', "size", 0, snprint_path_size},
- {'z', "serial", 0, snprint_path_serial},
-+ {'m', "multipath", 0, snprint_path_mpp},
- {0, NULL, 0 , NULL}
- };
-
+++ /dev/null
----
- multipathd/multipathd.service | 1 +
- 1 file changed, 1 insertion(+)
-
-Index: multipath-tools-130222/multipathd/multipathd.service
-===================================================================
---- multipath-tools-130222.orig/multipathd/multipathd.service
-+++ multipath-tools-130222/multipathd/multipathd.service
-@@ -10,6 +10,7 @@ Conflicts=shutdown.target
- [Service]
- Type=forking
- PIDFile=/var/run/multipathd.pid
-+ExecStartPre=/sbin/modprobe dm-multipath
- ExecStart=/sbin/multipathd
- ExecReload=/sbin/multipathd reconfigure
- #ExecStop=/path/to/scrip delete-me if not necessary
+++ /dev/null
----
- libmultipath/devmapper.c | 45 ---------------------------------------------
- libmultipath/devmapper.h | 1 -
- libmultipath/propsel.c | 2 --
- 3 files changed, 48 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -917,51 +917,6 @@ out:
- return r;
- }
-
--extern char *
--dm_get_name(char *uuid)
--{
-- struct dm_task *dmt;
-- struct dm_info info;
-- char *prefixed_uuid, *name = NULL;
-- const char *nametmp;
--
-- dmt = dm_task_create(DM_DEVICE_INFO);
-- if (!dmt)
-- return NULL;
--
-- prefixed_uuid = MALLOC(UUID_PREFIX_LEN + strlen(uuid) + 1);
-- if (!prefixed_uuid) {
-- condlog(0, "cannot create prefixed uuid : %s",
-- strerror(errno));
-- goto freeout;
-- }
-- sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid);
-- if (!dm_task_set_uuid(dmt, prefixed_uuid))
-- goto freeout;
--
-- if (!dm_task_run(dmt))
-- goto freeout;
--
-- if (!dm_task_get_info(dmt, &info) || !info.exists)
-- goto freeout;
--
-- nametmp = dm_task_get_name(dmt);
-- if (nametmp && strlen(nametmp)) {
-- name = MALLOC(strlen(nametmp) + 1);
-- if (name)
-- strcpy(name, nametmp);
-- } else {
-- condlog(2, "%s: no device-mapper name found", uuid);
-- }
--
--freeout:
-- if (prefixed_uuid)
-- FREE(prefixed_uuid);
-- dm_task_destroy(dmt);
--
-- return name;
--}
--
- int
- dm_geteventnr (char *name)
- {
-Index: multipath-tools-130222/libmultipath/devmapper.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.h
-+++ multipath-tools-130222/libmultipath/devmapper.h
-@@ -40,7 +40,6 @@ int dm_remove_partmaps (const char * map
- int dm_get_uuid(char *name, char *uuid);
- int dm_get_info (char * mapname, struct dm_info ** dmi);
- int dm_rename (char * old, char * new);
--char * dm_get_name(char * uuid);
- int dm_reassign(const char * mapname);
- int dm_reassign_table(const char *name, char *old, char *new);
- int dm_setgeometry(struct multipath *mpp);
-Index: multipath-tools-130222/libmultipath/propsel.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.c
-+++ multipath-tools-130222/libmultipath/propsel.c
-@@ -263,8 +263,6 @@ select_alias (struct multipath * mp)
- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
- }
- if (mp->alias == NULL)
-- mp->alias = dm_get_name(mp->wwid);
-- if (mp->alias == NULL)
- mp->alias = STRDUP(mp->wwid);
- }
-
+++ /dev/null
----
- libmultipath/hwtable.c | 1 +
- 1 file changed, 1 insertion(+)
-
-Index: multipath-tools-130222/libmultipath/hwtable.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/hwtable.c
-+++ multipath-tools-130222/libmultipath/hwtable.c
-@@ -794,6 +794,7 @@ static struct hwentry default_hw[] = {
- .prio_name = PRIO_ONTAP,
- .prio_args = NULL,
- .retain_hwhandler = RETAIN_HWHANDLER_ON,
-+ .user_friendly_names = USER_FRIENDLY_NAMES_OFF,
- .detect_prio = DETECT_PRIO_ON,
- },
- /*
+++ /dev/null
----
- libmultipath/propsel.c | 11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/propsel.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.c
-+++ multipath-tools-130222/libmultipath/propsel.c
-@@ -384,10 +384,17 @@ select_getuid (struct path * pp)
- void
- detect_prio(struct path * pp)
- {
-+ int ret;
- struct prio *p = &pp->prio;
-
-- if (get_target_port_group_support(pp->fd) > 0)
-- prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS);
-+ if (get_target_port_group_support(pp->fd) <= 0)
-+ return;
-+ ret = get_target_port_group(pp->fd);
-+ if (ret < 0)
-+ return;
-+ if (get_asymmetric_access_state(pp->fd, ret) < 0)
-+ return;
-+ prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS);
- }
-
- extern int
+++ /dev/null
----
- libmultipath/alias.c | 39 ++++++++++++++++++++++++++++++---------
- 1 file changed, 30 insertions(+), 9 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/alias.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/alias.c
-+++ multipath-tools-130222/libmultipath/alias.c
-@@ -46,11 +46,11 @@ format_devname(char *name, int id, int l
- memset(name,0, len);
- strcpy(name, prefix);
- for (pos = len - 1; pos >= prefix_len; pos--) {
-+ id--;
- name[pos] = 'a' + id % 26;
- if (id < 26)
- break;
- id /= 26;
-- id--;
- }
- memmove(name + prefix_len, name + pos, len - pos);
- name[prefix_len + len - pos] = '\0';
-@@ -66,13 +66,22 @@ scan_devname(char *alias, char *prefix)
- if (!prefix || strncmp(alias, prefix, strlen(prefix)))
- return -1;
-
-+ if (strlen(alias) == strlen(prefix))
-+ return -1;
-+
-+ if (strlen(alias) > strlen(prefix) + 7)
-+ /* id of 'aaaaaaaa' overflows int */
-+ return -1;
-+
- c = alias + strlen(prefix);
- while (*c != '\0' && *c != ' ' && *c != '\t') {
-+ if (*c < 'a' || *c > 'z')
-+ return -1;
- i = *c - 'a';
- n = ( n * 26 ) + i;
-+ if (n < 0)
-+ return -1;
- c++;
-- if (*c < 'a' || *c > 'z')
-- break;
- n++;
- }
-
-@@ -84,7 +93,9 @@ lookup_binding(FILE *f, char *map_wwid,
- {
- char buf[LINE_MAX];
- unsigned int line_nr = 0;
-- int id = 0;
-+ int id = 1;
-+ int biggest_id = 1;
-+ int smallest_bigger_id = INT_MAX;
-
- *map_alias = NULL;
-
-@@ -100,8 +111,12 @@ lookup_binding(FILE *f, char *map_wwid,
- if (!alias) /* blank line */
- continue;
- curr_id = scan_devname(alias, prefix);
-- if (curr_id >= id)
-- id = curr_id + 1;
-+ if (curr_id == id)
-+ id++;
-+ if (curr_id > biggest_id)
-+ biggest_id = curr_id;
-+ if (curr_id > id && curr_id < smallest_bigger_id)
-+ smallest_bigger_id = curr_id;
- wwid = strtok(NULL, " \t");
- if (!wwid){
- condlog(3,
-@@ -116,11 +131,17 @@ lookup_binding(FILE *f, char *map_wwid,
- if (*map_alias == NULL)
- condlog(0, "Cannot copy alias from bindings "
- "file : %s", strerror(errno));
-- return id;
-+ return 0;
- }
- }
- condlog(3, "No matching wwid [%s] in bindings file.", map_wwid);
-- return id;
-+ if (id < 0) {
-+ condlog(0, "no more available user_friendly_names");
-+ return 0;
-+ }
-+ if (id < smallest_bigger_id)
-+ return id;
-+ return biggest_id + 1;
- }
-
- static int
-@@ -254,7 +275,7 @@ get_user_friendly_alias(char *wwid, char
- return NULL;
- }
-
-- if (!alias && can_write && !bindings_read_only)
-+ if (!alias && can_write && !bindings_read_only && id)
- alias = allocate_binding(fd, wwid, id, prefix);
-
- fclose(f);
+++ /dev/null
----
- libmultipath/configure.c | 7 ------
- libmultipath/devmapper.c | 53 ++++++++++++++++++++++-------------------------
- libmultipath/devmapper.h | 2 -
- 3 files changed, 25 insertions(+), 37 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -384,24 +384,17 @@ domap (struct multipath * mpp, char * pa
-
- r = dm_addmap_create(mpp, params);
-
-- if (!r)
-- r = dm_addmap_create_ro(mpp, params);
--
- lock_multipath(mpp, 0);
- break;
-
- case ACT_RELOAD:
- r = dm_addmap_reload(mpp, params);
-- if (!r)
-- r = dm_addmap_reload_ro(mpp, params);
- if (r)
- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias);
- break;
-
- case ACT_RESIZE:
- r = dm_addmap_reload(mpp, params);
-- if (!r)
-- r = dm_addmap_reload_ro(mpp, params);
- if (r)
- r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1);
- break;
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -298,42 +298,39 @@ dm_addmap (int task, const char *target,
- return r;
- }
-
--static int
--_dm_addmap_create (struct multipath *mpp, char * params, int ro) {
-- int r;
-- r = dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro);
-- /*
-- * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
-- * Failing the second part leaves an empty map. Clean it up.
-- */
-- if (!r && dm_map_present(mpp->alias)) {
-- condlog(3, "%s: failed to load map (a path might be in use)",
-- mpp->alias);
-- dm_flush_map_nosync(mpp->alias);
-+extern int
-+dm_addmap_create (struct multipath *mpp, char * params) {
-+ int ro;
-+
-+ for (ro = 0; ro <= 1; ro++) {
-+ int err;
-+
-+ if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro))
-+ return 1;
-+ /*
-+ * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
-+ * Failing the second part leaves an empty map. Clean it up.
-+ */
-+ err = errno;
-+ if (dm_map_present(mpp->alias)) {
-+ condlog(3, "%s: failed to load map (a path might be in use)", mpp->alias);
-+ dm_flush_map_nosync(mpp->alias);
-+ }
-+ if (err != EROFS)
-+ break;
- }
-- return r;
-+ return 0;
- }
-
- #define ADDMAP_RW 0
- #define ADDMAP_RO 1
-
- extern int
--dm_addmap_create (struct multipath *mpp, char *params) {
-- return _dm_addmap_create(mpp, params, ADDMAP_RW);
--}
--
--extern int
--dm_addmap_create_ro (struct multipath *mpp, char *params) {
-- return _dm_addmap_create(mpp, params, ADDMAP_RO);
--}
--
--extern int
- dm_addmap_reload (struct multipath *mpp, char *params) {
-- return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW);
--}
--
--extern int
--dm_addmap_reload_ro (struct multipath *mpp, char *params) {
-+ if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW))
-+ return 1;
-+ if (errno != EROFS)
-+ return 0;
- return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RO);
- }
-
-Index: multipath-tools-130222/libmultipath/devmapper.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.h
-+++ multipath-tools-130222/libmultipath/devmapper.h
-@@ -12,9 +12,7 @@ int dm_drv_version (unsigned int * versi
- int dm_simplecmd_flush (int, const char *, int);
- int dm_simplecmd_noflush (int, const char *);
- int dm_addmap_create (struct multipath *mpp, char *params);
--int dm_addmap_create_ro (struct multipath *mpp, char *params);
- int dm_addmap_reload (struct multipath *mpp, char *params);
--int dm_addmap_reload_ro (struct multipath *mpp, char *params);
- int dm_map_present (const char *);
- int dm_get_map(char *, unsigned long long *, char *);
- int dm_get_status(char *, char *);
+++ /dev/null
----
- libmultipath/file.c | 4 +-
- libmultipath/lock.c | 9 ----
- libmultipath/lock.h | 1
- libmultipath/log_pthread.c | 22 -----------
- libmultipath/waiter.c | 2 -
- multipathd/cli_handlers.c | 4 +-
- multipathd/main.c | 90 ++++++++++++++++++++-------------------------
- multipathd/main.h | 3 +
- multipathd/uxlsnr.c | 21 +++++++---
- multipathd/uxlsnr.h | 3 +
- 10 files changed, 65 insertions(+), 94 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/file.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/file.c
-+++ multipath-tools-130222/libmultipath/file.c
-@@ -98,7 +98,7 @@ lock_file(int fd, char *file_name)
- sigaddset(&set, SIGALRM);
-
- sigaction(SIGALRM, &act, &oldact);
-- sigprocmask(SIG_UNBLOCK, &set, &oldset);
-+ pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
-
- alarm(FILE_TIMEOUT);
- err = fcntl(fd, F_SETLKW, &lock);
-@@ -112,7 +112,7 @@ lock_file(int fd, char *file_name)
- condlog(0, "%s is locked. Giving up.", file_name);
- }
-
-- sigprocmask(SIG_SETMASK, &oldset, NULL);
-+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- sigaction(SIGALRM, &oldact, NULL);
- return err;
- }
-Index: multipath-tools-130222/libmultipath/lock.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/lock.c
-+++ multipath-tools-130222/libmultipath/lock.c
-@@ -1,16 +1,7 @@
- #include <pthread.h>
--#include <signal.h>
- #include "lock.h"
- #include <stdio.h>
-
--void block_signal (int signum, sigset_t *old)
--{
-- sigset_t set;
-- sigemptyset(&set);
-- sigaddset(&set, signum);
-- pthread_sigmask(SIG_BLOCK, &set, old);
--}
--
- void cleanup_lock (void * data)
- {
- unlock ((*(struct mutex_lock *)data));
-Index: multipath-tools-130222/libmultipath/lock.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/lock.h
-+++ multipath-tools-130222/libmultipath/lock.h
-@@ -29,6 +29,5 @@ struct mutex_lock {
- #endif
-
- void cleanup_lock (void * data);
--void block_signal(int signum, sigset_t *old);
-
- #endif /* _LOCK_H */
-Index: multipath-tools-130222/libmultipath/log_pthread.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/log_pthread.c
-+++ multipath-tools-130222/libmultipath/log_pthread.c
-@@ -22,26 +22,13 @@ pthread_cond_t logev_cond;
-
- int logq_running;
-
--static void
--sigusr1 (int sig)
--{
-- pthread_mutex_lock(&logq_lock);
-- log_reset("multipathd");
-- pthread_mutex_unlock(&logq_lock);
--}
--
- void log_safe (int prio, const char * fmt, va_list ap)
- {
-- sigset_t old;
--
- if (log_thr == (pthread_t)0) {
- syslog(prio, fmt, ap);
- return;
- }
-
-- block_signal(SIGUSR1, &old);
-- block_signal(SIGHUP, NULL);
--
- pthread_mutex_lock(&logq_lock);
- log_enqueue(prio, fmt, ap);
- pthread_mutex_unlock(&logq_lock);
-@@ -49,8 +36,6 @@ void log_safe (int prio, const char * fm
- pthread_mutex_lock(&logev_lock);
- pthread_cond_signal(&logev_cond);
- pthread_mutex_unlock(&logev_lock);
--
-- pthread_sigmask(SIG_SETMASK, &old, NULL);
- }
-
- void log_thread_flush (void)
-@@ -81,15 +66,8 @@ static void flush_logqueue (void)
-
- static void * log_thread (void * et)
- {
-- struct sigaction sig;
- int running;
-
-- sig.sa_handler = sigusr1;
-- sigemptyset(&sig.sa_mask);
-- sig.sa_flags = 0;
-- if (sigaction(SIGUSR1, &sig, NULL) < 0)
-- logdbg(stderr, "Cannot set signal handler");
--
- pthread_mutex_lock(&logev_lock);
- logq_running = 1;
- pthread_mutex_unlock(&logev_lock);
-Index: multipath-tools-130222/libmultipath/waiter.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/waiter.c
-+++ multipath-tools-130222/libmultipath/waiter.c
-@@ -157,8 +157,6 @@ void *waitevent (void *et)
- waiter = (struct event_thread *)et;
- pthread_cleanup_push(free_waiter, et);
-
-- block_signal(SIGUSR1, NULL);
-- block_signal(SIGHUP, NULL);
- while (1) {
- r = waiteventloop(waiter);
-
-Index: multipath-tools-130222/multipathd/cli_handlers.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli_handlers.c
-+++ multipath-tools-130222/multipathd/cli_handlers.c
-@@ -939,8 +939,8 @@ int
- cli_shutdown (void * v, char ** reply, int * len, void * data)
- {
- condlog(3, "shutdown (operator)");
--
-- return exit_daemon(0);
-+ exit_daemon();
-+ return 0;
- }
-
- int
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -17,6 +17,7 @@
- #include <limits.h>
- #include <linux/oom.h>
- #include <libudev.h>
-+#include <semaphore.h>
- #include <mpath_persist.h>
-
- /*
-@@ -52,6 +53,7 @@
- #include <wwids.h>
- #include <pgpolicies.h>
- #include <uevent.h>
-+#include <log.h>
-
- #include "main.h"
- #include "pidfile.h"
-@@ -81,13 +83,11 @@ struct mpath_event_param
-
- unsigned int mpath_mx_alloc_len;
-
--pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
--pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
--
- int logsink;
- enum daemon_status running_state;
- pid_t daemon_pid;
-
-+static sem_t exit_sem;
- /*
- * global copy of vecs for use in sig handlers
- */
-@@ -838,9 +838,6 @@ out:
- static void *
- ueventloop (void * ap)
- {
-- block_signal(SIGUSR1, NULL);
-- block_signal(SIGHUP, NULL);
--
- if (uevent_listen())
- condlog(0, "error starting uevent listener");
-
-@@ -850,9 +847,6 @@ ueventloop (void * ap)
- static void *
- uevqloop (void * ap)
- {
-- block_signal(SIGUSR1, NULL);
-- block_signal(SIGHUP, NULL);
--
- if (uevent_dispatch(&uev_trigger, ap))
- condlog(0, "error starting uevent dispatcher");
-
-@@ -861,9 +855,6 @@ uevqloop (void * ap)
- static void *
- uxlsnrloop (void * ap)
- {
-- block_signal(SIGUSR1, NULL);
-- block_signal(SIGHUP, NULL);
--
- if (cli_init())
- return NULL;
-
-@@ -913,18 +904,10 @@ uxlsnrloop (void * ap)
- return NULL;
- }
-
--int
--exit_daemon (int status)
-+void
-+exit_daemon (void)
- {
-- if (status != 0)
-- fprintf(stderr, "bad exit status. see daemon.log\n");
--
-- if (running_state != DAEMON_SHUTDOWN) {
-- pthread_mutex_lock(&exit_mutex);
-- pthread_cond_signal(&exit_cond);
-- pthread_mutex_unlock(&exit_mutex);
-- }
-- return status;
-+ sem_post(&exit_sem);
- }
-
- const char *
-@@ -1287,7 +1270,6 @@ checkerloop (void *ap)
- struct path *pp;
- int count = 0;
- unsigned int i;
-- sigset_t old;
-
- mlockall(MCL_CURRENT | MCL_FUTURE);
- vecs = (struct vectors *)ap;
-@@ -1301,7 +1283,6 @@ checkerloop (void *ap)
- }
-
- while (1) {
-- block_signal(SIGHUP, &old);
- pthread_cleanup_push(cleanup_lock, &vecs->lock);
- lock(vecs->lock);
- pthread_testcancel();
-@@ -1325,7 +1306,6 @@ checkerloop (void *ap)
- }
-
- lock_cleanup_pop(vecs->lock);
-- pthread_sigmask(SIG_SETMASK, &old, NULL);
- sleep(1);
- }
- return NULL;
-@@ -1485,36 +1465,56 @@ signal_set(int signo, void (*func) (int)
- return (osig.sa_handler);
- }
-
-+void
-+handle_signals(void)
-+{
-+ if (reconfig_sig && running_state == DAEMON_RUNNING) {
-+ condlog(2, "reconfigure (signal)");
-+ pthread_cleanup_push(cleanup_lock,
-+ &gvecs->lock);
-+ lock(gvecs->lock);
-+ pthread_testcancel();
-+ reconfigure(gvecs);
-+ lock_cleanup_pop(gvecs->lock);
-+ }
-+ if (log_reset_sig) {
-+ condlog(2, "reset log (signal)");
-+ pthread_mutex_lock(&logq_lock);
-+ log_reset("multipathd");
-+ pthread_mutex_unlock(&logq_lock);
-+ }
-+ reconfig_sig = 0;
-+ log_reset_sig = 0;
-+}
-+
- static void
- sighup (int sig)
- {
-- condlog(2, "reconfigure (SIGHUP)");
--
-- if (running_state != DAEMON_RUNNING)
-- return;
--
-- reconfigure(gvecs);
--
--#ifdef _DEBUG_
-- dbg_free_final(NULL);
--#endif
-+ reconfig_sig = 1;
- }
-
- static void
- sigend (int sig)
- {
-- exit_daemon(0);
-+ exit_daemon();
- }
-
- static void
- sigusr1 (int sig)
- {
-- condlog(3, "SIGUSR1 received");
-+ log_reset_sig = 1;
- }
-
- static void
- signal_init(void)
- {
-+ sigset_t set;
-+
-+ sigemptyset(&set);
-+ sigaddset(&set, SIGHUP);
-+ sigaddset(&set, SIGUSR1);
-+ pthread_sigmask(SIG_BLOCK, &set, NULL);
-+
- signal_set(SIGHUP, sighup);
- signal_set(SIGUSR1, sigusr1);
- signal_set(SIGINT, sigend);
-@@ -1587,10 +1587,11 @@ child (void * param)
- struct vectors * vecs;
- struct multipath * mpp;
- int i;
-- sigset_t set;
- int rc, pid_rc;
-
- mlockall(MCL_CURRENT | MCL_FUTURE);
-+ sem_init(&exit_sem, 0, 0);
-+ signal_init();
-
- setup_thread_attr(&misc_attr, 64 * 1024, 1);
- setup_thread_attr(&waiter_attr, 32 * 1024, 1);
-@@ -1650,7 +1651,6 @@ child (void * param)
- if (!vecs)
- exit(1);
-
-- signal_init();
- setscheduler();
- set_oom_adj();
-
-@@ -1693,25 +1693,17 @@ child (void * param)
- }
- pthread_attr_destroy(&misc_attr);
-
-- pthread_mutex_lock(&exit_mutex);
- /* Startup complete, create logfile */
- pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
- /* Ignore errors, we can live without */
-
- running_state = DAEMON_RUNNING;
-- pthread_cond_wait(&exit_cond, &exit_mutex);
-- /* Need to block these to avoid deadlocking */
-- sigemptyset(&set);
-- sigaddset(&set, SIGTERM);
-- sigaddset(&set, SIGINT);
-- pthread_sigmask(SIG_BLOCK, &set, NULL);
-
- /*
- * exit path
- */
-+ while(sem_wait(&exit_sem) != 0); /* Do nothing */
- running_state = DAEMON_SHUTDOWN;
-- pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-- block_signal(SIGHUP, NULL);
- lock(vecs->lock);
- if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF)
- vector_foreach_slot(vecs->mpvec, mpp, i)
-Index: multipath-tools-130222/multipathd/main.h
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.h
-+++ multipath-tools-130222/multipathd/main.h
-@@ -16,7 +16,7 @@ struct prin_resp;
-
- extern pid_t daemon_pid;
-
--int exit_daemon(int);
-+void exit_daemon(void);
- const char * daemon_status(void);
- int reconfigure (struct vectors *);
- int ev_add_path (struct path *, struct vectors *);
-@@ -35,5 +35,6 @@ int mpath_pr_event_handle(struct path *p
- void * mpath_pr_event_handler_fn (void * );
- int update_map_pr(struct multipath *mpp);
- void * mpath_pr_event_handler_fn (void * pathp );
-+void handle_signals(void);
-
- #endif /* MAIN_H */
-Index: multipath-tools-130222/multipathd/uxlsnr.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/uxlsnr.c
-+++ multipath-tools-130222/multipathd/uxlsnr.c
-@@ -8,6 +8,7 @@
- /*
- * A simple domain socket listener
- */
-+#define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-@@ -19,20 +20,21 @@
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <sys/poll.h>
--
-+#include <signal.h>
- #include <checkers.h>
--
- #include <memory.h>
- #include <debug.h>
- #include <vector.h>
- #include <structs.h>
-+#include <structs_vec.h>
- #include <uxsock.h>
- #include <defaults.h>
-
-+#include "main.h"
- #include "cli.h"
- #include "uxlsnr.h"
-
--#define SLEEP_TIME 5000
-+struct timespec sleep_time = {5, 0};
-
- struct client {
- int fd;
-@@ -42,6 +44,8 @@ struct client {
- static struct client *clients;
- static unsigned num_clients;
- struct pollfd *polls;
-+volatile sig_atomic_t reconfig_sig = 0;
-+volatile sig_atomic_t log_reset_sig = 0;
-
- /*
- * handle a new client joining
-@@ -104,6 +108,7 @@ void * uxsock_listen(int (*uxsock_trigge
- int rlen;
- char *inbuf;
- char *reply;
-+ sigset_t mask;
-
- ux_sock = ux_socket_listen(DEFAULT_SOCKET);
-
-@@ -115,7 +120,9 @@ void * uxsock_listen(int (*uxsock_trigge
- pthread_cleanup_push(uxsock_cleanup, NULL);
-
- polls = (struct pollfd *)MALLOC(0);
--
-+ pthread_sigmask(SIG_SETMASK, NULL, &mask);
-+ sigdelset(&mask, SIGHUP);
-+ sigdelset(&mask, SIGUSR1);
- while (1) {
- struct client *c;
- int i, poll_count;
-@@ -132,11 +139,13 @@ void * uxsock_listen(int (*uxsock_trigge
- }
-
- /* most of our life is spent in this call */
-- poll_count = poll(polls, i, SLEEP_TIME);
-+ poll_count = ppoll(polls, i, &sleep_time, &mask);
-
- if (poll_count == -1) {
-- if (errno == EINTR)
-+ if (errno == EINTR) {
-+ handle_signals();
- continue;
-+ }
-
- /* something went badly wrong! */
- condlog(0, "poll");
-Index: multipath-tools-130222/multipathd/uxlsnr.h
-===================================================================
---- multipath-tools-130222.orig/multipathd/uxlsnr.h
-+++ multipath-tools-130222/multipathd/uxlsnr.h
-@@ -4,5 +4,8 @@
- void * uxsock_listen(int (*uxsock_trigger)
- (char *, char **, int *, void *),
- void * trigger_data);
-+
-+extern volatile sig_atomic_t reconfig_sig;
-+extern volatile sig_atomic_t log_reset_sig;
- #endif
-
+++ /dev/null
----
- libmultipath/waiter.c | 9 +++++++++
- multipathd/main.c | 8 ++++++++
- 2 files changed, 17 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/waiter.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/waiter.c
-+++ multipath-tools-130222/libmultipath/waiter.c
-@@ -57,6 +57,7 @@ void stop_waiter_thread (struct multipat
- thread = mpp->waiter;
- mpp->waiter = (pthread_t)0;
- pthread_cancel(thread);
-+ pthread_kill(thread, SIGUSR2);
- }
-
- /*
-@@ -65,6 +66,7 @@ void stop_waiter_thread (struct multipat
- */
- int waiteventloop (struct event_thread *waiter)
- {
-+ sigset_t set, oldset;
- int event_nr;
- int r;
-
-@@ -97,8 +99,15 @@ int waiteventloop (struct event_thread *
- dm_task_no_open_count(waiter->dmt);
-
- /* wait */
-+ sigemptyset(&set);
-+ sigaddset(&set, SIGUSR2);
-+ pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
-+
-+ pthread_testcancel();
- r = dm_task_run(waiter->dmt);
-+ pthread_testcancel();
-
-+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- dm_task_destroy(waiter->dmt);
- waiter->dmt = NULL;
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -1506,6 +1506,12 @@ sigusr1 (int sig)
- }
-
- static void
-+sigusr2 (int sig)
-+{
-+ condlog(3, "SIGUSR2 received");
-+}
-+
-+static void
- signal_init(void)
- {
- sigset_t set;
-@@ -1513,10 +1519,12 @@ signal_init(void)
- sigemptyset(&set);
- sigaddset(&set, SIGHUP);
- sigaddset(&set, SIGUSR1);
-+ sigaddset(&set, SIGUSR2);
- pthread_sigmask(SIG_BLOCK, &set, NULL);
-
- signal_set(SIGHUP, sighup);
- signal_set(SIGUSR1, sigusr1);
-+ signal_set(SIGUSR2, sigusr2);
- signal_set(SIGINT, sigend);
- signal_set(SIGTERM, sigend);
- signal(SIGPIPE, SIG_IGN);
+++ /dev/null
----
- libmultipath/wwids.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/wwids.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.c
-+++ multipath-tools-130222/libmultipath/wwids.c
-@@ -4,6 +4,7 @@
- #include <string.h>
- #include <limits.h>
- #include <stdio.h>
-+#include <sys/types.h>
-
- #include "checkers.h"
- #include "vector.h"
-@@ -100,6 +101,11 @@ replace_wwids(vector mp)
- condlog(0, "cannot truncate wwids file : %s", strerror(errno));
- goto out_file;
- }
-+ if (lseek(fd, 0, SEEK_SET) < 0) {
-+ condlog(0, "cannot seek to the start of the file : %s",
-+ strerror(errno));
-+ goto out_file;
-+ }
- len = strlen(WWIDS_FILE_HEADER);
- if (write_all(fd, WWIDS_FILE_HEADER, len) != len) {
- condlog(0, "Can't write wwid file header : %s",
+++ /dev/null
----
- multipath/multipath.conf.5 | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.conf.5
-+++ multipath-tools-130222/multipath/multipath.conf.5
-@@ -136,7 +136,7 @@ per-multipath option in the configuratio
- 1 priority group per target node name. Target node names are fetched
- in /sys/class/fc_transport/target*/node_name.
- .TP
--Default value is \fImultibus\fR.
-+Default value is \fIfailover\fR.
- .RE
- .TP
- .B uid_attribute
-@@ -182,7 +182,7 @@ Generate a random priority between 1 and
- Generate the path priority based on the regular expression and the
- priority provided as argument. requires prio_args keyword.
- .TP
--Default value is \fBnone\fR.
-+Default value is \fBconst\fR.
- .RE
- .TP
- .B prio_args
-@@ -270,7 +270,7 @@ The number of IO to route to a path befo
- the same path group. This is only for BIO based multipath. Default is
- .I 1000
- .TP
--.B rr_min_io_q
-+.B rr_min_io_rq
- The number of IO requests to route to a path before switching to the
- next in the same path group. This is only for request based multipath.
- Default is
+++ /dev/null
----
- multipath/Makefile | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/multipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipath/Makefile
-+++ multipath-tools-130222/multipath/Makefile
-@@ -23,8 +23,8 @@ install:
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
- $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
- $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
-- $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
-- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
-+ $(INSTALL_PROGRAM) -d $(DESTDIR)/usr/lib/udev/rules.d
-+ $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
-@@ -32,7 +32,7 @@ install:
- $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(mandir)
-
- uninstall:
-- rm $(DESTDIR)/lib/udev/rules.d/62-multipath.rules
-+ rm $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
- rm $(DESTDIR)$(bindir)/$(EXEC)
- rm $(DESTDIR)$(bindir)/mpathconf
- rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
+++ /dev/null
----
- kpartx/kpartx.c | 3 +--
- kpartx/lopart.c | 2 +-
- 2 files changed, 2 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/kpartx/kpartx.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.c
-+++ multipath-tools-130222/kpartx/kpartx.c
-@@ -204,7 +204,6 @@ main(int argc, char **argv){
- char * delim = NULL;
- char *uuid = NULL;
- char *mapname = NULL;
-- int loopro = 0;
- int hotplug = 0;
- int loopcreated = 0;
- struct stat buf;
-@@ -315,7 +314,7 @@ main(int argc, char **argv){
- if (!loopdev) {
- loopdev = find_unused_loop_device();
-
-- if (set_loop(loopdev, device, 0, &loopro)) {
-+ if (set_loop(loopdev, device, 0, &ro)) {
- fprintf(stderr, "can't set up loop\n");
- exit (1);
- }
-Index: multipath-tools-130222/kpartx/lopart.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/lopart.c
-+++ multipath-tools-130222/kpartx/lopart.c
-@@ -230,7 +230,7 @@ set_loop (const char *device, const char
-
- if ((ffd = open (file, mode)) < 0) {
-
-- if (!*loopro && errno == EROFS)
-+ if (!*loopro && (errno == EROFS || errno == EACCES))
- ffd = open (file, mode = O_RDONLY);
-
- if (ffd < 0) {
+++ /dev/null
----
- libmultipath/dict.c | 4 ----
- 1 file changed, 4 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -2468,16 +2468,12 @@ snprint_def_verbosity (char * buff, int
- static int
- snprint_def_max_polling_interval (char * buff, int len, void * data)
- {
-- if (conf->max_checkint == MAX_CHECKINT(conf->checkint))
-- return 0;
- return snprintf(buff, len, "%i", conf->max_checkint);
- }
-
- static int
- snprint_reassign_maps (char * buff, int len, void * data)
- {
-- if (conf->reassign_maps == DEFAULT_REASSIGN_MAPS)
-- return 0;
- return snprintf(buff, len, "\"%s\"",
- conf->reassign_maps?"yes":"no");
- }
+++ /dev/null
----
- multipath/multipath.rules | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipath/multipath.rules
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.rules
-+++ multipath-tools-130222/multipath/multipath.rules
-@@ -11,7 +11,7 @@ ACTION=="add", ENV{DEVTYPE}!="partition"
- ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
- TEST=="/etc/multipath.conf", \
- PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
-- ENV{DM_MULTIPATH_DEVICE_PATH}="1"
-+ ENV{DM_MULTIPATH_DEVICE_PATH}="1" ENV{ID_FS_TYPE}="mpath_member"
-
- ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
- RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
+++ /dev/null
----
- multipath/main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -311,7 +311,7 @@ configure (void)
- /*
- * get a path list
- */
-- if (conf->dev)
-+ if (conf->dev && !conf->list)
- di_flag = DI_WWID;
-
- if (conf->list > 1)
+++ /dev/null
-diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
-index 7b1cb62..4b860bb 100644
---- a/multipathd/cli_handlers.c
-+++ b/multipathd/cli_handlers.c
-@@ -603,7 +603,18 @@ cli_resize(void *v, char **reply, int *len, void *data)
- }
-
- pgp = VECTOR_SLOT(mpp->pg, 0);
-+
-+ if (!pgp){
-+ condlog(0, "%s: couldn't get path group. cannot resize",
-+ mapname);
-+ return 1;
-+ }
- pp = VECTOR_SLOT(pgp->paths, 0);
-+
-+ if (!pp){
-+ condlog(0, "%s: couldn't get path. cannot resize", mapname);
-+ return 1;
-+ }
- if (!pp->udev || sysfs_get_size(pp, &size)) {
- condlog(0, "%s: couldn't get size for sysfs. cannot resize",
- mapname);
+++ /dev/null
----
- multipathd/cli_handlers.c | 3 ++-
- multipathd/main.c | 12 ++++++------
- 2 files changed, 8 insertions(+), 7 deletions(-)
-
-Index: multipath-tools-130222/multipathd/cli_handlers.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli_handlers.c
-+++ multipath-tools-130222/multipathd/cli_handlers.c
-@@ -632,7 +632,8 @@ cli_resize(void *v, char **reply, int *l
- return 1;
-
- dm_lib_release();
-- setup_multipath(vecs, mpp);
-+ if (setup_multipath(vecs, mpp) != 0)
-+ return 1;
- sync_map_state(mpp);
-
- return 0;
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -134,7 +134,6 @@ coalesce_maps(struct vectors *vecs, vect
- struct multipath * ompp;
- vector ompv = vecs->mpvec;
- unsigned int i;
-- int j;
-
- vector_foreach_slot (ompv, ompp, i) {
- if (!find_mp_by_wwid(nmpv, ompp->wwid)) {
-@@ -148,16 +147,17 @@ coalesce_maps(struct vectors *vecs, vect
- /*
- * may be just because the device is open
- */
-+ if (setup_multipath(vecs, ompp) != 0) {
-+ i--;
-+ continue;
-+ }
- if (!vector_alloc_slot(nmpv))
- return 1;
-
- vector_set_slot(nmpv, ompp);
-- setup_multipath(vecs, ompp);
-
-- if ((j = find_slot(ompv, (void *)ompp)) != -1)
-- vector_del_slot(ompv, j);
--
-- continue;
-+ vector_del_slot(ompv, i);
-+ i--;
- }
- else {
- dm_lib_release();
+++ /dev/null
----
- libmultipath/dict.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -1126,11 +1126,11 @@ hw_failback_handler(vector strvec)
-
- buff = set_value(strvec);
-
-- if (strlen(buff) == 6 && !strcmp(buff, "\"manual\""))
-+ if (strlen(buff) == 6 && !strcmp(buff, "manual"))
- hwe->pgfailback = -FAILBACK_MANUAL;
-- else if (strlen(buff) == 9 && !strcmp(buff, "\"immediate\""))
-+ else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
- hwe->pgfailback = -FAILBACK_IMMEDIATE;
-- else if (strlen(buff) == 10 && !strcmp(buff, "\"followover\""))
-+ else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
- hwe->pgfailback = -FAILBACK_FOLLOWOVER;
- else
- hwe->pgfailback = atoi(buff);
+++ /dev/null
----
- libmpathpersist/mpath_persist.c | 7 ++++---
- libmpathpersist/mpath_persist.h | 2 +-
- libmpathpersist/mpath_pr_ioctl.c | 5 +++--
- libmultipath/config.c | 9 +++------
- libmultipath/config.h | 2 +-
- mpathpersist/Makefile | 2 +-
- mpathpersist/main.c | 11 +++++++----
- multipath/Makefile | 2 +-
- multipath/main.c | 12 ++++++++----
- multipathd/main.c | 11 ++++++++---
- 10 files changed, 37 insertions(+), 26 deletions(-)
-
-Index: multipath-tools-130222/libmpathpersist/mpath_persist.c
-===================================================================
---- multipath-tools-130222.orig/libmpathpersist/mpath_persist.c
-+++ multipath-tools-130222/libmpathpersist/mpath_persist.c
-@@ -1,4 +1,3 @@
--#include "mpath_persist.h"
- #include <libdevmapper.h>
- #include <defaults.h>
- #include <sys/stat.h>
-@@ -8,6 +7,7 @@
- #include <checkers.h>
- #include <structs.h>
- #include <structs_vec.h>
-+#include <libudev.h>
-
- #include <prio.h>
- #include <unistd.h>
-@@ -20,6 +20,7 @@
- #include <ctype.h>
- #include <propsel.h>
-
-+#include "mpath_persist.h"
- #include "mpathpr.h"
- #include "mpath_pr_ioctl.h"
-
-@@ -32,9 +33,9 @@
-
-
- int
--mpath_lib_init (void)
-+mpath_lib_init (struct udev *udev)
- {
-- if (load_config(DEFAULT_CONFIGFILE)){
-+ if (load_config(DEFAULT_CONFIGFILE, udev)){
- condlog(0, "Failed to initialize multipath config.");
- return 1;
- }
-Index: multipath-tools-130222/libmpathpersist/mpath_persist.h
-===================================================================
---- multipath-tools-130222.orig/libmpathpersist/mpath_persist.h
-+++ multipath-tools-130222/libmpathpersist/mpath_persist.h
-@@ -174,7 +174,7 @@ struct prout_param_descriptor { /* PROU
- *
- * RETURNS: 0->Success, 1->Failed.
- */
--extern int mpath_lib_init (void );
-+extern int mpath_lib_init (struct udev *udev);
-
-
- /*
-Index: multipath-tools-130222/libmpathpersist/mpath_pr_ioctl.c
-===================================================================
---- multipath-tools-130222.orig/libmpathpersist/mpath_pr_ioctl.c
-+++ multipath-tools-130222/libmpathpersist/mpath_pr_ioctl.c
-@@ -10,8 +10,9 @@
- #include <string.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
--#include "mpath_pr_ioctl.h"
--#include <mpath_persist.h>
-+#include <libudev.h>
-+#include "mpath_pr_ioctl.h"
-+#include <mpath_persist.h>
-
- #include <debug.h>
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -467,9 +467,6 @@ free_config (struct config * conf)
- if (conf->dev)
- FREE(conf->dev);
-
-- if (conf->udev)
-- udev_unref(conf->udev);
--
- if (conf->multipath_dir)
- FREE(conf->multipath_dir);
-
-@@ -519,12 +516,12 @@ free_config (struct config * conf)
- }
-
- int
--load_config (char * file)
-+load_config (char * file, struct udev *udev)
- {
- if (!conf)
- conf = alloc_config();
-
-- if (!conf)
-+ if (!conf || !udev)
- return 1;
-
- /*
-@@ -533,7 +530,7 @@ load_config (char * file)
- if (!conf->verbosity)
- conf->verbosity = DEFAULT_VERBOSITY;
-
-- conf->udev = udev_new();
-+ conf->udev = udev;
- dm_drv_version(conf->version, TGT_MPATH);
- conf->dev_type = DEV_NONE;
- conf->minio = DEFAULT_MINIO;
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -159,7 +159,7 @@ void free_mptable (vector mptable);
-
- int store_hwe (vector hwtable, struct hwentry *);
-
--int load_config (char * file);
-+int load_config (char * file, struct udev * udev);
- struct config * alloc_config (void);
- void free_config (struct config * conf);
-
-Index: multipath-tools-130222/mpathpersist/main.c
-===================================================================
---- multipath-tools-130222.orig/mpathpersist/main.c
-+++ multipath-tools-130222/mpathpersist/main.c
-@@ -7,6 +7,7 @@
- #include <vector.h>
- #include <structs.h>
- #include <getopt.h>
-+#include <libudev.h>
- #include <mpath_persist.h>
- #include "main.h"
- #include <pthread.h>
-@@ -68,7 +69,8 @@ int main (int argc, char * argv[])
- int noisy = 0;
- int num_transport =0;
- void *resp = NULL;
-- struct transportid * tmp;
-+ struct transportid * tmp;
-+ struct udev *udev = NULL;
-
- if (optind == argc)
- {
-@@ -84,8 +86,8 @@ int main (int argc, char * argv[])
- exit (1);
- }
-
--
-- mpath_lib_init();
-+ udev = udev_new();
-+ mpath_lib_init(udev);
- memset(transportids,0,MPATH_MX_TIDS);
-
- while (1)
-@@ -461,12 +463,13 @@ int main (int argc, char * argv[])
- if (res < 0)
- {
- mpath_lib_exit();
-+ udev_unref(udev);
- return MPATH_PR_FILE_ERROR;
- }
-
- out :
- mpath_lib_exit();
--
-+ udev_unref(udev);
- return (ret >= 0) ? ret : MPATH_PR_OTHER;
- }
-
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -27,6 +27,7 @@
- #include <stdio.h>
- #include <unistd.h>
- #include <ctype.h>
-+#include <libudev.h>
-
- #include <checkers.h>
- #include <prio.h>
-@@ -435,6 +436,7 @@ convert_dev(char *dev)
- int
- main (int argc, char *argv[])
- {
-+ struct udev *udev;
- int arg;
- extern char *optarg;
- extern int optind;
-@@ -445,7 +447,9 @@ main (int argc, char *argv[])
- exit(1);
- }
-
-- if (load_config(DEFAULT_CONFIGFILE))
-+ udev = udev_new();
-+
-+ if (load_config(DEFAULT_CONFIGFILE, udev))
- exit(1);
-
- if (dm_prereq())
-@@ -560,11 +564,11 @@ main (int argc, char *argv[])
-
- if (init_checkers()) {
- condlog(0, "failed to initialize checkers");
-- exit(1);
-+ goto out;
- }
- if (init_prio()) {
- condlog(0, "failed to initialize prioritizers");
-- exit(1);
-+ goto out;
- }
- dm_init();
-
-@@ -628,7 +632,7 @@ out:
- */
- free_config(conf);
- conf = NULL;
--
-+ udev_unref(udev);
- #ifdef _DEBUG_
- dbg_free_final(NULL);
- #endif
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -93,6 +93,8 @@ static sem_t exit_sem;
- */
- struct vectors * gvecs;
-
-+struct udev * udev;
-+
- static int
- need_switch_pathgroup (struct multipath * mpp, int refresh)
- {
-@@ -1408,7 +1410,7 @@ reconfigure (struct vectors * vecs)
- vecs->pathvec = NULL;
- conf = NULL;
-
-- if (!load_config(DEFAULT_CONFIGFILE)) {
-+ if (!load_config(DEFAULT_CONFIGFILE, udev)) {
- conf->verbosity = old->verbosity;
- conf->daemon = 1;
- configure(vecs, 1);
-@@ -1601,6 +1603,8 @@ child (void * param)
- sem_init(&exit_sem, 0, 0);
- signal_init();
-
-+ udev = udev_new();
-+
- setup_thread_attr(&misc_attr, 64 * 1024, 1);
- setup_thread_attr(&waiter_attr, 32 * 1024, 1);
-
-@@ -1615,7 +1619,7 @@ child (void * param)
- condlog(2, "--------start up--------");
- condlog(2, "read " DEFAULT_CONFIGFILE);
-
-- if (load_config(DEFAULT_CONFIGFILE))
-+ if (load_config(DEFAULT_CONFIGFILE, udev))
- exit(1);
-
- if (init_checkers()) {
-@@ -1765,7 +1769,8 @@ child (void * param)
- */
- free_config(conf);
- conf = NULL;
--
-+ udev_unref(udev);
-+ udev = NULL;
- #ifdef _DEBUG_
- dbg_free_final(NULL);
- #endif
-Index: multipath-tools-130222/mpathpersist/Makefile
-===================================================================
---- multipath-tools-130222.orig/mpathpersist/Makefile
-+++ multipath-tools-130222/mpathpersist/Makefile
-@@ -5,7 +5,7 @@ include ../Makefile.inc
- OBJS = main.o
-
- CFLAGS += -I$(multipathdir) -I$(mpathpersistdir)
--LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath
-+LDFLAGS += -lpthread -ldevmapper -L$(mpathpersistdir) -lmpathpersist -L$(multipathdir) -lmultipath -ludev
-
- EXEC = mpathpersist
-
-Index: multipath-tools-130222/multipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipath/Makefile
-+++ multipath-tools-130222/multipath/Makefile
-@@ -7,7 +7,7 @@ include ../Makefile.inc
- OBJS = main.o
-
- CFLAGS += -fPIC -I$(multipathdir)
--LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath
-+LDFLAGS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath -ludev
-
- EXEC = multipath
-
+++ /dev/null
----
- libmultipath/discovery.c | 1 +
- 1 file changed, 1 insertion(+)
-
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -799,6 +799,7 @@ path_offline (struct path * pp)
- condlog(3, "%s: path state = %s", pp->dev, buff);
-
- if (!strncmp(buff, "offline", 7) ||
-+ !strncmp(buff, "quiesce", 7) ||
- !strncmp(buff, "transport-offline", 17)) {
- pp->offline = 1;
- return PATH_DOWN;
+++ /dev/null
----
- libmultipath/prioritizers/alua.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/prioritizers/alua.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c
-+++ multipath-tools-130222/libmultipath/prioritizers/alua.c
-@@ -108,7 +108,7 @@ int getprio (struct path * pp, char * ar
- default:
- rc = 0;
- }
-- if (priopath)
-+ if (priopath && aas != AAS_OPTIMIZED)
- rc += 80;
- } else {
- switch(-rc) {
+++ /dev/null
----
- libmultipath/discovery.c | 109 +++++++++++++++++++++++++++++++++++++----------
- libmultipath/sysfs.c | 86 +++++++++++++++++++++++++++++++------
- libmultipath/sysfs.h | 2
- 3 files changed, 161 insertions(+), 36 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -162,7 +162,6 @@ declare_sysfs_get_str(cutype);
- declare_sysfs_get_str(vendor);
- declare_sysfs_get_str(model);
- declare_sysfs_get_str(rev);
--declare_sysfs_get_str(state);
- declare_sysfs_get_str(dev);
-
- int
-@@ -315,9 +314,14 @@ static void
- sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
- {
- struct udev_device *rport_dev = NULL;
-- char value[11];
-+ char value[16];
- char rport_id[32];
-+ int delay_fast_io_fail = 0;
-+ int current_dev_loss = 0;
-+ int ret;
-
-+ if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
-+ return;
- sprintf(rport_id, "rport-%d:%d-%d",
- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
- rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
-@@ -330,33 +334,85 @@ sysfs_set_rport_tmo(struct multipath *mp
- condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
- pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
-
-- snprintf(value, 11, "%u", mpp->dev_loss);
-- if (mpp->dev_loss &&
-- sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, 11) <= 0) {
-- if ((mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET ||
-- mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
-- && mpp->dev_loss > 600) {
-- condlog(3, "%s: limiting dev_loss_tmo to 600, since "
-- "fast_io_fail is not set", mpp->alias);
-- snprintf(value, 11, "%u", 600);
-- if (sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
-- value, 11) <= 0)
-- condlog(0, "%s failed to set dev_loss_tmo",
-- mpp->alias);
-+ memset(value, 0, 16);
-+ if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
-+ ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo",
-+ value, 16);
-+ if (ret <= 0) {
-+ condlog(0, "%s: failed to read dev_loss_tmo value, "
-+ "error %d", rport_id, -ret);
- goto out;
- }
-+ if (sscanf(value, "%u\n", ¤t_dev_loss) != 1) {
-+ condlog(0, "%s: Cannot parse dev_loss_tmo "
-+ "attribute '%s'", rport_id, value);
-+ goto out;
-+ }
-+ if ((mpp->dev_loss &&
-+ mpp->fast_io_fail >= (int)mpp->dev_loss) ||
-+ (!mpp->dev_loss &&
-+ mpp->fast_io_fail >= (int)current_dev_loss)) {
-+ condlog(3, "%s: limiting fast_io_fail_tmo to %d, since "
-+ "it must be less than dev_loss_tmo",
-+ rport_id, mpp->dev_loss - 1);
-+ if (mpp->dev_loss)
-+ mpp->fast_io_fail = mpp->dev_loss - 1;
-+ else
-+ mpp->fast_io_fail = current_dev_loss - 1;
-+ }
-+ if (mpp->fast_io_fail >= (int)current_dev_loss)
-+ delay_fast_io_fail = 1;
-+ }
-+ if (mpp->dev_loss > 600 &&
-+ (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF ||
-+ mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)) {
-+ condlog(3, "%s: limiting dev_loss_tmo to 600, since "
-+ "fast_io_fail is unset or off", rport_id);
-+ mpp->dev_loss = 600;
- }
-- if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET){
-+ if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
- if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
- sprintf(value, "off");
- else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
- sprintf(value, "0");
-+ else if (delay_fast_io_fail)
-+ snprintf(value, 16, "%u", current_dev_loss - 1);
- else
-- snprintf(value, 11, "%u", mpp->fast_io_fail);
-- if (sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
-- value, 11) <= 0) {
-- condlog(0, "%s failed to set fast_io_fail_tmo",
-- mpp->alias);
-+ snprintf(value, 16, "%u", mpp->fast_io_fail);
-+ ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
-+ value, strlen(value));
-+ if (ret <= 0) {
-+ if (ret == -EBUSY)
-+ condlog(3, "%s: rport blocked", rport_id);
-+ else
-+ condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
-+ rport_id, value, -ret);
-+ goto out;
-+ }
-+ }
-+ if (mpp->dev_loss) {
-+ snprintf(value, 16, "%u", mpp->dev_loss);
-+ ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
-+ value, strlen(value));
-+ if (ret <= 0) {
-+ if (ret == -EBUSY)
-+ condlog(3, "%s: rport blocked", rport_id);
-+ else
-+ condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
-+ rport_id, value, -ret);
-+ goto out;
-+ }
-+ }
-+ if (delay_fast_io_fail) {
-+ snprintf(value, 16, "%u", mpp->fast_io_fail);
-+ ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
-+ value, strlen(value));
-+ if (ret <= 0) {
-+ if (ret == -EBUSY)
-+ condlog(3, "%s: rport blocked", rport_id);
-+ else
-+ condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
-+ rport_id, value, -ret);
- }
- }
- out:
-@@ -394,7 +450,7 @@ sysfs_set_session_tmo(struct multipath *
- } else {
- snprintf(value, 11, "%u", mpp->fast_io_fail);
- if (sysfs_attr_set_value(session_dev, "recovery_tmo",
-- value, 11)) {
-+ value, 11) <= 0) {
- condlog(3, "%s: Failed to set recovery_tmo, "
- " error %d", pp->dev, errno);
- }
-@@ -752,6 +808,9 @@ cciss_sysfs_pathinfo (struct path * pp)
- static int
- common_sysfs_pathinfo (struct path * pp)
- {
-+ if (!pp)
-+ return 1;
-+
- if (!pp->udev) {
- condlog(4, "%s: udev not initialised", pp->dev);
- return 1;
-@@ -793,7 +852,8 @@ path_offline (struct path * pp)
- return PATH_DOWN;
- }
-
-- if (sysfs_get_state(parent, buff, SCSI_STATE_SIZE))
-+ memset(buff, 0x0, SCSI_STATE_SIZE);
-+ if (sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE) <= 0)
- return PATH_DOWN;
-
- condlog(3, "%s: path state = %s", pp->dev, buff);
-@@ -983,6 +1043,9 @@ pathinfo (struct path *pp, vector hwtabl
- {
- int path_state;
-
-+ if (!pp)
-+ return 1;
-+
- condlog(3, "%s: mask = 0x%x", pp->dev, mask);
-
- /*
-Index: multipath-tools-130222/libmultipath/sysfs.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/sysfs.c
-+++ multipath-tools-130222/libmultipath/sysfs.c
-@@ -38,7 +38,12 @@
- #include "debug.h"
- #include "devmapper.h"
-
--ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name,
-+/*
-+ * When we modify an attribute value we cannot rely on libudev for now,
-+ * as libudev lacks the capability to update an attribute value.
-+ * So for modified attributes we need to implement our own function.
-+ */
-+ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name,
- char * value, size_t value_len)
- {
- char devpath[PATH_SIZE];
-@@ -54,28 +59,83 @@ ssize_t sysfs_attr_set_value(struct udev
- condlog(4, "open '%s'", devpath);
- if (stat(devpath, &statbuf) != 0) {
- condlog(4, "stat '%s' failed: %s", devpath, strerror(errno));
-- return 0;
-+ return -errno;
- }
-
- /* skip directories */
-- if (S_ISDIR(statbuf.st_mode))
-- return 0;
-+ if (S_ISDIR(statbuf.st_mode)) {
-+ condlog(4, "%s is a directory", devpath);
-+ return -EISDIR;
-+ }
-
- /* skip non-writeable files */
-- if ((statbuf.st_mode & S_IWUSR) == 0)
-+ if ((statbuf.st_mode & S_IRUSR) == 0) {
-+ condlog(4, "%s is not readable", devpath);
-+ return -EPERM;
-+ }
-+
-+ /* read attribute value */
-+ fd = open(devpath, O_RDONLY);
-+ if (fd < 0) {
-+ condlog(4, "attribute '%s' can not be opened: %s",
-+ devpath, strerror(errno));
-+ return -errno;
-+ }
-+ size = read(fd, value, value_len);
-+ if (size < 0) {
-+ condlog(4, "read from %s failed: %s", devpath, strerror(errno));
-+ size = -errno;
-+ } else if (size == value_len) {
-+ condlog(4, "overflow while reading from %s", devpath);
-+ size = 0;
-+ }
-+
-+ close(fd);
-+ return size;
-+}
-+
-+ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name,
-+ char * value, size_t value_len)
-+{
-+ char devpath[PATH_SIZE];
-+ struct stat statbuf;
-+ int fd;
-+ ssize_t size = -1;
-+
-+ if (!dev || !attr_name || !value || !value_len)
- return 0;
-
-+ snprintf(devpath, PATH_SIZE, "%s/%s", udev_device_get_syspath(dev),
-+ attr_name);
-+ condlog(4, "open '%s'", devpath);
-+ if (stat(devpath, &statbuf) != 0) {
-+ condlog(4, "stat '%s' failed: %s", devpath, strerror(errno));
-+ return -errno;
-+ }
-+
-+ /* skip directories */
-+ if (S_ISDIR(statbuf.st_mode)) {
-+ condlog(4, "%s is a directory", devpath);
-+ return -EISDIR;
-+ }
-+
-+ /* skip non-writeable files */
-+ if ((statbuf.st_mode & S_IWUSR) == 0) {
-+ condlog(4, "%s is not writeable", devpath);
-+ return -EPERM;
-+ }
-+
- /* write attribute value */
- fd = open(devpath, O_WRONLY);
- if (fd < 0) {
- condlog(4, "attribute '%s' can not be opened: %s",
- devpath, strerror(errno));
-- return 0;
-+ return -errno;
- }
- size = write(fd, value, value_len);
- if (size < 0) {
- condlog(4, "write to %s failed: %s", devpath, strerror(errno));
-- size = 0;
-+ size = -errno;
- } else if (size < value_len) {
- condlog(4, "tried to write %ld to %s. Wrote %ld",
- (long)value_len, devpath, (long)size);
-@@ -89,14 +149,14 @@ ssize_t sysfs_attr_set_value(struct udev
- int
- sysfs_get_size (struct path *pp, unsigned long long * size)
- {
-- const char * attr;
-+ char attr[255];
- int r;
-
-- if (!pp->udev)
-+ if (!pp->udev || !size)
- return 1;
-
-- attr = udev_device_get_sysattr_value(pp->udev, "size");
-- if (!attr) {
-+ attr[0] = '\0';
-+ if (sysfs_attr_get_value(pp->udev, "size", attr, 255) == 0) {
- condlog(3, "%s: No size attribute in sysfs", pp->dev);
- return 1;
- }
-@@ -104,8 +164,8 @@ sysfs_get_size (struct path *pp, unsigne
- r = sscanf(attr, "%llu\n", size);
-
- if (r != 1) {
-- condlog(3, "%s: Cannot parse size attribute '%s'",
-- pp->dev, attr);
-+ condlog(3, "%s: Cannot parse size attribute", pp->dev);
-+ *size = 0;
- return 1;
- }
-
-Index: multipath-tools-130222/libmultipath/sysfs.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/sysfs.h
-+++ multipath-tools-130222/libmultipath/sysfs.h
-@@ -7,6 +7,8 @@
-
- ssize_t sysfs_attr_set_value(struct udev_device *dev, const char *attr_name,
- char * value, size_t value_len);
-+ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name,
-+ char * value, size_t value_len);
- int sysfs_get_size (struct path *pp, unsigned long long * size);
- int sysfs_check_holders(char * check_devt, char * new_devt);
- #endif
+++ /dev/null
----
- libmultipath/dict.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -2562,7 +2562,7 @@ snprint_def_failback (char * buff, int l
- if (!pgfailback)
- pgfailback = DEFAULT_FAILBACK;
-
-- switch(conf->pgfailback) {
-+ switch(pgfailback) {
- case FAILBACK_UNDEF:
- break;
- case -FAILBACK_MANUAL:
+++ /dev/null
----
- libmultipath/devmapper.c | 21 +++++++++++++++++----
- libmultipath/devmapper.h | 2 +-
- 2 files changed, 18 insertions(+), 5 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -363,7 +363,7 @@ out:
- }
-
- extern int
--dm_get_map(char * name, unsigned long long * size, char * outparams)
-+dm_get_map(const char * name, unsigned long long * size, char * outparams)
- {
- int r = 1;
- struct dm_task *dmt;
-@@ -682,7 +682,9 @@ _dm_flush_map (const char * mapname, int
- extern int
- dm_suspend_and_flush_map (const char * mapname)
- {
-- int s;
-+ int s = 0, queue_if_no_path = 0;
-+ unsigned long long mapsize;
-+ char params[PARAMS_SIZE] = {0};
-
- if (!dm_map_present(mapname))
- return 0;
-@@ -690,8 +692,17 @@ dm_suspend_and_flush_map (const char * m
- if (dm_type(mapname, TGT_MPATH) <= 0)
- return 0; /* nothing to do */
-
-- s = dm_queue_if_no_path((char *)mapname, 0);
-- if (!s)
-+ if (!dm_get_map(mapname, &mapsize, params)) {
-+ if (strstr(params, "queue_if_no_path"))
-+ queue_if_no_path = 1;
-+ }
-+
-+ if (queue_if_no_path)
-+ s = dm_queue_if_no_path((char *)mapname, 0);
-+ /* Leave queue_if_no_path alone if unset failed */
-+ if (s)
-+ queue_if_no_path = 0;
-+ else
- s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0);
-
- if (!dm_flush_map(mapname)) {
-@@ -700,6 +711,8 @@ dm_suspend_and_flush_map (const char * m
- }
- condlog(2, "failed to remove multipath map %s", mapname);
- dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname);
-+ if (queue_if_no_path)
-+ s = dm_queue_if_no_path((char *)mapname, 1);
- return 1;
- }
-
-Index: multipath-tools-130222/libmultipath/devmapper.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.h
-+++ multipath-tools-130222/libmultipath/devmapper.h
-@@ -14,7 +14,7 @@ int dm_simplecmd_noflush (int, const cha
- int dm_addmap_create (struct multipath *mpp, char *params);
- int dm_addmap_reload (struct multipath *mpp, char *params);
- int dm_map_present (const char *);
--int dm_get_map(char *, unsigned long long *, char *);
-+int dm_get_map(const char *, unsigned long long *, char *);
- int dm_get_status(char *, char *);
- int dm_type(const char *, char *);
- int _dm_flush_map (const char *, int);
+++ /dev/null
----
- libmultipath/uevent.c | 17 ++++++++++++-----
- libmultipath/uevent.h | 4 +++-
- multipathd/main.c | 8 +++++---
- 3 files changed, 20 insertions(+), 9 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/uevent.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/uevent.c
-+++ multipath-tools-130222/libmultipath/uevent.c
-@@ -47,7 +47,6 @@
- #include "list.h"
- #include "uevent.h"
- #include "vector.h"
--#include "config.h"
-
- typedef int (uev_trigger)(struct uevent *, void * trigger_data);
-
-@@ -127,11 +126,14 @@ service_uevq(struct list_head *tmpq)
-
- static void uevq_stop(void *arg)
- {
-+ struct udev *udev = arg;
-+
- condlog(3, "Stopping uev queue");
- pthread_mutex_lock(uevq_lockp);
- my_uev_trigger = NULL;
- pthread_cond_signal(uev_condp);
- pthread_mutex_unlock(uevq_lockp);
-+ udev_unref(udev);
- }
-
- void
-@@ -399,9 +401,9 @@ exit:
- return 1;
- }
-
--int uevent_listen(void)
-+int uevent_listen(struct udev *udev)
- {
-- int err;
-+ int err = 2;
- struct udev_monitor *monitor = NULL;
- int fd, socket_flags;
- int need_failback = 1;
-@@ -411,9 +413,14 @@ int uevent_listen(void)
- * thereby not getting to empty the socket's receive buffer queue
- * often enough.
- */
-- pthread_cleanup_push(uevq_stop, NULL);
-+ if (!udev) {
-+ condlog(1, "no udev context");
-+ return 1;
-+ }
-+ udev_ref(udev);
-+ pthread_cleanup_push(uevq_stop, udev);
-
-- monitor = udev_monitor_new_from_netlink(conf->udev, "udev");
-+ monitor = udev_monitor_new_from_netlink(udev, "udev");
- if (!monitor) {
- condlog(2, "failed to create udev monitor");
- goto out;
-Index: multipath-tools-130222/libmultipath/uevent.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/uevent.h
-+++ multipath-tools-130222/libmultipath/uevent.h
-@@ -13,6 +13,8 @@
- #define NETLINK_KOBJECT_UEVENT 15
- #endif
-
-+struct udev;
-+
- struct uevent {
- struct list_head node;
- struct udev_device *udev;
-@@ -27,7 +29,7 @@ struct uevent {
- int is_uevent_busy(void);
- void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached);
-
--int uevent_listen(void);
-+int uevent_listen(struct udev *udev);
- int uevent_dispatch(int (*store_uev)(struct uevent *, void * trigger_data),
- void * trigger_data);
- int uevent_get_major(struct uevent *uev);
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -840,7 +840,7 @@ out:
- static void *
- ueventloop (void * ap)
- {
-- if (uevent_listen())
-+ if (uevent_listen(udev))
- condlog(0, "error starting uevent listener");
-
- return NULL;
-@@ -1593,7 +1593,7 @@ static int
- child (void * param)
- {
- pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr;
-- pthread_attr_t log_attr, misc_attr;
-+ pthread_attr_t log_attr, misc_attr, uevent_attr;
- struct vectors * vecs;
- struct multipath * mpp;
- int i;
-@@ -1606,6 +1606,7 @@ child (void * param)
- udev = udev_new();
-
- setup_thread_attr(&misc_attr, 64 * 1024, 1);
-+ setup_thread_attr(&uevent_attr, 128 * 1024, 1);
- setup_thread_attr(&waiter_attr, 32 * 1024, 1);
-
- if (logsink) {
-@@ -1671,10 +1672,11 @@ child (void * param)
- /*
- * Start uevent listener early to catch events
- */
-- if ((rc = pthread_create(&uevent_thr, &misc_attr, ueventloop, vecs))) {
-+ if ((rc = pthread_create(&uevent_thr, &uevent_attr, ueventloop, udev))) {
- condlog(0, "failed to create uevent thread: %d", rc);
- exit(1);
- }
-+ pthread_attr_destroy(&uevent_attr);
- if ((rc = pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs))) {
- condlog(0, "failed to create cli listener: %d", rc);
- exit(1);
+++ /dev/null
----
- libmultipath/dict.c | 2 --
- 1 file changed, 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -2717,8 +2717,6 @@ snprint_def_log_checker_err (char * buff
- static int
- snprint_def_find_multipaths (char * buff, int len, void * data)
- {
-- if (conf->find_multipaths == DEFAULT_FIND_MULTIPATHS)
-- return 0;
- if (!conf->find_multipaths)
- return snprintf(buff, len, "no");
-
+++ /dev/null
----
- multipathd/main.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -1735,8 +1735,9 @@ child (void * param)
- vecs->pathvec = NULL;
- unlock(vecs->lock);
- /* Now all the waitevent threads will start rushing in. */
-+ /* freeing vecs isn't worth the races
- while (vecs->lock.depth > 0) {
-- sleep (1); /* This is weak. */
-+ sleep (1);
- condlog(3, "Have %d wait event checkers threads to de-alloc,"
- " waiting...", vecs->lock.depth);
- }
-@@ -1746,7 +1747,7 @@ child (void * param)
- vecs->lock.mutex = NULL;
- FREE(vecs);
- vecs = NULL;
--
-+ */
- cleanup_checkers();
- cleanup_prio();
-
+++ /dev/null
----
- kpartx/dasd.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/kpartx/dasd.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/dasd.c
-+++ multipath-tools-130222/kpartx/dasd.c
-@@ -46,6 +46,8 @@ unsigned long long sectors512(unsigned l
- return sectors * (blocksize >> 9);
- }
-
-+typedef unsigned int __attribute__((__may_alias__)) label_ints_t;
-+
- /*
- */
- int
-@@ -169,7 +171,7 @@ read_dasd_pt(int fd, struct slice all, s
- /*
- * VM style CMS1 labeled disk
- */
-- unsigned int *label = (unsigned int *) &vlabel;
-+ label_ints_t *label = (label_ints_t *) &vlabel;
-
- blocksize = label[4];
- if (label[14] != 0) {
+++ /dev/null
----
- libmultipath/defaults.h | 3 -
- libmultipath/file.c | 89 +++++++++++++++++++++++++++++++++++++++++-
- libmultipath/file.h | 3 +
- libmultipath/wwids.c | 7 ++-
- multipath/main.c | 36 +++++++++++++++-
- multipath/multipath.rules | 26 +++++++++---
- multipathd/main.c | 4 +
- multipathd/multipathd.service | 2
- multipathd/pidfile.c | 3 +
- 9 files changed, 160 insertions(+), 13 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/defaults.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/defaults.h
-+++ multipath-tools-130222/libmultipath/defaults.h
-@@ -24,7 +24,8 @@
- #define MAX_CHECKINT(a) (a << 2)
-
- #define MAX_DEV_LOSS_TMO 0x7FFFFFFF
--#define DEFAULT_PIDFILE "/var/run/multipathd.pid"
-+#define DEFAULT_PIDFILE "/var/run/multipathd/multipathd.pid"
-+#define DEFAULT_TIMESTAMP_FILE "/var/run/multipathd/timestamp"
- #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd"
- #define DEFAULT_CONFIGFILE "/etc/multipath.conf"
- #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
-Index: multipath-tools-130222/libmultipath/file.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/file.c
-+++ multipath-tools-130222/libmultipath/file.c
-@@ -12,10 +12,12 @@
- #include <limits.h>
- #include <stdio.h>
- #include <signal.h>
-+#include <time.h>
-
- #include "file.h"
- #include "debug.h"
- #include "uxsock.h"
-+#include "defaults.h"
-
-
- /*
-@@ -36,8 +38,8 @@
- * See the file COPYING included with this distribution for more details.
- */
-
--static int
--ensure_directories_exist(char *str, mode_t dir_mode)
-+int
-+ensure_directories_exist(const char *str, mode_t dir_mode)
- {
- char *pathname;
- char *end;
-@@ -178,3 +180,86 @@ fail:
- close(fd);
- return -1;
- }
-+
-+/* If you can't get the timestamp, return equal to just keep using the
-+ * existing value.
-+ */
-+int timestamp_equal(long int chk_timestamp)
-+{
-+ char buf[4096];
-+ FILE *file;
-+ long int file_timestamp;
-+ int ret = 1;
-+
-+ if ((file = fopen(DEFAULT_TIMESTAMP_FILE, "r")) == NULL) {
-+ if (errno != ENOENT)
-+ condlog(2, "Cannot open timestamp file [%s]: %s",
-+ DEFAULT_TIMESTAMP_FILE, strerror(errno));
-+ goto out;
-+ }
-+ errno = 0;
-+ if (fgets(buf, sizeof(buf), file) == NULL) {
-+ if (errno)
-+ condlog(2, "Cannot read from timestamp file: %s",
-+ strerror(errno));
-+ goto out;
-+ }
-+ if (sscanf(buf, "DM_MULTIPATH_TIMESTAMP=%ld", &file_timestamp) != 1) {
-+ if (errno)
-+ condlog(0, "Cannot get timestamp: %s", strerror(errno));
-+ else
-+ condlog(0, "invalid timestamp file [%s]: %s",
-+ DEFAULT_TIMESTAMP_FILE, strerror(errno));
-+ goto out;
-+ }
-+ if (file_timestamp != chk_timestamp) {
-+ condlog(3, "timestamp has changed");
-+ ret = 0;
-+ }
-+ else
-+ condlog(3, "timestamp has not changed");
-+out:
-+ if (file)
-+ fclose(file);
-+ return ret;
-+}
-+
-+int update_timestamp(int create)
-+{
-+ char buf[44];
-+ time_t timestamp;
-+ int fd;
-+ int flags = O_WRONLY;
-+ if (create)
-+ flags |= O_CREAT;
-+ if((fd = open(DEFAULT_TIMESTAMP_FILE, flags,
-+ (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
-+ if (errno == ENOENT)
-+ return 0;
-+ condlog(0, "Cannot open timestamp file [%s]: %s",
-+ DEFAULT_TIMESTAMP_FILE, strerror(errno));
-+ return 1;
-+ }
-+ if (ftruncate(fd, 0) < 0) {
-+ condlog(0, "Cannot truncate timestamp file [%s]: %s",
-+ DEFAULT_TIMESTAMP_FILE, strerror(errno));
-+ goto fail;
-+ }
-+ if (time(×tamp) == -1) {
-+ condlog(0, "Cannot get current time: %s", strerror(errno));
-+ goto fail;
-+ }
-+ memset(buf, 0, sizeof(buf));
-+ snprintf(buf, sizeof(buf)-1, "DM_MULTIPATH_TIMESTAMP=%ld\n",
-+ timestamp);
-+ if (write(fd, buf, strlen(buf)) != strlen(buf)) {
-+ condlog(0, "Cannot write out timestamp to %s: %s",
-+ DEFAULT_TIMESTAMP_FILE, strerror(errno));
-+ goto fail;
-+ }
-+ close(fd);
-+ return 0;
-+fail:
-+ close(fd);
-+ return 1;
-+}
-Index: multipath-tools-130222/libmultipath/file.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/file.h
-+++ multipath-tools-130222/libmultipath/file.h
-@@ -7,5 +7,8 @@
-
- #define FILE_TIMEOUT 30
- int open_file(char *file, int *can_write, char *header);
-+int ensure_directories_exist(const char *str, mode_t dir_mode);
-+int update_timestamp(int create);
-+int timestamp_equal(long int chk_timestamp);
-
- #endif /* _FILE_H */
-Index: multipath-tools-130222/multipathd/pidfile.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/pidfile.c
-+++ multipath-tools-130222/multipathd/pidfile.c
-@@ -9,6 +9,7 @@
- #include <fcntl.h> /* for fcntl() */
-
- #include <debug.h>
-+#include <file.h>
-
- #include "pidfile.h"
-
-@@ -18,6 +19,8 @@ int pidfile_create(const char *pidFile,
- struct flock lock;
- int fd, value;
-
-+ if (ensure_directories_exist(pidFile, 0700))
-+ return 1;
- if((fd = open(pidFile, O_WRONLY | O_CREAT,
- (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
- condlog(0, "Cannot open pidfile [%s], error was [%s]",
-Index: multipath-tools-130222/libmultipath/wwids.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.c
-+++ multipath-tools-130222/libmultipath/wwids.c
-@@ -125,6 +125,7 @@ replace_wwids(vector mp)
- goto out_file;
- }
- ret = 0;
-+ update_timestamp(0);
- out_file:
- close(fd);
- out:
-@@ -209,6 +210,8 @@ remove_wwid(char *wwid) {
- goto out_file;
- }
- ret = do_remove_wwid(fd, str);
-+ if (!ret)
-+ update_timestamp(0);
-
- out_file:
- close(fd);
-@@ -294,8 +297,10 @@ remember_wwid(char *wwid)
- condlog(3, "failed writing wwid %s to wwids file", wwid);
- return -1;
- }
-- if (ret == 1)
-+ if (ret == 1) {
- condlog(3, "wrote wwid %s to wwids file", wwid);
-+ update_timestamp(0);
-+ }
- else
- condlog(4, "wwid %s already in wwids file", wwid);
- return 0;
-Index: multipath-tools-130222/multipath/multipath.rules
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.rules
-+++ multipath-tools-130222/multipath/multipath.rules
-@@ -4,18 +4,34 @@ SUBSYSTEM!="block", GOTO="end_mpath"
-
- IMPORT{cmdline}="nompath"
- ENV{nompath}=="?*", GOTO="end_mpath"
-+ENV{DEVTYPE}=="partition", GOTO="end_mpath"
- ENV{MPATH_SBIN_PATH}="/sbin"
- TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
-+TEST!="/etc/multipath.conf", GOTO="check_kpartx"
-
--ACTION=="add", ENV{DEVTYPE}!="partition", \
-- ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
-- TEST=="/etc/multipath.conf", \
-+ACTION=="add", ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
- PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
-- ENV{DM_MULTIPATH_DEVICE_PATH}="1" ENV{ID_FS_TYPE}="mpath_member"
-+ ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member"
-
--ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
-+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \
- RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
-
-+ACTION!="change", GOTO="update_timestamp"
-+IMPORT{db}="DM_MULTIPATH_TIMESTAMP"
-+IMPORT{db}="DM_MULTIPATH_DEVICE_PATH"
-+# Check if the device is part of a multipath device. the -T option just keeps
-+# the old result if the timestamp hasn't changed.
-+PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -T $env{DM_MULTIPATH_TIMESTAMP}:$env{DM_MULTIPATH_DEVICE_PATH} -c $env{DEVNAME}", \
-+ ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member", \
-+ GOTO="update_timestamp"
-+
-+# If the device isn't part of a multipath device, clear this
-+ENV{DM_MULTIPATH_DEVICE_PATH}=""
-+
-+LABEL="update_timestamp"
-+IMPORT{file}="/run/multipathd/timestamp"
-+
-+LABEL="check_kpartx"
- KERNEL!="dm-*", GOTO="end_mpath"
- ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
- ACTION!="change", GOTO="end_mpath"
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -54,6 +54,7 @@
- #include <pgpolicies.h>
- #include <uevent.h>
- #include <log.h>
-+#include <file.h>
-
- #include "main.h"
- #include "pidfile.h"
-@@ -1417,6 +1418,7 @@ reconfigure (struct vectors * vecs)
- free_config(old);
- retval = 0;
- }
-+ update_timestamp(0);
-
- return retval;
- }
-@@ -1709,6 +1711,7 @@ child (void * param)
-
- /* Startup complete, create logfile */
- pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
-+ update_timestamp(1);
- /* Ignore errors, we can live without */
-
- running_state = DAEMON_RUNNING;
-@@ -1758,6 +1761,7 @@ child (void * param)
- if (!pid_rc) {
- condlog(3, "unlink pidfile");
- unlink(DEFAULT_PIDFILE);
-+ unlink(DEFAULT_TIMESTAMP_FILE);
- }
-
- condlog(2, "--------shut down-------");
-Index: multipath-tools-130222/multipathd/multipathd.service
-===================================================================
---- multipath-tools-130222.orig/multipathd/multipathd.service
-+++ multipath-tools-130222/multipathd/multipathd.service
-@@ -9,7 +9,7 @@ Conflicts=shutdown.target
-
- [Service]
- Type=forking
--PIDFile=/var/run/multipathd.pid
-+PIDFile=/var/run/multipathd/multipathd.pid
- ExecStartPre=/sbin/modprobe dm-multipath
- ExecStart=/sbin/multipathd
- ExecReload=/sbin/multipathd reconfigure
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -55,6 +55,7 @@
- #include <sys/time.h>
- #include <sys/resource.h>
- #include <wwids.h>
-+#include <file.h>
- #include "dev_t.h"
-
- int logsink;
-@@ -84,7 +85,7 @@ usage (char * progname)
- {
- fprintf (stderr, VERSION_STRING);
- fprintf (stderr, "Usage:\n");
-- fprintf (stderr, " %s [-c|-w|-W] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
-+ fprintf (stderr, " %s [-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
- fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
- fprintf (stderr, " %s -F [-v lvl]\n", progname);
- fprintf (stderr, " %s -t\n", progname);
-@@ -98,6 +99,9 @@ usage (char * progname)
- " -f flush a multipath device map\n" \
- " -F flush all multipath device maps\n" \
- " -c check if a device should be a path in a multipath device\n" \
-+ " -T tm:val\n" \
-+ " check if tm matches the multipathd timestamp. If so val is\n" \
-+ " whether or not the device is a path in a multipath device\n" \
- " -q allow queue_if_no_path when multipathd is not running\n"\
- " -d dry run, do not create or update devmaps\n" \
- " -t dump internal hardware table\n" \
-@@ -441,7 +445,31 @@ main (int argc, char *argv[])
- extern char *optarg;
- extern int optind;
- int r = 1;
--
-+ long int timestamp = -1;
-+ int valid = -1;
-+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
-+ switch(arg) {
-+ case 'T':
-+ if (optarg[0] == ':')
-+ sscanf(optarg, ":%d", &valid);
-+ else
-+ sscanf(optarg, "%ld:%d", ×tamp, &valid);
-+ if (timestamp_equal(timestamp))
-+ return (valid != 1);
-+ break;
-+ case ':':
-+ fprintf(stderr, "Missing option argument\n");
-+ usage(argv[0]);
-+ exit(1);
-+ case '?':
-+ fprintf(stderr, "Unknown switch: %s\n", optarg);
-+ usage(argv[0]);
-+ exit(1);
-+ default:
-+ break;
-+ }
-+ }
-+ optind = 1;
- if (getuid() != 0) {
- fprintf(stderr, "need to be root\n");
- exit(1);
-@@ -455,7 +483,7 @@ main (int argc, char *argv[])
- if (dm_prereq())
- exit(1);
-
-- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtqwW")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
- switch(arg) {
- case 1: printf("optarg : %s\n",optarg);
- break;
-@@ -517,6 +545,8 @@ main (int argc, char *argv[])
- case 't':
- r = dump_config();
- goto out;
-+ case 'T':
-+ break;
- case 'h':
- usage(argv[0]);
- exit(0);
+++ /dev/null
----
- libmultipath/checkers/rdac.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/checkers/rdac.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/checkers/rdac.c
-+++ multipath-tools-130222/libmultipath/checkers/rdac.c
-@@ -222,10 +222,9 @@ libcheck_check (struct checker * c)
- goto done;
- }
-
-- /* check if controller is in service mode */
-+ /* check if controller is reporting asymmetric access state of unavailable */
- if ((inq.avtcvp & 0x10) &&
-- ((inq.asym_access_state_cur & 0x0F) == 0x3) &&
-- (inq.vendor_specific_cur == 0x7)) {
-+ ((inq.asym_access_state_cur & 0x0F) == 0x3)) {
- ret = PATH_DOWN;
- goto done;
- }
+++ /dev/null
----
- kpartx/dos.c | 17 ++++++++++-------
- kpartx/gpt.c | 20 +-------------------
- kpartx/kpartx.c | 12 ++++++++++++
- kpartx/kpartx.h | 8 ++++++++
- 4 files changed, 31 insertions(+), 26 deletions(-)
-
-Index: multipath-tools-130222/kpartx/dos.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/dos.c
-+++ multipath-tools-130222/kpartx/dos.c
-@@ -26,7 +26,9 @@ read_extended_partition(int fd, struct p
- int moretodo = 1;
- int i, n=0;
-
-- next = start = le32_to_cpu(ep->start_sect);
-+ int sector_size_mul = get_sector_size(fd)/512;
-+
-+ next = start = sector_size_mul * le32_to_cpu(ep->start_sect);
-
- while (moretodo) {
- here = next;
-@@ -45,14 +47,14 @@ read_extended_partition(int fd, struct p
- memcpy(&p, bp + 0x1be + i * sizeof (p), sizeof (p));
- if (is_extended(p.sys_type)) {
- if (p.nr_sects && !moretodo) {
-- next = start + le32_to_cpu(p.start_sect);
-+ next = start + sector_size_mul * le32_to_cpu(p.start_sect);
- moretodo = 1;
- }
- continue;
- }
- if (n < ns) {
-- sp[n].start = here + le32_to_cpu(p.start_sect);
-- sp[n].size = le32_to_cpu(p.nr_sects);
-+ sp[n].start = here + sector_size_mul * le32_to_cpu(p.start_sect);
-+ sp[n].size = sector_size_mul * le32_to_cpu(p.nr_sects);
- n++;
- } else {
- fprintf(stderr,
-@@ -76,6 +78,7 @@ read_dos_pt(int fd, struct slice all, st
- unsigned long offset = all.start;
- int i, n=4;
- unsigned char *bp;
-+ int sector_size_mul = get_sector_size(fd)/512;
-
- bp = (unsigned char *)getblock(fd, offset);
- if (bp == NULL)
-@@ -89,8 +92,8 @@ read_dos_pt(int fd, struct slice all, st
- if (is_gpt(p.sys_type))
- return 0;
- if (i < ns) {
-- sp[i].start = le32_to_cpu(p.start_sect);
-- sp[i].size = le32_to_cpu(p.nr_sects);
-+ sp[i].start = sector_size_mul * le32_to_cpu(p.start_sect);
-+ sp[i].size = sector_size_mul * le32_to_cpu(p.nr_sects);
- } else {
- fprintf(stderr,
- "dos_partition: too many slices\n");
-@@ -99,7 +102,7 @@ read_dos_pt(int fd, struct slice all, st
- if (is_extended(p.sys_type)) {
- n += read_extended_partition(fd, &p, sp+n, ns-n);
- /* hide the extended partition itself */
-- sp[i].size = 2;
-+ sp[i].size = sector_size_mul * 2;
- }
- }
- return n;
-Index: multipath-tools-130222/kpartx/gpt.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/gpt.c
-+++ multipath-tools-130222/kpartx/gpt.c
-@@ -38,6 +38,7 @@
- #include <byteswap.h>
- #include <linux/fs.h>
- #include "crc32.h"
-+#include "kpartx.h"
-
- #if BYTE_ORDER == LITTLE_ENDIAN
- # define __le16_to_cpu(x) (x)
-@@ -116,25 +117,6 @@ is_pmbr_valid(legacy_mbr *mbr)
-
-
- /************************************************************
-- * get_sector_size
-- * Requires:
-- * - filedes is an open file descriptor, suitable for reading
-- * Modifies: nothing
-- * Returns:
-- * sector size, or 512.
-- ************************************************************/
--static int
--get_sector_size(int filedes)
--{
-- int rc, sector_size = 512;
--
-- rc = ioctl(filedes, BLKSSZGET, §or_size);
-- if (rc)
-- sector_size = 512;
-- return sector_size;
--}
--
--/************************************************************
- * _get_num_sectors
- * Requires:
- * - filedes is an open file descriptor, suitable for reading
-Index: multipath-tools-130222/kpartx/kpartx.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.c
-+++ multipath-tools-130222/kpartx/kpartx.c
-@@ -26,6 +26,7 @@
- #include <string.h>
- #include <unistd.h>
- #include <stdint.h>
-+#include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <ctype.h>
-@@ -606,3 +607,14 @@ getblock (int fd, unsigned int secnr) {
-
- return bp->block;
- }
-+
-+int
-+get_sector_size(int filedes)
-+{
-+ int rc, sector_size = 512;
-+
-+ rc = ioctl(filedes, BLKSSZGET, §or_size);
-+ if (rc)
-+ sector_size = 512;
-+ return sector_size;
-+}
-Index: multipath-tools-130222/kpartx/kpartx.h
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.h
-+++ multipath-tools-130222/kpartx/kpartx.h
-@@ -2,6 +2,7 @@
- #define _KPARTX_H
-
- #include <stdint.h>
-+#include <sys/ioctl.h>
-
- /*
- * For each partition type there is a routine that takes
-@@ -18,6 +19,13 @@
- #define safe_sprintf(var, format, args...) \
- snprintf(var, sizeof(var), format, ##args) >= sizeof(var)
-
-+#ifndef BLKSSZGET
-+#define BLKSSZGET _IO(0x12,104) /* get block device sector size */
-+#endif
-+
-+int
-+get_sector_size(int filedes);
-+
- /*
- * units: 512 byte sectors
- */
+++ /dev/null
----
- multipath/multipath.rules | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipath/multipath.rules
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.rules
-+++ multipath-tools-130222/multipath/multipath.rules
-@@ -13,12 +13,13 @@ ACTION=="add", ENV{DM_MULTIPATH_DEVICE_P
- PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
- ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member"
-
--ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \
-+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DM_MULTIPATH_WIPE_PARTS}="1", \
- RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
-
- ACTION!="change", GOTO="update_timestamp"
- IMPORT{db}="DM_MULTIPATH_TIMESTAMP"
- IMPORT{db}="DM_MULTIPATH_DEVICE_PATH"
-+IMPORT{db}="DM_MULTIPATH_WIPE_PARTS"
- # Check if the device is part of a multipath device. the -T option just keeps
- # the old result if the timestamp hasn't changed.
- PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -T $env{DM_MULTIPATH_TIMESTAMP}:$env{DM_MULTIPATH_DEVICE_PATH} -c $env{DEVNAME}", \
-@@ -27,8 +28,13 @@ PROGRAM=="$env{MPATH_SBIN_PATH}/multipat
-
- # If the device isn't part of a multipath device, clear this
- ENV{DM_MULTIPATH_DEVICE_PATH}=""
-+ENV{DM_MULTIPATH_WIPE_PARTS}=""
-
- LABEL="update_timestamp"
-+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DM_MULTIPATH_WIPE_PARTS}!="1", \
-+ ENV{DM_MULTIPATH_WIPE_PARTS}="1", \
-+ RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
-+
- IMPORT{file}="/run/multipathd/timestamp"
-
- LABEL="check_kpartx"
+++ /dev/null
----
- multipath/multipath.rules | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipath/multipath.rules
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.rules
-+++ multipath-tools-130222/multipath/multipath.rules
-@@ -4,7 +4,8 @@ SUBSYSTEM!="block", GOTO="end_mpath"
-
- IMPORT{cmdline}="nompath"
- ENV{nompath}=="?*", GOTO="end_mpath"
--ENV{DEVTYPE}=="partition", GOTO="end_mpath"
-+ENV{DEVTYPE}=="partition", IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH", \
-+ GOTO="end_mpath"
- ENV{MPATH_SBIN_PATH}="/sbin"
- TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
- TEST!="/etc/multipath.conf", GOTO="check_kpartx"
+++ /dev/null
----
- libmultipath/checkers/rdac.c | 91 ++++++++++++++++++++++++++++++++++++++-----
- libmultipath/discovery.c | 2
- 2 files changed, 81 insertions(+), 12 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/checkers/rdac.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/checkers/rdac.c
-+++ multipath-tools-130222/libmultipath/checkers/rdac.c
-@@ -34,6 +34,18 @@
- #define MSG_RDAC_UP "rdac checker reports path is up"
- #define MSG_RDAC_DOWN "rdac checker reports path is down"
- #define MSG_RDAC_GHOST "rdac checker reports path is ghost"
-+#define MSG_RDAC_DOWN_TYPE(STR) MSG_RDAC_DOWN": "STR
-+
-+#define RTPG_UNAVAILABLE 0x3
-+#define RTPG_OFFLINE 0xE
-+#define RTPG_TRANSITIONING 0xF
-+
-+#define RTPG_UNAVAIL_NON_RESPONSIVE 0x2
-+#define RTPG_UNAVAIL_IN_RESET 0x3
-+#define RTPG_UNAVAIL_CFW_DL1 0x4
-+#define RTPG_UNAVAIL_CFW_DL2 0x5
-+#define RTPG_UNAVAIL_QUIESCED 0x6
-+#define RTPG_UNAVAIL_SERVICE_MODE 0x7
-
- struct control_mode_page {
- unsigned char header[8];
-@@ -199,22 +211,64 @@ struct volume_access_inq
- char PQ_PDT;
- char dontcare0[7];
- char avtcvp;
-- char dontcare1;
-- char asym_access_state_cur;
-+ char vol_ppp;
-+ char aas_cur;
- char vendor_specific_cur;
-- char dontcare2[36];
-+ char aas_alt;
-+ char vendor_specific_alt;
-+ char dontcare1[34];
- };
-
-+const char
-+*checker_msg_string(struct volume_access_inq *inq)
-+{
-+ /* lun not connected */
-+ if (((inq->PQ_PDT & 0xE0) == 0x20) || (inq->PQ_PDT & 0x7f))
-+ return MSG_RDAC_DOWN_TYPE("lun not connected");
-+
-+ /* if no tpg data is available, give the generic path down message */
-+ if (!(inq->avtcvp & 0x10))
-+ return MSG_RDAC_DOWN;
-+
-+ /* controller is booting up */
-+ if (((inq->aas_cur & 0x0F) == RTPG_TRANSITIONING) &&
-+ (inq->aas_alt & 0x0F) != RTPG_TRANSITIONING)
-+ return MSG_RDAC_DOWN_TYPE("ctlr is in startup sequence");
-+
-+ /* if not unavailable, give generic message */
-+ if ((inq->aas_cur & 0x0F) != RTPG_UNAVAILABLE)
-+ return MSG_RDAC_DOWN;
-+
-+ /* target port group unavailable */
-+ switch (inq->vendor_specific_cur) {
-+ case RTPG_UNAVAIL_NON_RESPONSIVE:
-+ return MSG_RDAC_DOWN_TYPE("non-responsive to queries");
-+ case RTPG_UNAVAIL_IN_RESET:
-+ return MSG_RDAC_DOWN_TYPE("ctlr held in reset");
-+ case RTPG_UNAVAIL_CFW_DL1:
-+ case RTPG_UNAVAIL_CFW_DL2:
-+ return MSG_RDAC_DOWN_TYPE("ctlr firmware downloading");
-+ case RTPG_UNAVAIL_QUIESCED:
-+ return MSG_RDAC_DOWN_TYPE("ctlr quiesced by admin request");
-+ case RTPG_UNAVAIL_SERVICE_MODE:
-+ return MSG_RDAC_DOWN_TYPE("ctlr is in service mode");
-+ default:
-+ return MSG_RDAC_DOWN_TYPE("ctlr is unavailable");
-+ }
-+}
-+
- extern int
- libcheck_check (struct checker * c)
- {
- struct volume_access_inq inq;
-- int ret;
-+ int ret, inqfail;
-
-+ inqfail = 0;
- memset(&inq, 0, sizeof(struct volume_access_inq));
- if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq),
- c->timeout)) {
- ret = PATH_DOWN;
-+ inqfail = 1;
- goto done;
- } else if (((inq.PQ_PDT & 0xE0) == 0x20) || (inq.PQ_PDT & 0x7f)) {
- /* LUN not connected*/
-@@ -222,11 +276,27 @@ libcheck_check (struct checker * c)
- goto done;
- }
-
-- /* check if controller is reporting asymmetric access state of unavailable */
-- if ((inq.avtcvp & 0x10) &&
-- ((inq.asym_access_state_cur & 0x0F) == 0x3)) {
-- ret = PATH_DOWN;
-- goto done;
-+ /* If TPGDE bit set, evaluate TPG information */
-+ if ((inq.avtcvp & 0x10)) {
-+ switch (inq.aas_cur & 0x0F) {
-+ /* Never use the path if it reports unavailable */
-+ case RTPG_UNAVAILABLE:
-+ ret = PATH_DOWN;
-+ goto done;
-+ /*
-+ * If both controllers report transitioning, it
-+ * means mode select or STPG is being processed.
-+ *
-+ * If this controller alone is transitioning, it's
-+ * booting and we shouldn't use it yet.
-+ */
-+ case RTPG_TRANSITIONING:
-+ if ((inq.aas_alt & 0xF) != RTPG_TRANSITIONING) {
-+ ret = PATH_DOWN;
-+ goto done;
-+ }
-+ break;
-+ }
- }
-
- /* If owner set or ioship mode is enabled return PATH_UP always */
-@@ -238,7 +308,8 @@ libcheck_check (struct checker * c)
- done:
- switch (ret) {
- case PATH_DOWN:
-- MSG(c, MSG_RDAC_DOWN);
-+ MSG(c, (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
-+ checker_msg_string(&inq));
- break;
- case PATH_UP:
- MSG(c, MSG_RDAC_UP);
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -1116,8 +1116,6 @@ pathinfo (struct path *pp, vector hwtabl
- if (!strlen(pp->wwid))
- get_uid(pp);
- get_prio(pp);
-- } else {
-- pp->priority = PRIO_UNDEF;
- }
- }
-
+++ /dev/null
----
- libmultipath/blacklist.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/blacklist.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/blacklist.c
-+++ multipath-tools-130222/libmultipath/blacklist.c
-@@ -163,7 +163,7 @@ setup_default_blist (struct config * con
- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
- return 1;
-
-- str = STRDUP("^hd[a-z]");
-+ str = STRDUP("^(td|hd)[a-z]");
- if (!str)
- return 1;
- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
+++ /dev/null
----
- libmultipath/util.c | 22 ++++++++++++++++++++++
- libmultipath/util.h | 1 +
- multipath/main.c | 23 +----------------------
- multipathd/cli_handlers.c | 18 ++++++++++++++++++
- 4 files changed, 42 insertions(+), 22 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/util.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/util.c
-+++ multipath-tools-130222/libmultipath/util.c
-@@ -236,6 +236,28 @@ skip_proc:
- return 0;
- }
-
-+/* This function returns a pointer inside of the supplied pathname string.
-+ * If is_path_device is true, it may also modify the supplied string */
-+char *convert_dev(char *name, int is_path_device)
-+{
-+ char *ptr;
-+
-+ if (!name)
-+ return NULL;
-+ if (is_path_device) {
-+ ptr = strstr(name, "cciss/");
-+ if (ptr) {
-+ ptr += 5;
-+ *ptr = '!';
-+ }
-+ }
-+ if (!strncmp(name, "/dev/", 5) && strlen(name) > 5)
-+ ptr = name + 5;
-+ else
-+ ptr = name;
-+ return ptr;
-+}
-+
- dev_t parse_devt(const char *dev_t)
- {
- int maj, min;
-Index: multipath-tools-130222/libmultipath/util.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/util.h
-+++ multipath-tools-130222/libmultipath/util.h
-@@ -10,6 +10,7 @@ size_t strlcat(char *dst, const char *sr
- void remove_trailing_chars(char *path, char c);
- int devt2devname (char *, int, char *);
- dev_t parse_devt(const char *dev_t);
-+char *convert_dev(char *dev, int is_path_device);
-
- #define safe_sprintf(var, format, args...) \
- snprintf(var, sizeof(var), format, ##args) >= sizeof(var)
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -254,16 +254,7 @@ configure (void)
- vecs.pathvec = pathvec;
- vecs.mpvec = curmp;
-
-- /*
-- * dev is "/dev/" . "sysfs block dev"
-- */
-- if (conf->dev) {
-- if (!strncmp(conf->dev, "/dev/", 5) &&
-- strlen(conf->dev) > 5)
-- dev = conf->dev + 5;
-- else
-- dev = conf->dev;
-- }
-+ dev = convert_dev(conf->dev, (conf->dev_type == DEV_DEVNODE));
-
- /*
- * if we have a blacklisted device parameter, exit early
-@@ -427,16 +418,6 @@ get_dev_type(char *dev) {
- return DEV_DEVMAP;
- }
-
--static void
--convert_dev(char *dev)
--{
-- char *ptr = strstr(dev, "cciss/");
-- if (ptr) {
-- ptr += 5;
-- *ptr = '!';
-- }
--}
--
- int
- main (int argc, char *argv[])
- {
-@@ -577,8 +558,6 @@ main (int argc, char *argv[])
-
- strncpy(conf->dev, argv[optind], FILE_NAME_SIZE);
- conf->dev_type = get_dev_type(conf->dev);
-- if (conf->dev_type == DEV_DEVNODE)
-- convert_dev(conf->dev);
- }
- conf->daemon = 0;
-
-Index: multipath-tools-130222/multipathd/cli_handlers.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli_handlers.c
-+++ multipath-tools-130222/multipathd/cli_handlers.c
-@@ -235,6 +235,7 @@ cli_list_map_topology (void * v, char **
- struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
-
-+ param = convert_dev(param, 0);
- get_path_layout(vecs->pathvec, 0);
- mpp = find_mp_by_str(vecs->mpvec, param);
-
-@@ -416,6 +417,7 @@ cli_add_path (void * v, char ** reply, i
- struct path *pp;
- int r;
-
-+ param = convert_dev(param, 1);
- condlog(2, "%s: add path (operator)", param);
-
- if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
-@@ -459,6 +461,7 @@ cli_del_path (void * v, char ** reply, i
- char * param = get_keyparam(v, PATH);
- struct path *pp;
-
-+ param = convert_dev(param, 1);
- condlog(2, "%s: remove path (operator)", param);
- pp = find_path_by_dev(vecs->pathvec, param);
- if (!pp) {
-@@ -478,6 +481,7 @@ cli_add_map (void * v, char ** reply, in
- char *alias;
- int rc;
-
-+ param = convert_dev(param, 0);
- condlog(2, "%s: add map (operator)", param);
-
- if (filter_wwid(conf->blist_wwid, conf->elist_wwid, param) > 0) {
-@@ -518,6 +522,7 @@ cli_del_map (void * v, char ** reply, in
- char *alias;
- int rc;
-
-+ param = convert_dev(param, 0);
- condlog(2, "%s: remove map (operator)", param);
- minor = dm_get_minor(param);
- if (minor < 0) {
-@@ -549,6 +554,7 @@ cli_reload(void *v, char **reply, int *l
- struct multipath *mpp;
- int minor;
-
-+ mapname = convert_dev(mapname, 0);
- condlog(2, "%s: reload map (operator)", mapname);
- if (sscanf(mapname, "dm-%d", &minor) == 1)
- mpp = find_mp_by_minor(vecs->mpvec, minor);
-@@ -591,6 +597,7 @@ cli_resize(void *v, char **reply, int *l
- struct pathgroup *pgp;
- struct path *pp;
-
-+ mapname = convert_dev(mapname, 0);
- condlog(2, "%s: resize map (operator)", mapname);
- if (sscanf(mapname, "dm-%d", &minor) == 1)
- mpp = find_mp_by_minor(vecs->mpvec, minor);
-@@ -665,6 +672,7 @@ cli_restore_queueing(void *v, char **rep
- struct multipath *mpp;
- int minor;
-
-+ mapname = convert_dev(mapname, 0);
- condlog(2, "%s: restore map queueing (operator)", mapname);
- if (sscanf(mapname, "dm-%d", &minor) == 1)
- mpp = find_mp_by_minor(vecs->mpvec, minor);
-@@ -716,6 +724,7 @@ cli_disable_queueing(void *v, char **rep
- struct multipath *mpp;
- int minor;
-
-+ mapname = convert_dev(mapname, 0);
- condlog(2, "%s: disable map queueing (operator)", mapname);
- if (sscanf(mapname, "dm-%d", &minor) == 1)
- mpp = find_mp_by_minor(vecs->mpvec, minor);
-@@ -753,6 +762,7 @@ cli_switch_group(void * v, char ** reply
- char * mapname = get_keyparam(v, MAP);
- int groupnum = atoi(get_keyparam(v, GROUP));
-
-+ mapname = convert_dev(mapname, 0);
- condlog(2, "%s: switch to path group #%i (operator)", mapname, groupnum);
-
- return dm_switchgroup(mapname, groupnum);
-@@ -775,6 +785,7 @@ cli_suspend(void * v, char ** reply, int
- char * param = get_keyparam(v, MAP);
- int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param);
-
-+ param = convert_dev(param, 0);
- condlog(2, "%s: suspend (operator)", param);
-
- if (!r) /* error */
-@@ -796,6 +807,7 @@ cli_resume(void * v, char ** reply, int
- char * param = get_keyparam(v, MAP);
- int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param);
-
-+ param = convert_dev(param, 0);
- condlog(2, "%s: resume (operator)", param);
-
- if (!r) /* error */
-@@ -817,6 +829,7 @@ cli_reinstate(void * v, char ** reply, i
- char * param = get_keyparam(v, PATH);
- struct path * pp;
-
-+ param = convert_dev(param, 1);
- pp = find_path_by_dev(vecs->pathvec, param);
-
- if (!pp)
-@@ -837,6 +850,7 @@ cli_reassign (void * v, char ** reply, i
- {
- char * param = get_keyparam(v, MAP);
-
-+ param = convert_dev(param, 0);
- condlog(3, "%s: reset devices (operator)", param);
-
- dm_reassign(param);
-@@ -851,6 +865,7 @@ cli_fail(void * v, char ** reply, int *
- struct path * pp;
- int r;
-
-+ param = convert_dev(param, 1);
- pp = find_path_by_dev(vecs->pathvec, param);
-
- if (!pp)
-@@ -962,6 +977,7 @@ cli_getprstatus (void * v, char ** reply
- struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
-
-+ param = convert_dev(param, 0);
- get_path_layout(vecs->pathvec, 0);
- mpp = find_mp_by_str(vecs->mpvec, param);
-
-@@ -991,6 +1007,7 @@ cli_setprstatus(void * v, char ** reply,
- struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
-
-+ param = convert_dev(param, 0);
- get_path_layout(vecs->pathvec, 0);
- mpp = find_mp_by_str(vecs->mpvec, param);
-
-@@ -1013,6 +1030,7 @@ cli_unsetprstatus(void * v, char ** repl
- struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
-
-+ param = convert_dev(param, 0);
- get_path_layout(vecs->pathvec, 0);
- mpp = find_mp_by_str(vecs->mpvec, param);
-
+++ /dev/null
----
- kpartx/lopart.c | 18 ++++++++++++++++--
- 1 file changed, 16 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/kpartx/lopart.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/lopart.c
-+++ multipath-tools-130222/kpartx/lopart.c
-@@ -32,6 +32,10 @@
- #include "lopart.h"
- #include "xstrncpy.h"
-
-+#ifndef LOOP_CTL_GET_FREE
-+#define LOOP_CTL_GET_FREE 0x4C82
-+#endif
-+
- #if !defined (__alpha__) && !defined (__ia64__) && !defined (__x86_64__) \
- && !defined (__s390x__)
- #define int2ptr(x) ((void *) ((int) x))
-@@ -140,14 +144,24 @@ find_unused_loop_device (void)
-
- char dev[20];
- char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
-- int i, j, fd, somedev = 0, someloop = 0, loop_known = 0;
-+ int i, j, fd, first = 0, somedev = 0, someloop = 0, loop_known = 0;
- struct stat statbuf;
- struct loop_info loopinfo;
- FILE *procdev;
-
-+ if (stat("/dev/loop-control", &statbuf) == 0 &&
-+ S_ISCHR(statbuf.st_mode)) {
-+ fd = open("/dev/loop-control", O_RDWR);
-+ if (fd >= 0) {
-+ first = ioctl(fd, LOOP_CTL_GET_FREE);
-+ close(fd);
-+ }
-+ if (first < 0)
-+ first = 0;
-+ }
- for (j = 0; j < SIZE(loop_formats); j++) {
-
-- for(i = 0; i < 256; i++) {
-+ for(i = first; i < 256; i++) {
- sprintf(dev, loop_formats[j], i);
-
- if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
+++ /dev/null
----
- Makefile.inc | 2 +-
- libmultipath/checkers/rdac.c | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/Makefile.inc
-===================================================================
---- multipath-tools-130222.orig/Makefile.inc
-+++ multipath-tools-130222/Makefile.inc
-@@ -39,7 +39,7 @@ GZIP = /bin/gzip -9 -c
- INSTALL_PROGRAM = install
-
- ifndef RPM_OPT_FLAGS
-- RPM_OPT_FLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4
-+ RPM_OPT_FLAGS = -O2 -g -pipe -Wformat-security -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4
- endif
-
- LDFLAGS += -Wl,-z,relro
-Index: multipath-tools-130222/libmultipath/checkers/rdac.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/checkers/rdac.c
-+++ multipath-tools-130222/libmultipath/checkers/rdac.c
-@@ -308,8 +308,8 @@ libcheck_check (struct checker * c)
- done:
- switch (ret) {
- case PATH_DOWN:
-- MSG(c, (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
-- checker_msg_string(&inq));
-+ MSG(c, "%s", (inqfail) ? MSG_RDAC_DOWN_TYPE("inquiry failed") :
-+ checker_msg_string(&inq));
- break;
- case PATH_UP:
- MSG(c, MSG_RDAC_UP);
+++ /dev/null
----
- multipath/11-dm-mpath.rules | 34 ++++++++++++++++++++++++++++++++++
- multipath/Makefile | 2 ++
- 2 files changed, 36 insertions(+)
-
-Index: multipath-tools-130222/multipath/11-dm-mpath.rules
-===================================================================
---- /dev/null
-+++ multipath-tools-130222/multipath/11-dm-mpath.rules
-@@ -0,0 +1,34 @@
-+ACTION!="add|change", GOTO="mpath_end"
-+ENV{DM_UDEV_RULES_VSN}!="?*", GOTO="mpath_end"
-+ENV{DM_UUID}!="mpath-?*", GOTO="mpath_end"
-+
-+# Do not initiate scanning if no path is available,
-+# otherwise there would be a hang or IO error on access.
-+# We'd like to avoid this, especially within udev processing.
-+ENV{DM_NR_VALID_PATHS}!="?*", IMPORT{db}="DM_NR_VALID_PATHS"
-+ENV{DM_NR_VALID_PATHS}=="0", ENV{DM_NOSCAN}="1"
-+
-+# Also skip all foreign rules if no path is available.
-+# Remember the original value of DM_DISABLE_OTHER_RULES_FLAG
-+# and restore it back once we have at least one path available.
-+IMPORT{db}="DM_DISABLE_OTHER_RULES_FLAG_OLD"
-+ENV{DM_ACTION}=="PATH_FAILED",\
-+ ENV{DM_NR_VALID_PATHS}=="0",\
-+ ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}=="",\
-+ ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="$env{DM_UDEV_DISABLE_OTHER_RULES_FLAG}",\
-+ ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
-+ENV{DM_ACTION}=="PATH_REINSTATED",\
-+ ENV{DM_NR_VALID_PATHS}=="1",\
-+ ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\
-+ ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\
-+ ENV{DM_ACTIVATION}="1"
-+
-+# DM_SUBSYSTEM_UDEV_FLAG0 is the "RELOAD" flag for multipath subsystem.
-+# Drop the DM_ACTIVATION flag here as mpath reloads tables if any of its
-+# paths are lost/recovered. For any stack above the mpath device, this is not
-+# something that should be reacted upon since it would be useless extra work.
-+# It's exactly mpath's job to provide *seamless* device access to any of the
-+# paths that are available underneath.
-+ENV{DM_SUBSYSTEM_UDEV_FLAG0}=="1", ENV{DM_ACTIVATION}="0"
-+
-+LABEL="mpath_end"
-Index: multipath-tools-130222/multipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/multipath/Makefile
-+++ multipath-tools-130222/multipath/Makefile
-@@ -25,6 +25,7 @@ install:
- $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
- $(INSTALL_PROGRAM) -d $(DESTDIR)/usr/lib/udev/rules.d
- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
-+ $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)/usr/lib/udev/rules.d/11-dm-mpath.rules
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
- $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
-@@ -33,6 +34,7 @@ install:
-
- uninstall:
- rm $(DESTDIR)/usr/lib/udev/rules.d/62-multipath.rules
-+ rm $(DESTDIR)/usr/lib/udev/rules.d/11-dm-mpath.rules
- rm $(DESTDIR)$(bindir)/$(EXEC)
- rm $(DESTDIR)$(bindir)/mpathconf
- rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
+++ /dev/null
----
- kpartx/devmapper.c | 4 ++--
- kpartx/devmapper.h | 8 +++++++-
- kpartx/kpartx.c | 6 +++---
- libmultipath/configure.c | 4 ++--
- libmultipath/devmapper.c | 26 ++++++++++++++------------
- libmultipath/devmapper.h | 10 ++++++++--
- multipathd/cli_handlers.c | 4 ++--
- 7 files changed, 38 insertions(+), 24 deletions(-)
-
-Index: multipath-tools-130222/kpartx/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/devmapper.c
-+++ multipath-tools-130222/kpartx/devmapper.c
-@@ -60,7 +60,7 @@ dm_prereq (char * str, int x, int y, int
- }
-
- extern int
--dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie) {
-+dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie, uint16_t udev_flags) {
- int r = 0;
- int udev_wait_flag = (task == DM_DEVICE_RESUME ||
- task == DM_DEVICE_REMOVE);
-@@ -78,7 +78,7 @@ dm_simplecmd (int task, const char *name
- if (no_flush)
- dm_task_no_flush(dmt);
-
-- if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, (udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK))
-+ if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, ((udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK) | udev_flags))
- goto out;
- r = dm_task_run(dmt);
-
-Index: multipath-tools-130222/kpartx/devmapper.h
-===================================================================
---- multipath-tools-130222.orig/kpartx/devmapper.h
-+++ multipath-tools-130222/kpartx/devmapper.h
-@@ -2,10 +2,16 @@
- #define MINOR(dev) ((dev & 0xff) | ((dev >> 12) & 0xfff00))
- #define MKDEV(ma,mi) ((mi & 0xff) | (ma << 8) | ((mi & ~0xff) << 12))
-
-+#ifdef DM_SUBSYSTEM_UDEV_FLAG0
-+#define MPATH_UDEV_RELOAD_FLAG DM_SUBSYSTEM_UDEV_FLAG0
-+#else
-+#define MPATH_UDEV_RELOAD_FLAG 0
-+#endif
-+
- extern int udev_sync;
-
- int dm_prereq (char *, int, int, int);
--int dm_simplecmd (int, const char *, int, uint32_t *);
-+int dm_simplecmd (int, const char *, int, uint32_t *, uint16_t);
- int dm_addmap (int, const char *, const char *, const char *, uint64_t,
- int, const char *, int, mode_t, uid_t, gid_t, uint32_t *);
- int dm_map_present (char *);
-Index: multipath-tools-130222/kpartx/kpartx.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/kpartx.c
-+++ multipath-tools-130222/kpartx/kpartx.c
-@@ -421,7 +421,7 @@ main(int argc, char **argv){
- continue;
-
- if (!dm_simplecmd(DM_DEVICE_REMOVE, partname,
-- 0, &cookie)) {
-+ 0, &cookie, 0)) {
- r++;
- continue;
- }
-@@ -473,7 +473,7 @@ main(int argc, char **argv){
- }
- if (op == DM_DEVICE_RELOAD &&
- !dm_simplecmd(DM_DEVICE_RESUME, partname,
-- 1, &cookie)) {
-+ 1, &cookie, MPATH_UDEV_RELOAD_FLAG)) {
- fprintf(stderr, "resume failed on %s\n",
- partname);
- r++;
-@@ -505,7 +505,7 @@ main(int argc, char **argv){
- continue;
-
- if (!dm_simplecmd(DM_DEVICE_REMOVE,
-- partname, 1, &cookie)) {
-+ partname, 1, &cookie, 0)) {
- r++;
- continue;
- }
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -390,13 +390,13 @@ domap (struct multipath * mpp, char * pa
- case ACT_RELOAD:
- r = dm_addmap_reload(mpp, params);
- if (r)
-- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias);
-+ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, MPATH_UDEV_RELOAD_FLAG);
- break;
-
- case ACT_RESIZE:
- r = dm_addmap_reload(mpp, params);
- if (r)
-- r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1);
-+ r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1, 0);
- break;
-
- case ACT_RENAME:
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -103,7 +103,9 @@ dm_lib_prereq (void)
- {
- char version[64];
- int v[3];
--#ifdef LIBDM_API_COOKIE
-+#if defined(DM_SUBSYSTEM_UDEV_FLAG0)
-+ int minv[3] = {1, 2, 82};
-+#elif defined(LIBDM_API_COOKIE)
- int minv[3] = {1, 2, 38};
- #else
- int minv[3] = {1, 2, 8};
-@@ -200,7 +202,7 @@ dm_prereq (void)
- }
-
- static int
--dm_simplecmd (int task, const char *name, int no_flush, int need_sync) {
-+dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags) {
- int r = 0;
- int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME ||
- task == DM_DEVICE_REMOVE));
-@@ -219,7 +221,7 @@ dm_simplecmd (int task, const char *name
- dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */
- #endif
-
-- if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0))
-+ if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags))
- goto out;
- r = dm_task_run (dmt);
-
-@@ -229,13 +231,13 @@ dm_simplecmd (int task, const char *name
- }
-
- extern int
--dm_simplecmd_flush (int task, const char *name, int needsync) {
-- return dm_simplecmd(task, name, 0, needsync);
-+dm_simplecmd_flush (int task, const char *name, int needsync, uint16_t udev_flags) {
-+ return dm_simplecmd(task, name, 0, needsync, udev_flags);
- }
-
- extern int
--dm_simplecmd_noflush (int task, const char *name) {
-- return dm_simplecmd(task, name, 1, 1);
-+dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) {
-+ return dm_simplecmd(task, name, 1, 1, udev_flags);
- }
-
- extern int
-@@ -670,7 +672,7 @@ _dm_flush_map (const char * mapname, int
- return 1;
- }
-
-- r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname, need_sync);
-+ r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname, need_sync, 0);
-
- if (r) {
- condlog(4, "multipath map %s removed", mapname);
-@@ -703,14 +705,14 @@ dm_suspend_and_flush_map (const char * m
- if (s)
- queue_if_no_path = 0;
- else
-- s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0);
-+ s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0, 0);
-
- if (!dm_flush_map(mapname)) {
- condlog(4, "multipath map %s removed", mapname);
- return 0;
- }
- condlog(2, "failed to remove multipath map %s", mapname);
-- dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname);
-+ dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 0);
- if (queue_if_no_path)
- s = dm_queue_if_no_path((char *)mapname, 1);
- return 1;
-@@ -1077,7 +1079,7 @@ dm_remove_partmaps (const char * mapname
- condlog(4, "partition map %s removed",
- names->name);
- dm_simplecmd_flush(DM_DEVICE_REMOVE, names->name,
-- need_sync);
-+ need_sync, 0);
- }
-
- next = names->next;
-@@ -1305,7 +1307,7 @@ int dm_reassign_table(const char *name,
- condlog(3, "%s: failed to reassign targets", name);
- goto out_reload;
- }
-- dm_simplecmd_noflush(DM_DEVICE_RESUME, name);
-+ dm_simplecmd_noflush(DM_DEVICE_RESUME, name, MPATH_UDEV_RELOAD_FLAG);
- }
- r = 1;
-
-Index: multipath-tools-130222/libmultipath/devmapper.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.h
-+++ multipath-tools-130222/libmultipath/devmapper.h
-@@ -6,11 +6,17 @@
- #define TGT_MPATH "multipath"
- #define TGT_PART "linear"
-
-+#ifdef DM_SUBSYSTEM_UDEV_FLAG0
-+#define MPATH_UDEV_RELOAD_FLAG DM_SUBSYSTEM_UDEV_FLAG0
-+#else
-+#define MPATH_UDEV_RELOAD_FLAG 0
-+#endif
-+
- void dm_init(void);
- int dm_prereq (void);
- int dm_drv_version (unsigned int * version, char * str);
--int dm_simplecmd_flush (int, const char *, int);
--int dm_simplecmd_noflush (int, const char *);
-+int dm_simplecmd_flush (int, const char *, int, uint16_t);
-+int dm_simplecmd_noflush (int, const char *, uint16_t);
- int dm_addmap_create (struct multipath *mpp, char *params);
- int dm_addmap_reload (struct multipath *mpp, char *params);
- int dm_map_present (const char *);
-Index: multipath-tools-130222/multipathd/cli_handlers.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/cli_handlers.c
-+++ multipath-tools-130222/multipathd/cli_handlers.c
-@@ -783,7 +783,7 @@ cli_suspend(void * v, char ** reply, int
- {
- struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
-- int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param);
-+ int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0);
-
- param = convert_dev(param, 0);
- condlog(2, "%s: suspend (operator)", param);
-@@ -805,7 +805,7 @@ cli_resume(void * v, char ** reply, int
- {
- struct vectors * vecs = (struct vectors *)data;
- char * param = get_keyparam(v, MAP);
-- int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param);
-+ int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
-
- param = convert_dev(param, 0);
- condlog(2, "%s: resume (operator)", param);
+++ /dev/null
----
- libmultipath/config.c | 10 ++++++++--
- libmultipath/config.h | 1 +
- libmultipath/dict.c | 28 ++++++++++++++++++++++++++++
- multipath/multipath.conf.5 | 11 +++++++++++
- 4 files changed, 48 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -431,11 +431,16 @@ restart:
- break;
- j = n;
- vector_foreach_slot_after(hw, hwe2, j) {
-- if (hwe_regmatch(hwe1, hwe2))
-+ if (conf->hw_strmatch) {
-+ if (hwe_strmatch(hwe2, hwe1))
-+ continue;
-+ }
-+ else if (hwe_regmatch(hwe1, hwe2))
- continue;
- /* dup */
- merge_hwe(hwe2, hwe1);
-- if (hwe_strmatch(hwe2, hwe1) == 0) {
-+ if (conf->hw_strmatch ||
-+ hwe_strmatch(hwe2, hwe1) == 0) {
- vector_del_slot(hw, i);
- free_hwe(hwe1);
- n -= 1;
-@@ -550,6 +555,7 @@ load_config (char * file, struct udev *u
- conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
- conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
- conf->detect_prio = DEFAULT_DETECT_PRIO;
-+ conf->hw_strmatch = 0;
-
- /*
- * preload default hwtable
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -107,6 +107,7 @@ struct config {
- int log_checker_err;
- int allow_queueing;
- int find_multipaths;
-+ int hw_strmatch;
- uid_t uid;
- gid_t gid;
- mode_t mode;
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -693,6 +693,25 @@ def_detect_prio_handler(vector strvec)
- return 0;
- }
-
-+static int
-+def_hw_strmatch_handler(vector strvec)
-+{
-+ char *buff;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
-+ !strncmp(buff, "1", 1))
-+ conf->hw_strmatch = 1;
-+ else
-+ conf->hw_strmatch = 0;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * blacklist block handlers
- */
-@@ -2795,6 +2814,14 @@ snprint_def_detect_prio(char * buff, int
- }
-
- static int
-+snprint_def_hw_strmatch(char * buff, int len, void * data)
-+{
-+ if (conf->hw_strmatch)
-+ return snprintf(buff, len, "yes");
-+ return snprintf(buff, len, "no");
-+}
-+
-+static int
- snprint_ble_simple (char * buff, int len, void * data)
- {
- struct blentry * ble = (struct blentry *)data;
-@@ -2861,6 +2888,7 @@ init_keywords(void)
- install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
- install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
- install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
-+ install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
- __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);
-Index: multipath-tools-130222/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.conf.5
-+++ multipath-tools-130222/multipath/multipath.conf.5
-@@ -400,6 +400,17 @@ will automatically use the
- .I alua
- prioritizer. If not, the prioritizer will be selected as usual. Default is
- .I no
-+.TP
-+.B hw_str_match
-+If set to
-+.I yes
-+, the vendor, product, and revision parameters of user device configs will be
-+string matched against the built-in device configs to determine if they should
-+modify an existing config, or create a new one. If set to
-+.I no
-+, the user device configs will be regular expression matched against the
-+built-in configs instead. Default is
-+.I no
- .
- .SH "blacklist section"
- The
+++ /dev/null
----
- multipath/mpathconf.8 | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipath/mpathconf.8
-===================================================================
---- multipath-tools-130222.orig/multipath/mpathconf.8
-+++ multipath-tools-130222/multipath/mpathconf.8
-@@ -86,7 +86,7 @@ If set to \fBy\fP, this runs
- .B service multipathd start
- to start the multipathd daemon on \fB--enable\fP,
- .B service multipathd stop
--to start the multipathd daemon on \fB--disable\fP, and
-+to stop the multipathd daemon on \fB--disable\fP, and
- .B service multipathd reload
- to reconfigure multipathd on \fB--user_frindly_names\fP and
- \fB--find_multipaths\fP.
+++ /dev/null
----
- multipath/main.c | 19 ++++++++++++++++---
- multipath/multipath.8 | 5 ++++-
- 2 files changed, 20 insertions(+), 4 deletions(-)
-
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -85,7 +85,7 @@ usage (char * progname)
- {
- fprintf (stderr, VERSION_STRING);
- fprintf (stderr, "Usage:\n");
-- fprintf (stderr, " %s [-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
-+ fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
- fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
- fprintf (stderr, " %s -F [-v lvl]\n", progname);
- fprintf (stderr, " %s -t\n", progname);
-@@ -98,6 +98,7 @@ usage (char * progname)
- " -ll show multipath topology (maximum info)\n" \
- " -f flush a multipath device map\n" \
- " -F flush all multipath device maps\n" \
-+ " -a add a device wwid to the wwids file\n" \
- " -c check if a device should be a path in a multipath device\n" \
- " -T tm:val\n" \
- " check if tm matches the multipathd timestamp. If so val is\n" \
-@@ -292,6 +293,15 @@ configure (void)
- }
- goto out;
- }
-+ if (conf->dry_run == 5) {
-+ r = remember_wwid(refwwid);
-+ if (r == 0)
-+ printf("wwid '%s' added\n", refwwid);
-+ else
-+ printf("failed adding '%s' to wwids file\n",
-+ refwwid);
-+ goto out;
-+ }
- condlog(3, "scope limited to %s", refwwid);
- if (conf->dry_run == 2) {
- if (check_wwids_file(refwwid, 0) == 0){
-@@ -428,7 +438,7 @@ main (int argc, char *argv[])
- int r = 1;
- long int timestamp = -1;
- int valid = -1;
-- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
- switch(arg) {
- case 'T':
- if (optarg[0] == ':')
-@@ -464,7 +474,7 @@ main (int argc, char *argv[])
- if (dm_prereq())
- exit(1);
-
-- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
- switch(arg) {
- case 1: printf("optarg : %s\n",optarg);
- break;
-@@ -537,6 +547,9 @@ main (int argc, char *argv[])
- case 'W':
- conf->dry_run = 4;
- break;
-+ case 'a':
-+ conf->dry_run = 5;
-+ break;
- case ':':
- fprintf(stderr, "Missing option argument\n");
- usage(argv[0]);
-Index: multipath-tools-130222/multipath/multipath.8
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.8
-+++ multipath-tools-130222/multipath/multipath.8
-@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
- .RB [\| \-b\ \c
- .IR bindings_file \|]
- .RB [\| \-d \|]
--.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w | \-W \|]
-+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-w | \-W \|]
- .RB [\| \-p\ \c
- .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
- .RB [\| device \|]
-@@ -68,6 +68,9 @@ check if a block device should be a path
- .B \-q
- allow device tables with queue_if_no_path when multipathd is not running
- .TP
-+.B \-a
-+add the wwid for the specified device to the wwids file
-+.TP
- .B \-w
- remove the wwid for the specified device from the wwids file
- .TP
+++ /dev/null
----
- libmultipath/wwids.c | 44 ++++++++++++++++++++++++++++++++++++++++++
- libmultipath/wwids.h | 1
- multipath/main.c | 12 ++++++++---
- multipath/multipath.8 | 5 +++-
- multipathd/multipathd.service | 1
- 5 files changed, 59 insertions(+), 4 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/wwids.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.c
-+++ multipath-tools-130222/libmultipath/wwids.c
-@@ -305,3 +305,47 @@ remember_wwid(char *wwid)
- condlog(4, "wwid %s already in wwids file", wwid);
- return 0;
- }
-+
-+int remember_cmdline_wwid(void)
-+{
-+ FILE *f = NULL;
-+ char buf[LINE_MAX], *next, *ptr;
-+ int ret = 0;
-+
-+ f = fopen("/proc/cmdline", "re");
-+ if (!f) {
-+ condlog(0, "can't open /proc/cmdline : %s", strerror(errno));
-+ return -1;
-+ }
-+
-+ if (!fgets(buf, sizeof(buf), f)) {
-+ if (ferror(f))
-+ condlog(0, "read of /proc/cmdline failed : %s",
-+ strerror(errno));
-+ else
-+ condlog(0, "couldn't read /proc/cmdline");
-+ fclose(f);
-+ return -1;
-+ }
-+ fclose(f);
-+ next = buf;
-+ while((ptr = strstr(next, "mpath.wwid="))) {
-+ ptr += 11;
-+ next = strpbrk(ptr, " \t\n");
-+ if (next) {
-+ *next = '\0';
-+ next++;
-+ }
-+ if (strlen(ptr)) {
-+ if (remember_wwid(ptr) != 0)
-+ ret = -1;
-+ }
-+ else {
-+ condlog(0, "empty mpath.wwid kernel command line option");
-+ ret = -1;
-+ }
-+ if (!next)
-+ break;
-+ }
-+ return ret;
-+}
-Index: multipath-tools-130222/libmultipath/wwids.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.h
-+++ multipath-tools-130222/libmultipath/wwids.h
-@@ -17,5 +17,6 @@ int remember_wwid(char *wwid);
- int check_wwids_file(char *wwid, int write_wwid);
- int remove_wwid(char *wwid);
- int replace_wwids(vector mp);
-+int remember_cmdline_wwid(void);
-
- #endif /* _WWIDS_H */
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -85,7 +85,7 @@ usage (char * progname)
- {
- fprintf (stderr, VERSION_STRING);
- fprintf (stderr, "Usage:\n");
-- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
-+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
- fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
- fprintf (stderr, " %s -F [-v lvl]\n", progname);
- fprintf (stderr, " %s -t\n", progname);
-@@ -99,6 +99,8 @@ usage (char * progname)
- " -f flush a multipath device map\n" \
- " -F flush all multipath device maps\n" \
- " -a add a device wwid to the wwids file\n" \
-+ " -A add devices from kernel command line mpath.wwids\n"
-+ " parameters to wwids file\n" \
- " -c check if a device should be a path in a multipath device\n" \
- " -T tm:val\n" \
- " check if tm matches the multipathd timestamp. If so val is\n" \
-@@ -438,7 +440,7 @@ main (int argc, char *argv[])
- int r = 1;
- long int timestamp = -1;
- int valid = -1;
-- while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
- switch(arg) {
- case 'T':
- if (optarg[0] == ':')
-@@ -474,7 +476,7 @@ main (int argc, char *argv[])
- if (dm_prereq())
- exit(1);
-
-- while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
- switch(arg) {
- case 1: printf("optarg : %s\n",optarg);
- break;
-@@ -538,6 +540,10 @@ main (int argc, char *argv[])
- goto out;
- case 'T':
- break;
-+ case 'A':
-+ if (remember_cmdline_wwid() != 0)
-+ exit(1);
-+ exit(0);
- case 'h':
- usage(argv[0]);
- exit(0);
-Index: multipath-tools-130222/multipathd/multipathd.service
-===================================================================
---- multipath-tools-130222.orig/multipathd/multipathd.service
-+++ multipath-tools-130222/multipathd/multipathd.service
-@@ -11,6 +11,7 @@ Conflicts=shutdown.target
- Type=forking
- PIDFile=/var/run/multipathd/multipathd.pid
- ExecStartPre=/sbin/modprobe dm-multipath
-+ExecStartPre=-/sbin/multipath -A
- ExecStart=/sbin/multipathd
- ExecReload=/sbin/multipathd reconfigure
- #ExecStop=/path/to/scrip delete-me if not necessary
-Index: multipath-tools-130222/multipath/multipath.8
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.8
-+++ multipath-tools-130222/multipath/multipath.8
-@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
- .RB [\| \-b\ \c
- .IR bindings_file \|]
- .RB [\| \-d \|]
--.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-w | \-W \|]
-+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-A | \-w | \-W \|]
- .RB [\| \-p\ \c
- .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
- .RB [\| device \|]
-@@ -71,6 +71,9 @@ allow device tables with queue_if_no_pat
- .B \-a
- add the wwid for the specified device to the wwids file
- .TP
-+.B \-A
-+add wwids from any kernel command line mpath.wwid parameters to the wwids file
-+.TP
- .B \-w
- remove the wwid for the specified device from the wwids file
- .TP
+++ /dev/null
----
- libmultipath/devmapper.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -1151,6 +1151,8 @@ dm_rename_partmaps (char * old, char * n
- unsigned long long size;
- char dev_t[32];
- int r = 1;
-+ int offset;
-+ char *delim;
-
- if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
- return 1;
-@@ -1171,6 +1173,11 @@ dm_rename_partmaps (char * old, char * n
- if (dm_dev_t(old, &dev_t[0], 32))
- goto out;
-
-+ if (isdigit(new[strlen(new)-1]))
-+ delim = "p";
-+ else
-+ delim = "";
-+
- do {
- if (
- /*
-@@ -1198,8 +1205,9 @@ dm_rename_partmaps (char * old, char * n
- * then it's a kpartx generated partition.
- * Rename it.
- */
-- snprintf(buff, PARAMS_SIZE, "%s%s",
-- new, names->name + strlen(old));
-+ for (offset = strlen(old); names->name[offset] && !(isdigit(names->name[offset])); offset++); /* do nothing */
-+ snprintf(buff, PARAMS_SIZE, "%s%s%s",
-+ new, delim, names->name + offset);
- dm_rename(names->name, buff);
- condlog(4, "partition map %s renamed",
- names->name);
+++ /dev/null
----
- libmultipath/checkers/tur.c | 9 +++------
- 1 file changed, 3 insertions(+), 6 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/checkers/tur.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/checkers/tur.c
-+++ multipath-tools-130222/libmultipath/checkers/tur.c
-@@ -409,7 +409,6 @@ libcheck_check (struct checker * c)
- ct->running = 0;
- MSG(c, MSG_TUR_TIMEOUT);
- tur_status = PATH_DOWN;
-- ct->state = PATH_UNCHECKED;
- } else {
- condlog(3, "%d:%d: tur checker not finished",
- TUR_DEVT(ct));
-@@ -426,12 +425,10 @@ libcheck_check (struct checker * c)
- pthread_mutex_unlock(&ct->lock);
- } else {
- if (ct->thread) {
-- /* pthread cancel failed. continue in sync mode */
- pthread_mutex_unlock(&ct->lock);
-- condlog(3, "%d:%d: tur thread not responding, "
-- "using sync mode", TUR_DEVT(ct));
-- return tur_check(c->fd, c->timeout, c->message,
-- ct->wwid);
-+ condlog(3, "%d:%d: tur thread not responding, ",
-+ TUR_DEVT(ct));
-+ return PATH_DOWN;
- }
- /* Start new TUR checker */
- ct->state = PATH_UNCHECKED;
+++ /dev/null
----
- libmultipath/structs_vec.c | 31 +++++++++++++++++++++++++++----
- multipathd/main.c | 4 ++++
- 2 files changed, 31 insertions(+), 4 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/structs_vec.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs_vec.c
-+++ multipath-tools-130222/libmultipath/structs_vec.c
-@@ -280,12 +280,38 @@ update_multipath_status (struct multipat
- return 0;
- }
-
-+void sync_paths(struct multipath *mpp, vector pathvec)
-+{
-+ struct path *pp;
-+ struct pathgroup *pgp;
-+ int found, i, j;
-+
-+ vector_foreach_slot (mpp->paths, pp, i) {
-+ found = 0;
-+ vector_foreach_slot(mpp->pg, pgp, j) {
-+ if (find_slot(pgp->paths, (void *)pp) != -1) {
-+ found = 1;
-+ break;
-+ }
-+ }
-+ if (!found) {
-+ condlog(3, "%s dropped path %s", mpp->alias, pp->dev);
-+ vector_del_slot(mpp->paths, i--);
-+ orphan_path(pp);
-+ }
-+ }
-+ update_mpp_paths(mpp, pathvec);
-+ vector_foreach_slot (mpp->paths, pp, i)
-+ pp->mpp = mpp;
-+}
-+
- extern int
- update_multipath_strings (struct multipath *mpp, vector pathvec)
- {
- if (!mpp)
- return 1;
-
-+ update_mpp_paths(mpp, pathvec);
- condlog(4, "%s: %s", mpp->alias, __FUNCTION__);
-
- free_multipath_attributes(mpp);
-@@ -294,6 +320,7 @@ update_multipath_strings (struct multipa
-
- if (update_multipath_table(mpp, pathvec))
- return 1;
-+ sync_paths(mpp, pathvec);
-
- if (update_multipath_status(mpp))
- return 1;
-@@ -494,13 +521,9 @@ int update_multipath (struct vectors *ve
- return 2;
- }
-
-- free_pgvec(mpp->pg, KEEP_PATHS);
-- mpp->pg = NULL;
--
- if (__setup_multipath(vecs, mpp, reset))
- return 1; /* mpp freed in setup_multipath */
-
-- adopt_paths(vecs->pathvec, mpp, 0);
- /*
- * compare checkers states with DM states
- */
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -1152,6 +1152,10 @@ check_path (struct vectors * vecs, struc
- pp->dev);
- pp->dmstate = PSTATE_UNDEF;
- }
-+ /* if update_multipath_strings orphaned the path, quit early */
-+ if (!pp->mpp)
-+ return;
-+
- pp->chkrstate = newstate;
- if (newstate != pp->state) {
- int oldstate = pp->state;
+++ /dev/null
----
- libmultipath/prioritizers/alua.c | 4 ++--
- multipathd/multipathd.8 | 37 +++++++++++++++++++++++++++++++++----
- 2 files changed, 35 insertions(+), 6 deletions(-)
-
-Index: multipath-tools-130222/multipathd/multipathd.8
-===================================================================
---- multipath-tools-130222.orig/multipathd/multipathd.8
-+++ multipath-tools-130222/multipathd/multipathd.8
-@@ -42,6 +42,9 @@ format wildcards.
- .B list|show maps|multipaths
- Show the multipath devices that the multipathd is monitoring.
- .TP
-+.B list|show daemon
-+Show the current state of the multipathd daemon
-+.TP
- .B list|show maps|multipaths format $format
- Show the status of all multipath devices that the multipathd is monitoring,
- using a format string with multipath format wildcards.
-@@ -83,16 +86,16 @@ Add a path to the list of monitored path
- .B remove|del path $path
- Stop monitoring a path. $path is as listed in /sys/block (e.g. sda).
- .TP
--.B add map $map
-+.B add map|multipath $map
- Add a multipath device to the list of monitored devices. $map can either be a device-mapper device as listed in /sys/block (e.g. dm-0) or it can be the alias for the multipath device (e.g. mpath1) or the uid of the multipath device (e.g. 36005076303ffc56200000000000010aa).
- .TP
--.B remove|del map $map
-+.B remove|del map|multipath $map
- Stop monitoring a multipath device.
- .TP
- .B resize map|multipath $map
- Resizes map $map to the given size
- .TP
--.B switch|switchgroup map $map group $group
-+.B switch|switchgroup map|multipath $map group $group
- Force a multipath device to switch to a specific path group. $group is the path group index, starting with 1.
- .TP
- .B reconfigure
-@@ -104,6 +107,13 @@ Sets map $map into suspend state.
- .B resume map|multipath $map
- Resumes map $map from suspend state.
- .TP
-+.B reset map|multipath $map
-+Reassign existing device-mapper table(s) use use the multipath device, instead
-+of its path devices.
-+.TP
-+.B reload map|multipath $map
-+Reload a multipath device.
-+.TP
- .B fail path $path
- Sets path $path into failed state.
- .TP
-@@ -120,10 +130,29 @@ Restore queueing on all multipath device
- Disable queuing on multipathed map $map
- .TP
- .B restorequeueing map|multipath $map
--Restore queuing on multipahted map $map
-+Restore queuing on multipathed map $map
-+.TP
-+.B forcequeueing daemon
-+Forces multipathd into queue_without_daemon mode, so that no_path_retry queueing
-+will not be disabled when the daemon stops
-+.TP
-+.B restorequeueing daemon
-+Restores configured queue_without_daemon mode
-+.TP
-+.B map|multipath $map setprstatus
-+Enable persistent reservation management on $map
-+.TP
-+.B map|multipath $map unsetprstatus
-+Disable persistent reservation management on $map
-+.TP
-+.B map|multipath $map getprstatus
-+Get the current persistent reservation management status of $map
- .TP
- .B quit|exit
- End interactive session.
-+.TP
-+.B shutdown
-+Stop multipathd.
-
- .SH "SEE ALSO"
- .BR multipath (8)
-Index: multipath-tools-130222/libmultipath/prioritizers/alua.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c
-+++ multipath-tools-130222/libmultipath/prioritizers/alua.c
-@@ -119,10 +119,10 @@ int getprio (struct path * pp, char * ar
- condlog(0, "%s: couldn't get target port group", pp->dev);
- break;
- case ALUA_PRIO_GETAAS_FAILED:
-- condlog(0, "%s: couln't get asymmetric access state", pp->dev);
-+ condlog(0, "%s: couldn't get asymmetric access state", pp->dev);
- break;
- case ALUA_PRIO_TPGS_FAILED:
-- condlog(3, "%s: couln't get supported alua states", pp->dev);
-+ condlog(3, "%s: couldn't get supported alua states", pp->dev);
- break;
- }
- }
+++ /dev/null
----
- libmultipath/hwtable.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/hwtable.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/hwtable.c
-+++ multipath-tools-130222/libmultipath/hwtable.c
-@@ -1108,6 +1108,19 @@ static struct hwentry default_hw[] = {
- .prio_name = PRIO_ALUA,
- .prio_args = NULL,
- },
-+ {
-+ .vendor = "DataCore",
-+ .product = "Virtual Disk",
-+ .features = DEFAULT_FEATURES,
-+ .hwhandler = DEFAULT_HWHANDLER,
-+ .pgpolicy = GROUP_BY_PRIO,
-+ .pgfailback = -FAILBACK_IMMEDIATE,
-+ .rr_weight = RR_WEIGHT_NONE,
-+ .no_path_retry = NO_PATH_RETRY_QUEUE,
-+ .checker_name = TUR,
-+ .prio_name = PRIO_ALUA,
-+ .prio_args = NULL,
-+ },
- /*
- * EOL
- */
+++ /dev/null
----
- multipathd/main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -562,7 +562,7 @@ rescan:
- return 0;
- }
- else
-- return 1;
-+ goto fail;
-
- fail_map:
- remove_map(mpp, vecs, 1);
+++ /dev/null
----
- libmultipath/parser.c | 154 ++++++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 126 insertions(+), 28 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/parser.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/parser.c
-+++ multipath-tools-130222/libmultipath/parser.c
-@@ -395,36 +395,57 @@ set_value(vector strvec)
- char *alloc = NULL;
- char *tmp;
-
-- if (!str)
-+ if (!str) {
-+ condlog(0, "option '%s' missing value",
-+ (char *)VECTOR_SLOT(strvec, 0));
- return NULL;
--
-+ }
- size = strlen(str);
-- if (size == 0)
-+ if (size == 0) {
-+ condlog(0, "option '%s' has empty value",
-+ (char *)VECTOR_SLOT(strvec, 0));
- return NULL;
--
-- if (*str == '"') {
-- for (i = 2; i < VECTOR_SIZE(strvec); i++) {
-- str = VECTOR_SLOT(strvec, i);
-- len += strlen(str);
-- if (!alloc)
-- alloc =
-- (char *) MALLOC(sizeof (char *) *
-- (len + 1));
-- else {
-- alloc =
-- REALLOC(alloc, sizeof (char *) * (len + 1));
-- tmp = VECTOR_SLOT(strvec, i-1);
-- if (alloc && *str != '"' && *tmp != '"')
-- strncat(alloc, " ", 1);
-- }
--
-- if (alloc && i != VECTOR_SIZE(strvec)-1)
-- strncat(alloc, str, strlen(str));
-- }
-- } else {
-- alloc = MALLOC(sizeof (char *) * (size + 1));
-+ }
-+ if (*str != '"') {
-+ alloc = MALLOC(sizeof (char) * (size + 1));
- if (alloc)
- memcpy(alloc, str, size);
-+ else
-+ condlog(0, "can't allocate memeory for option '%s'",
-+ (char *)VECTOR_SLOT(strvec, 0));
-+ return alloc;
-+ }
-+ /* Even empty quotes counts as a value (An empty string) */
-+ alloc = (char *) MALLOC(sizeof (char));
-+ if (!alloc) {
-+ condlog(0, "can't allocate memeory for option '%s'",
-+ (char *)VECTOR_SLOT(strvec, 0));
-+ return NULL;
-+ }
-+ for (i = 2; i < VECTOR_SIZE(strvec); i++) {
-+ str = VECTOR_SLOT(strvec, i);
-+ if (!str) {
-+ free(alloc);
-+ condlog(0, "parse error for option '%s'",
-+ (char *)VECTOR_SLOT(strvec, 0));
-+ return NULL;
-+ }
-+ if (*str == '"')
-+ break;
-+ tmp = alloc;
-+ /* The first +1 is for the NULL byte. The rest are for the
-+ * spaces between words */
-+ len += strlen(str) + 1;
-+ alloc = REALLOC(alloc, sizeof (char) * len);
-+ if (!alloc) {
-+ FREE(tmp);
-+ condlog(0, "can't allocate memeory for option '%s'",
-+ (char *)VECTOR_SLOT(strvec, 0));
-+ return NULL;
-+ }
-+ if (*alloc != '\0')
-+ strncat(alloc, " ", 1);
-+ strncat(alloc, str, strlen(str));
- }
- return alloc;
- }
-@@ -465,6 +486,74 @@ void free_uniques(vector uniques)
- }
-
- int
-+is_sublevel_keyword(char *str)
-+{
-+ return (strcmp(str, "defaults") == 0 || strcmp(str, "blacklist") == 0 ||
-+ strcmp(str, "blacklist_exceptions") == 0 ||
-+ strcmp(str, "devices") == 0 || strcmp(str, "devices") == 0 ||
-+ strcmp(str, "device") == 0 || strcmp(str, "multipaths") == 0 ||
-+ strcmp(str, "multipath") == 0);
-+}
-+
-+int
-+validate_config_strvec(vector strvec)
-+{
-+ char *str;
-+ int i;
-+
-+ str = VECTOR_SLOT(strvec, 0);
-+ if (str == NULL) {
-+ condlog(0, "can't parse option on line %d of config file",
-+ line_nr);
-+ return -1;
-+ }
-+ if (*str == '}') {
-+ if (VECTOR_SIZE(strvec) > 1)
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr);
-+ return 0;
-+ }
-+ if (*str == '{') {
-+ condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr);
-+ return -1;
-+ }
-+ if (is_sublevel_keyword(str)) {
-+ str = VECTOR_SLOT(strvec, 1);
-+ if (str == NULL)
-+ condlog(0, "missing '{' on line %d of config file", line_nr);
-+ else if (*str != '{')
-+ condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str);
-+ else if (VECTOR_SIZE(strvec) > 2)
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
-+ return 0;
-+ }
-+ str = VECTOR_SLOT(strvec, 1);
-+ if (str == NULL) {
-+ condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr);
-+ return -1;
-+ }
-+ if (*str != '"') {
-+ if (VECTOR_SIZE(strvec) > 2)
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
-+ return 0;
-+ }
-+ for (i = 2; i < VECTOR_SIZE(strvec); i++) {
-+ str = VECTOR_SLOT(strvec, i);
-+ if (str == NULL) {
-+ condlog(0, "can't parse value on line %d of config file", line_nr);
-+ return -1;
-+ }
-+ if (*str == '"') {
-+ if (VECTOR_SIZE(strvec) > i + 1)
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr);
-+ return 0;
-+ }
-+ }
-+ condlog(0, "missing closing quotes on line %d of config file",
-+ line_nr);
-+ return 0;
-+}
-+
-+int
- process_stream(vector keywords)
- {
- int i;
-@@ -494,11 +583,20 @@ process_stream(vector keywords)
- if (!strvec)
- continue;
-
-+ if (validate_config_strvec(strvec) != 0) {
-+ free_strvec(strvec);
-+ continue;
-+ }
-+
- str = VECTOR_SLOT(strvec, 0);
-
-- if (!strcmp(str, EOB) && kw_level > 0) {
-- free_strvec(strvec);
-- break;
-+ if (!strcmp(str, EOB)) {
-+ if (kw_level > 0) {
-+ free_strvec(strvec);
-+ break;
-+ }
-+ condlog(0, "unmatched '%s' at line %d of config file",
-+ EOB, line_nr);
- }
-
- for (i = 0; i < VECTOR_SIZE(keywords); i++) {
+++ /dev/null
----
- libmultipath/prio.c | 7 +++++++
- libmultipath/prio.h | 1 +
- libmultipath/prioritizers/alua_rtpg.c | 5 +++--
- libmultipath/prioritizers/emc.c | 2 +-
- libmultipath/prioritizers/hds.c | 2 +-
- libmultipath/prioritizers/hp_sw.c | 2 +-
- libmultipath/prioritizers/ontap.c | 4 ++--
- libmultipath/prioritizers/rdac.c | 2 +-
- multipath.conf.annotated | 5 +++--
- multipath/multipath.conf.5 | 4 ++--
- 10 files changed, 22 insertions(+), 12 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/prio.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prio.c
-+++ multipath-tools-130222/libmultipath/prio.c
-@@ -10,6 +10,13 @@
-
- static LIST_HEAD(prioritizers);
-
-+unsigned int get_prio_timeout(unsigned int default_timeout)
-+{
-+ if (conf->checker_timeout)
-+ return conf->checker_timeout * 1000;
-+ return default_timeout;
-+}
-+
- int init_prio (void)
- {
- if (!add_prio(DEFAULT_PRIO))
-Index: multipath-tools-130222/libmultipath/prio.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prio.h
-+++ multipath-tools-130222/libmultipath/prio.h
-@@ -51,6 +51,7 @@ struct prio {
- int (*getprio)(struct path *, char *);
- };
-
-+unsigned int get_prio_timeout(unsigned int default_timeout);
- int init_prio (void);
- void cleanup_prio (void);
- struct prio * add_prio (char *);
-Index: multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/alua_rtpg.c
-+++ multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c
-@@ -21,6 +21,7 @@
- #define __user
- #include <scsi/sg.h>
-
-+#include "../prio.h"
- #include "alua_rtpg.h"
-
- #define SENSE_BUFF_LEN 32
-@@ -134,7 +135,7 @@ do_inquiry(int fd, int evpd, unsigned in
- hdr.dxfer_len = resplen;
- hdr.sbp = sense;
- hdr.mx_sb_len = sizeof(sense);
-- hdr.timeout = DEF_TIMEOUT;
-+ hdr.timeout = get_prio_timeout(DEF_TIMEOUT);
-
- if (ioctl(fd, SG_IO, &hdr) < 0) {
- PRINT_DEBUG("do_inquiry: IOCTL failed!\n");
-@@ -253,7 +254,7 @@ do_rtpg(int fd, void* resp, long resplen
- hdr.dxfer_len = resplen;
- hdr.mx_sb_len = sizeof(sense);
- hdr.sbp = sense;
-- hdr.timeout = DEF_TIMEOUT;
-+ hdr.timeout = get_prio_timeout(DEF_TIMEOUT);
-
- if (ioctl(fd, SG_IO, &hdr) < 0)
- return -RTPG_RTPG_FAILED;
-Index: multipath-tools-130222/libmultipath/prioritizers/emc.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/emc.c
-+++ multipath-tools-130222/libmultipath/prioritizers/emc.c
-@@ -31,7 +31,7 @@ int emc_clariion_prio(const char *dev, i
- io_hdr.dxferp = sense_buffer;
- io_hdr.cmdp = inqCmdBlk;
- io_hdr.sbp = sb;
-- io_hdr.timeout = 60000;
-+ io_hdr.timeout = get_prio_timeout(60000);
- io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- pp_emc_log(0, "sending query command failed");
-Index: multipath-tools-130222/libmultipath/prioritizers/hds.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/hds.c
-+++ multipath-tools-130222/libmultipath/prioritizers/hds.c
-@@ -114,7 +114,7 @@ int hds_modular_prio (const char *dev, i
- io_hdr.dxferp = inqBuff;
- io_hdr.cmdp = inqCmdBlk;
- io_hdr.sbp = sense_buffer;
-- io_hdr.timeout = 2000; /* TimeOut = 2 seconds */
-+ io_hdr.timeout = get_prio_timeout(2000); /* TimeOut = 2 seconds */
-
- if (ioctl (fd, SG_IO, &io_hdr) < 0) {
- pp_hds_log(0, "SG_IO error");
-Index: multipath-tools-130222/libmultipath/prioritizers/hp_sw.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/hp_sw.c
-+++ multipath-tools-130222/libmultipath/prioritizers/hp_sw.c
-@@ -46,7 +46,7 @@ int hp_sw_prio(const char *dev, int fd)
- io_hdr.dxfer_direction = SG_DXFER_NONE;
- io_hdr.cmdp = turCmdBlk;
- io_hdr.sbp = sb;
-- io_hdr.timeout = 60000;
-+ io_hdr.timeout = get_prio_timeout(60000);
- io_hdr.pack_id = 0;
- retry:
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
-Index: multipath-tools-130222/libmultipath/prioritizers/ontap.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/ontap.c
-+++ multipath-tools-130222/libmultipath/prioritizers/ontap.c
-@@ -89,7 +89,7 @@ static int send_gva(const char *dev, int
- io_hdr.dxferp = results;
- io_hdr.cmdp = cdb;
- io_hdr.sbp = sb;
-- io_hdr.timeout = SG_TIMEOUT;
-+ io_hdr.timeout = get_prio_timeout(SG_TIMEOUT);
- io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- pp_ontap_log(0, "SG_IO ioctl failed, errno=%d", errno);
-@@ -141,7 +141,7 @@ static int get_proxy(const char *dev, in
- io_hdr.dxferp = results;
- io_hdr.cmdp = cdb;
- io_hdr.sbp = sb;
-- io_hdr.timeout = SG_TIMEOUT;
-+ io_hdr.timeout = get_prio_timeout(SG_TIMEOUT);
- io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- pp_ontap_log(0, "ioctl sending inquiry command failed, "
-Index: multipath-tools-130222/libmultipath/prioritizers/rdac.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/rdac.c
-+++ multipath-tools-130222/libmultipath/prioritizers/rdac.c
-@@ -31,7 +31,7 @@ int rdac_prio(const char *dev, int fd)
- io_hdr.dxferp = sense_buffer;
- io_hdr.cmdp = inqCmdBlk;
- io_hdr.sbp = sb;
-- io_hdr.timeout = 60000;
-+ io_hdr.timeout = get_prio_timeout(60000);
- io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- pp_rdac_log(0, "sending inquiry command failed");
-Index: multipath-tools-130222/multipath.conf.annotated
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.annotated
-+++ multipath-tools-130222/multipath.conf.annotated
-@@ -188,8 +188,9 @@
- # #
- # # name : checker_timeout
- # # scope : multipath & multipathd
--# # desc : The timeout to use for path checkers that issue scsi
--# # commands with an explicit timeout, in seconds.
-+# # desc : The timeout to use for path checkers and prioritizers
-+# # that issue scsi commands with an explicit timeout, in
-+# # seconds.
- # # values : n > 0
- # # default : taken from /sys/block/sd<x>/device/timeout
- # checker_timeout 60
-Index: multipath-tools-130222/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.conf.5
-+++ multipath-tools-130222/multipath/multipath.conf.5
-@@ -321,8 +321,8 @@ maximum number of open fds is taken from
- if that number is greated than 1024.
- .TP
- .B checker_timeout
--Specify the timeout to user for path checkers that issue scsi commands with an
--explicit timeout, in seconds; default taken from
-+Specify the timeout to use for path checkers and prioritizers that issue scsi
-+commands with an explicit timeout, in seconds; default taken from
- .I /sys/block/sd<x>/device/timeout
- .TP
- .B fast_io_fail_tmo
+++ /dev/null
----
- libmultipath/config.c | 1 +
- libmultipath/config.h | 1 +
- libmultipath/dict.c | 33 +++++++++++++++++++++++++++++++++
- libmultipath/discovery.c | 8 ++++++--
- multipath.conf.annotated | 10 ++++++++++
- multipath/multipath.conf.5 | 9 +++++++++
- 6 files changed, 60 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -556,6 +556,7 @@ load_config (char * file, struct udev *u
- conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
- conf->detect_prio = DEFAULT_DETECT_PRIO;
- conf->hw_strmatch = 0;
-+ conf->force_sync = 0;
-
- /*
- * preload default hwtable
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -115,6 +115,7 @@ struct config {
- int reassign_maps;
- int retain_hwhandler;
- int detect_prio;
-+ int force_sync;
- unsigned int version[3];
-
- char * dev;
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -712,6 +712,29 @@ def_hw_strmatch_handler(vector strvec)
- return 0;
- }
-
-+static int
-+def_force_sync_handler(vector strvec)
-+{
-+ char * buff;
-+
-+ buff = set_value(strvec);
-+
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ conf->force_sync = 0;
-+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "1")))
-+ conf->force_sync = 1;
-+ else
-+ conf->force_sync = 0;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * blacklist block handlers
- */
-@@ -2822,6 +2845,15 @@ snprint_def_hw_strmatch(char * buff, int
- }
-
- static int
-+snprint_def_force_sync(char * buff, int len, void * data)
-+{
-+ if (conf->force_sync)
-+ return snprintf(buff, len, "yes");
-+ else
-+ return snprintf(buff, len, "no");
-+}
-+
-+static int
- snprint_ble_simple (char * buff, int len, void * data)
- {
- struct blentry * ble = (struct blentry *)data;
-@@ -2889,6 +2921,7 @@ init_keywords(void)
- install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
- install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
- install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
-+ install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
- __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);
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -952,8 +952,12 @@ get_state (struct path * pp, int daemon)
- }
- }
- checker_clear_message(c);
-- if (daemon)
-- checker_set_async(c);
-+ if (daemon) {
-+ if (conf->force_sync == 0)
-+ checker_set_async(c);
-+ else
-+ checker_set_sync(c);
-+ }
- if (!conf->checker_timeout &&
- (pp->bus != SYSFS_BUS_SCSI ||
- sysfs_get_timeout(pp, &(c->timeout))))
-Index: multipath-tools-130222/multipath.conf.annotated
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.annotated
-+++ multipath-tools-130222/multipath.conf.annotated
-@@ -214,6 +214,8 @@
- # # values : n > 0
- # # default : determined by the OS
- # dev_loss_tmo 600
-+#
-+# #
- # # name : bindings_file
- # # scope : multipath
- # # desc : The location of the bindings file that is used with
-@@ -222,6 +224,14 @@
- # # default : "/var/lib/multipath/bindings"
- # bindings_file "/etc/multipath_bindings"
- #
-+# #
-+# # name : force_sync
-+# # scope : multipathd
-+# # desc : If set to yes, multipath will run all of the checkers in
-+# # sync mode, even if the checker has an async mode.
-+# # values : yes|no
-+# # default : no
-+# force_sync yes
- #}
- #
- ##
-Index: multipath-tools-130222/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.conf.5
-+++ multipath-tools-130222/multipath/multipath.conf.5
-@@ -411,6 +411,15 @@ modify an existing config, or create a n
- , the user device configs will be regular expression matched against the
- built-in configs instead. Default is
- .I no
-+.TP
-+.B force_sync
-+If set to
-+.I yes
-+, multipathd will call the path checkers in sync mode only. This means that
-+only one checker will run at a time. This is useful in the case where many
-+multipathd checkers running in parallel causes significant CPU pressure. The
-+Default is
-+.I no
- .
- .SH "blacklist section"
- The
+++ /dev/null
----
- libmultipath/configure.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++
- libmultipath/configure.h | 2
- libmultipath/discovery.c | 87 +++++++++++++++++
- libmultipath/discovery.h | 2
- libmultipath/structs.c | 84 +++++++++++++++++
- libmultipath/structs.h | 25 ++++-
- 6 files changed, 427 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -39,6 +39,219 @@
- #include "uxsock.h"
- #include "wwids.h"
-
-+/* group paths in pg by host adapter
-+ */
-+int group_by_host_adapter(struct pathgroup *pgp, vector adapters)
-+{
-+ struct adapter_group *agp;
-+ struct host_group *hgp;
-+ struct path *pp, *pp1;
-+ char adapter_name1[SLOT_NAME_SIZE];
-+ char adapter_name2[SLOT_NAME_SIZE];
-+ int i, j;
-+ int found_hostgroup = 0;
-+
-+ while (VECTOR_SIZE(pgp->paths) > 0) {
-+
-+ pp = VECTOR_SLOT(pgp->paths, 0);
-+
-+ if (sysfs_get_host_adapter_name(pp, adapter_name1))
-+ goto out;
-+ /* create a new host adapter group
-+ */
-+ agp = alloc_adaptergroup();
-+ if (!agp)
-+ goto out;
-+ agp->pgp = pgp;
-+
-+ strncpy(agp->adapter_name, adapter_name1, SLOT_NAME_SIZE);
-+ store_adaptergroup(adapters, agp);
-+
-+ /* create a new host port group
-+ */
-+ hgp = alloc_hostgroup();
-+ if (!hgp)
-+ goto out;
-+ if (store_hostgroup(agp->host_groups, hgp))
-+ goto out;
-+
-+ hgp->host_no = pp->sg_id.host_no;
-+ agp->num_hosts++;
-+ if (store_path(hgp->paths, pp))
-+ goto out;
-+
-+ hgp->num_paths++;
-+ /* delete path from path group
-+ */
-+ vector_del_slot(pgp->paths, 0);
-+
-+ /* add all paths belonging to same host adapter
-+ */
-+ vector_foreach_slot(pgp->paths, pp1, i) {
-+ if (sysfs_get_host_adapter_name(pp1, adapter_name2))
-+ goto out;
-+ if (strcmp(adapter_name1, adapter_name2) == 0) {
-+ found_hostgroup = 0;
-+ vector_foreach_slot(agp->host_groups, hgp, j) {
-+ if (hgp->host_no == pp1->sg_id.host_no) {
-+ if (store_path(hgp->paths, pp1))
-+ goto out;
-+ hgp->num_paths++;
-+ found_hostgroup = 1;
-+ break;
-+ }
-+ }
-+ if (!found_hostgroup) {
-+ /* this path belongs to new host port
-+ * within this adapter
-+ */
-+ hgp = alloc_hostgroup();
-+ if (!hgp)
-+ goto out;
-+
-+ if (store_hostgroup(agp->host_groups, hgp))
-+ goto out;
-+
-+ agp->num_hosts++;
-+ if (store_path(hgp->paths, pp1))
-+ goto out;
-+
-+ hgp->host_no = pp1->sg_id.host_no;
-+ hgp->num_paths++;
-+ }
-+ /* delete paths from original path_group
-+ * as they are added into adapter group now
-+ */
-+ vector_del_slot(pgp->paths, i);
-+ i--;
-+ }
-+ }
-+ }
-+ return 0;
-+
-+out: /* add back paths into pg as re-ordering failed
-+ */
-+ vector_foreach_slot(adapters, agp, i) {
-+ vector_foreach_slot(agp->host_groups, hgp, j) {
-+ while (VECTOR_SIZE(hgp->paths) > 0) {
-+ pp = VECTOR_SLOT(hgp->paths, 0);
-+ if (store_path(pgp->paths, pp))
-+ condlog(3, "failed to restore "
-+ "path %s into path group",
-+ pp->dev);
-+ vector_del_slot(hgp->paths, 0);
-+ }
-+ }
-+ }
-+ free_adaptergroup(adapters);
-+ return 1;
-+}
-+
-+/* re-order paths in pg by alternating adapters and host ports
-+ * for optimized selection
-+ */
-+int order_paths_in_pg_by_alt_adapters(struct pathgroup *pgp, vector adapters,
-+ int total_paths)
-+{
-+ int next_adapter_index = 0;
-+ struct adapter_group *agp;
-+ struct host_group *hgp;
-+ struct path *pp;
-+
-+ while (total_paths > 0) {
-+ agp = VECTOR_SLOT(adapters, next_adapter_index);
-+ if (!agp) {
-+ condlog(0, "can't get adapter group %d", next_adapter_index);
-+ return 1;
-+ }
-+
-+ hgp = VECTOR_SLOT(agp->host_groups, agp->next_host_index);
-+ if (!hgp) {
-+ condlog(0, "can't get host group %d of adapter group %d", next_adapter_index, agp->next_host_index);
-+ return 1;
-+ }
-+
-+ if (!hgp->num_paths) {
-+ agp->next_host_index++;
-+ agp->next_host_index %= agp->num_hosts;
-+ next_adapter_index++;
-+ next_adapter_index %= VECTOR_SIZE(adapters);
-+ continue;
-+ }
-+
-+ pp = VECTOR_SLOT(hgp->paths, 0);
-+
-+ if (store_path(pgp->paths, pp))
-+ return 1;
-+
-+ total_paths--;
-+
-+ vector_del_slot(hgp->paths, 0);
-+
-+ hgp->num_paths--;
-+
-+ agp->next_host_index++;
-+ agp->next_host_index %= agp->num_hosts;
-+ next_adapter_index++;
-+ next_adapter_index %= VECTOR_SIZE(adapters);
-+ }
-+
-+ /* all paths are added into path_group
-+ * in crafted child order
-+ */
-+ return 0;
-+}
-+
-+/* round-robin: order paths in path group to alternate
-+ * between all host adapters
-+ */
-+int rr_optimize_path_order(struct pathgroup *pgp)
-+{
-+ vector adapters;
-+ struct path *pp;
-+ int total_paths;
-+ int i;
-+
-+ total_paths = VECTOR_SIZE(pgp->paths);
-+ vector_foreach_slot(pgp->paths, pp, i) {
-+ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP &&
-+ pp->sg_id.proto_id != SCSI_PROTOCOL_SAS &&
-+ pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI &&
-+ pp->sg_id.proto_id != SCSI_PROTOCOL_SRP) {
-+ /* return success as default path order
-+ * is maintained in path group
-+ */
-+ return 0;
-+ }
-+ }
-+ adapters = vector_alloc();
-+ if (!adapters)
-+ return 0;
-+
-+ /* group paths in path group by host adapters
-+ */
-+ if (group_by_host_adapter(pgp, adapters)) {
-+ /* already freed adapters */
-+ condlog(3, "Failed to group paths by adapters");
-+ return 0;
-+ }
-+
-+ /* re-order paths in pg to alternate between adapters and host ports
-+ */
-+ if (order_paths_in_pg_by_alt_adapters(pgp, adapters, total_paths)) {
-+ condlog(3, "Failed to re-order paths in pg by adapters "
-+ "and host ports");
-+ free_adaptergroup(adapters);
-+ /* return failure as original paths are
-+ * removed form pgp
-+ */
-+ return 1;
-+ }
-+
-+ free_adaptergroup(adapters);
-+ return 0;
-+}
-+
- extern int
- setup_map (struct multipath * mpp, char * params, int params_size)
- {
-@@ -101,6 +314,22 @@ setup_map (struct multipath * mpp, char
- */
- mpp->bestpg = select_path_group(mpp);
-
-+ /* re-order paths in all path groups in an optimized way
-+ * for round-robin path selectors to get maximum throughput.
-+ */
-+ if (!strncmp(mpp->selector, "round-robin", 11)) {
-+ vector_foreach_slot(mpp->pg, pgp, i) {
-+ if (VECTOR_SIZE(pgp->paths) <= 2)
-+ continue;
-+ if (rr_optimize_path_order(pgp)) {
-+ condlog(2, "cannot re-order paths for "
-+ "optimization: %s",
-+ mpp->alias);
-+ return 1;
-+ }
-+ }
-+ }
-+
- /*
- * transform the mp->pg vector of vectors of paths
- * into a mp->params strings to feed the device-mapper
-Index: multipath-tools-130222/libmultipath/configure.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.h
-+++ multipath-tools-130222/libmultipath/configure.h
-@@ -29,4 +29,4 @@ int reinstate_paths (struct multipath *m
- int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int force_reload);
- int get_refwwid (char * dev, enum devtypes dev_type, vector pathvec, char **wwid);
- int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh);
--
-+int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name);
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -310,6 +310,93 @@ sysfs_get_tgt_nodename (struct path *pp,
- return 1;
- }
-
-+int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name)
-+{
-+ int proto_id;
-+
-+ if (!pp || !adapter_name)
-+ return 1;
-+
-+ proto_id = pp->sg_id.proto_id;
-+
-+ if (proto_id != SCSI_PROTOCOL_FCP &&
-+ proto_id != SCSI_PROTOCOL_SAS &&
-+ proto_id != SCSI_PROTOCOL_ISCSI &&
-+ proto_id != SCSI_PROTOCOL_SRP) {
-+ return 1;
-+ }
-+ /* iscsi doesn't have adapter info in sysfs
-+ * get ip_address for grouping paths
-+ */
-+ if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
-+ return sysfs_get_iscsi_ip_address(pp, adapter_name);
-+
-+ /* fetch adapter pci name for other protocols
-+ */
-+ return sysfs_get_host_pci_name(pp, adapter_name);
-+}
-+
-+int sysfs_get_host_pci_name(struct path *pp, char *pci_name)
-+{
-+ struct udev_device *hostdev, *parent;
-+ char host_name[HOST_NAME_LEN];
-+ const char *driver_name, *value;
-+
-+ if (!pp || !pci_name)
-+ return 1;
-+
-+ sprintf(host_name, "host%d", pp->sg_id.host_no);
-+ hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
-+ "scsi_host", host_name);
-+ if (!hostdev)
-+ return 1;
-+
-+ parent = udev_device_get_parent(hostdev);
-+ while (parent) {
-+ driver_name = udev_device_get_driver(parent);
-+ if (!driver_name) {
-+ parent = udev_device_get_parent(parent);
-+ continue;
-+ }
-+ if (!strcmp(driver_name, "pcieport"))
-+ break;
-+ parent = udev_device_get_parent(parent);
-+ }
-+ if (parent) {
-+ /* pci_device found
-+ */
-+ value = udev_device_get_sysname(parent);
-+
-+ strncpy(pci_name, value, SLOT_NAME_SIZE);
-+ udev_device_unref(hostdev);
-+ return 0;
-+ }
-+ udev_device_unref(hostdev);
-+ return 1;
-+}
-+
-+int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address)
-+{
-+ struct udev_device *hostdev;
-+ char host_name[HOST_NAME_LEN];
-+ const char *value;
-+
-+ sprintf(host_name, "host%d", pp->sg_id.host_no);
-+ hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
-+ "iscsi_host", host_name);
-+ if (hostdev) {
-+ value = udev_device_get_sysattr_value(hostdev,
-+ "ipaddress");
-+ if (value) {
-+ strncpy(ip_address, value, SLOT_NAME_SIZE);
-+ udev_device_unref(hostdev);
-+ return 0;
-+ } else
-+ udev_device_unref(hostdev);
-+ }
-+ return 1;
-+}
-+
- static void
- sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
- {
-Index: multipath-tools-130222/libmultipath/discovery.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.h
-+++ multipath-tools-130222/libmultipath/discovery.h
-@@ -38,6 +38,8 @@ int store_pathinfo (vector pathvec, vect
- struct path **pp_ptr);
- int sysfs_set_scsi_tmo (struct multipath *mpp);
- int sysfs_get_timeout(struct path *pp, unsigned int *timeout);
-+int sysfs_get_host_pci_name(struct path *pp, char *pci_name);
-+int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address);
-
- /*
- * discovery bitmask
-Index: multipath-tools-130222/libmultipath/structs.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs.c
-+++ multipath-tools-130222/libmultipath/structs.c
-@@ -18,6 +18,70 @@
- #include "blacklist.h"
- #include "prio.h"
-
-+struct adapter_group *
-+alloc_adaptergroup(void)
-+{
-+ struct adapter_group *agp;
-+
-+ agp = (struct adapter_group *)MALLOC(sizeof(struct adapter_group));
-+
-+ if (!agp)
-+ return NULL;
-+
-+ agp->host_groups = vector_alloc();
-+ if (!agp->host_groups) {
-+ FREE(agp);
-+ agp = NULL;
-+ }
-+ return agp;
-+}
-+
-+void free_adaptergroup(vector adapters)
-+{
-+ int i;
-+ struct adapter_group *agp;
-+
-+ vector_foreach_slot(adapters, agp, i) {
-+ free_hostgroup(agp->host_groups);
-+ FREE(agp);
-+ }
-+ vector_free(adapters);
-+}
-+
-+void free_hostgroup(vector hostgroups)
-+{
-+ int i;
-+ struct host_group *hgp;
-+
-+ if (!hostgroups)
-+ return;
-+
-+ vector_foreach_slot(hostgroups, hgp, i) {
-+ vector_free(hgp->paths);
-+ FREE(hgp);
-+ }
-+ vector_free(hostgroups);
-+}
-+
-+struct host_group *
-+alloc_hostgroup(void)
-+{
-+ struct host_group *hgp;
-+
-+ hgp = (struct host_group *)MALLOC(sizeof(struct host_group));
-+
-+ if (!hgp)
-+ return NULL;
-+
-+ hgp->paths = vector_alloc();
-+
-+ if (!hgp->paths) {
-+ FREE(hgp);
-+ hgp = NULL;
-+ }
-+ return hgp;
-+}
-+
- struct path *
- alloc_path (void)
- {
-@@ -242,6 +306,26 @@ store_pathgroup (vector pgvec, struct pa
- return 0;
- }
-
-+int
-+store_hostgroup(vector hostgroupvec, struct host_group * hgp)
-+{
-+ if (!vector_alloc_slot(hostgroupvec))
-+ return 1;
-+
-+ vector_set_slot(hostgroupvec, hgp);
-+ return 0;
-+}
-+
-+int
-+store_adaptergroup(vector adapters, struct adapter_group * agp)
-+{
-+ if (!vector_alloc_slot(adapters))
-+ return 1;
-+
-+ vector_set_slot(adapters, agp);
-+ return 0;
-+}
-+
- struct multipath *
- find_mp_by_minor (vector mpvec, int minor)
- {
-Index: multipath-tools-130222/libmultipath/structs.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs.h
-+++ multipath-tools-130222/libmultipath/structs.h
-@@ -15,7 +15,8 @@
- #define BLK_DEV_SIZE 33
- #define PATH_SIZE 512
- #define NAME_SIZE 512
--
-+#define HOST_NAME_LEN 8
-+#define SLOT_NAME_SIZE 40
-
- #define SCSI_VENDOR_SIZE 9
- #define SCSI_PRODUCT_SIZE 17
-@@ -251,6 +252,20 @@ struct pathgroup {
- char * selector;
- };
-
-+struct adapter_group {
-+ char adapter_name[SLOT_NAME_SIZE];
-+ struct pathgroup *pgp;
-+ int num_hosts;
-+ vector host_groups;
-+ int next_host_index;
-+};
-+
-+struct host_group {
-+ int host_no;
-+ int num_paths;
-+ vector paths;
-+};
-+
- struct path * alloc_path (void);
- struct pathgroup * alloc_pathgroup (void);
- struct multipath * alloc_multipath (void);
-@@ -263,6 +278,14 @@ void free_multipath_attributes (struct m
- void drop_multipath (vector mpvec, char * wwid, enum free_path_mode free_paths);
- void free_multipathvec (vector mpvec, enum free_path_mode free_paths);
-
-+struct adapter_group * alloc_adaptergroup(void);
-+struct host_group * alloc_hostgroup(void);
-+void free_adaptergroup(vector adapters);
-+void free_hostgroup(vector hostgroups);
-+
-+int store_adaptergroup(vector adapters, struct adapter_group *agp);
-+int store_hostgroup(vector hostgroupvec, struct host_group *hgp);
-+
- int store_path (vector pathvec, struct path * pp);
- int store_pathgroup (vector pgvec, struct pathgroup * pgp);
-
+++ /dev/null
----
- libmultipath/dict.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -43,6 +43,9 @@ def_fast_io_fail_handler(vector strvec)
- char * buff;
-
- buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
- if (strlen(buff) == 3 && !strcmp(buff, "off"))
- conf->fast_io_fail = MP_FAST_IO_FAIL_OFF;
- else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 ||
-@@ -1002,6 +1005,9 @@ hw_dev_loss_handler(vector strvec)
- char * buff;
- struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
-
-+ if (!hwe)
-+ return 1;
-+
- buff = set_value(strvec);
- if (!buff)
- return 1;
-@@ -1021,6 +1027,9 @@ hw_pgpolicy_handler(vector strvec)
- char * buff;
- struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
-
-+ if (!hwe)
-+ return 1;
-+
- buff = set_value(strvec);
-
- if (!buff)
+++ /dev/null
----
- libmultipath/configure.c | 11 +++++++++++
- libmultipath/configure.h | 1 +
- libmultipath/devmapper.c | 3 +--
- 3 files changed, 13 insertions(+), 2 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -394,6 +394,8 @@ select_action (struct multipath * mpp, v
- cmpp->alias, mpp->alias);
- strncpy(mpp->alias_old, cmpp->alias, WWID_SIZE);
- mpp->action = ACT_RENAME;
-+ if (force_reload)
-+ mpp->action = ACT_RENAME2;
- return;
- }
- mpp->action = ACT_CREATE;
-@@ -632,6 +634,15 @@ domap (struct multipath * mpp, char * pa
- r = dm_rename(mpp->alias_old, mpp->alias);
- break;
-
-+ case ACT_RENAME2:
-+ r = dm_rename(mpp->alias_old, mpp->alias);
-+ if (r) {
-+ r = dm_addmap_reload(mpp, params);
-+ if (r)
-+ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, MPATH_UDEV_RELOAD_FLAG);
-+ }
-+ break;
-+
- default:
- break;
- }
-Index: multipath-tools-130222/libmultipath/configure.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.h
-+++ multipath-tools-130222/libmultipath/configure.h
-@@ -18,6 +18,7 @@ enum actions {
- ACT_RENAME,
- ACT_CREATE,
- ACT_RESIZE,
-+ ACT_RENAME2,
- };
-
- #define FLUSH_ONE 1
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -565,10 +565,9 @@ dm_dev_t (const char * mapname, char * d
- if (!dm_task_run(dmt))
- goto out;
-
-- if (!dm_task_get_info(dmt, &info))
-+ if (!dm_task_get_info(dmt, &info) || !info.exists)
- goto out;
-
-- r = info.open_count;
- if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len)
- goto out;
-
+++ /dev/null
----
- libmultipath/alias.c | 64 ++++++++++++++++++++++++++++++++++++++++++---
- libmultipath/alias.h | 2 +
- libmultipath/propsel.c | 32 +++++++++++++++-------
- libmultipath/structs_vec.c | 15 ++++++++++
- 4 files changed, 100 insertions(+), 13 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/alias.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/alias.c
-+++ multipath-tools-130222/libmultipath/alias.c
-@@ -145,7 +145,7 @@ lookup_binding(FILE *f, char *map_wwid,
- }
-
- static int
--rlookup_binding(FILE *f, char *buff, char *map_alias)
-+rlookup_binding(FILE *f, char *buff, char *map_alias, char *prefix)
- {
- char line[LINE_MAX];
- unsigned int line_nr = 0;
-@@ -164,7 +164,7 @@ rlookup_binding(FILE *f, char *buff, cha
- alias = strtok(line, " \t");
- if (!alias) /* blank line */
- continue;
-- curr_id = scan_devname(alias, NULL); /* TBD: Why this call? */
-+ curr_id = scan_devname(alias, prefix);
- if (curr_id >= id)
- id = curr_id + 1;
- wwid = strtok(NULL, " \t");
-@@ -188,6 +188,11 @@ rlookup_binding(FILE *f, char *buff, cha
- }
- }
- condlog(3, "No matching alias [%s] in bindings file.", map_alias);
-+
-+ /* Get the theoretical id for this map alias.
-+ * Used by use_existing_alias
-+ */
-+ id = scan_devname(map_alias, prefix);
- return id;
- }
-
-@@ -237,6 +242,59 @@ allocate_binding(int fd, char *wwid, int
- }
-
- char *
-+use_existing_alias (char *wwid, char *file, char *alias_old,
-+ char *prefix, int bindings_read_only)
-+{
-+ char *alias = NULL;
-+ int id = 0;
-+ int fd, can_write;
-+ char buff[WWID_SIZE];
-+ FILE *f;
-+
-+ fd = open_file(file, &can_write, BINDINGS_FILE_HEADER);
-+ if (fd < 0)
-+ return NULL;
-+
-+ f = fdopen(fd, "r");
-+ if (!f) {
-+ condlog(0, "cannot fdopen on bindings file descriptor");
-+ close(fd);
-+ return NULL;
-+ }
-+ /* lookup the binding. if it exsists, the wwid will be in buff
-+ * either way, id contains the id for the alias
-+ */
-+ id = rlookup_binding(f , buff, alias_old, prefix);
-+ if (id < 0)
-+ goto out;
-+
-+ if (strlen(buff) > 0) {
-+ /* if buff is our wwid, it's already
-+ * allocated correctly
-+ */
-+ if (strcmp(buff, wwid) == 0)
-+ alias = STRDUP(alias_old);
-+ else {
-+ alias = NULL;
-+ condlog(0, "alias %s already bound to wwid %s, cannot reuse",
-+ alias_old, buff);
-+ }
-+ goto out;
-+ }
-+
-+ /* allocate the existing alias in the bindings file */
-+ if (can_write && id && !bindings_read_only) {
-+ alias = allocate_binding(fd, wwid, id, prefix);
-+ condlog(0, "Allocated existing binding [%s] for WWID [%s]",
-+ alias, wwid);
-+ }
-+
-+out:
-+ fclose(f);
-+ return alias;
-+}
-+
-+char *
- get_user_friendly_alias(char *wwid, char *file, char *prefix,
- int bindings_read_only)
- {
-@@ -305,7 +363,7 @@ get_user_friendly_wwid(char *alias, char
- return -1;
- }
-
-- rlookup_binding(f, buff, alias);
-+ rlookup_binding(f, buff, alias, NULL);
- if (!strlen(buff)) {
- fclose(f);
- return -1;
-Index: multipath-tools-130222/libmultipath/alias.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/alias.h
-+++ multipath-tools-130222/libmultipath/alias.h
-@@ -10,3 +10,5 @@
- char *get_user_friendly_alias(char *wwid, char *file, char *prefix,
- int bindings_readonly);
- int get_user_friendly_wwid(char *alias, char *buff, char *file);
-+char *use_existing_alias (char *wwid, char *file, char *alias_old,
-+ char *prefix, int bindings_read_only);
-Index: multipath-tools-130222/libmultipath/propsel.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.c
-+++ multipath-tools-130222/libmultipath/propsel.c
-@@ -253,19 +253,31 @@ want_user_friendly_names(struct multipat
- extern int
- select_alias (struct multipath * mp)
- {
-- if (mp->mpe && mp->mpe->alias)
-+ if (mp->mpe && mp->mpe->alias) {
- mp->alias = STRDUP(mp->mpe->alias);
-- else {
-- mp->alias = NULL;
-- if (want_user_friendly_names(mp)) {
-- select_alias_prefix(mp);
-- mp->alias = get_user_friendly_alias(mp->wwid,
-- conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
-- }
-- if (mp->alias == NULL)
-- mp->alias = STRDUP(mp->wwid);
-+ goto out;
- }
-
-+ mp->alias = NULL;
-+ if (!want_user_friendly_names(mp))
-+ goto out;
-+
-+ select_alias_prefix(mp);
-+
-+ if (strlen(mp->alias_old) > 0) {
-+ mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
-+ mp->alias_old, mp->alias_prefix,
-+ conf->bindings_read_only);
-+ memset (mp->alias_old, 0, WWID_SIZE);
-+ }
-+
-+ if (mp->alias == NULL)
-+ mp->alias = get_user_friendly_alias(mp->wwid,
-+ conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
-+out:
-+ if (mp->alias == NULL)
-+ mp->alias = STRDUP(mp->wwid);
-+
- return mp->alias ? 0 : 1;
- }
-
-Index: multipath-tools-130222/libmultipath/structs_vec.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs_vec.c
-+++ multipath-tools-130222/libmultipath/structs_vec.c
-@@ -430,6 +430,20 @@ out:
- return NULL;
- }
-
-+static void
-+find_existing_alias (struct multipath * mpp,
-+ struct vectors *vecs)
-+{
-+ struct multipath * mp;
-+ int i;
-+
-+ vector_foreach_slot (vecs->mpvec, mp, i)
-+ if (strcmp(mp->wwid, mpp->wwid) == 0) {
-+ strncpy(mpp->alias_old, mp->alias, WWID_SIZE);
-+ return;
-+ }
-+}
-+
- extern struct multipath *
- add_map_with_path (struct vectors * vecs,
- struct path * pp, int add_vec)
-@@ -443,6 +457,7 @@ add_map_with_path (struct vectors * vecs
- mpp->hwe = pp->hwe;
-
- strcpy(mpp->wwid, pp->wwid);
-+ find_existing_alias(mpp, vecs);
- if (select_alias(mpp))
- goto out;
- mpp->size = pp->size;
+++ /dev/null
----
- libmultipath/alias.c | 31 +++++++++++++++----------------
- libmultipath/propsel.c | 4 ++--
- 2 files changed, 17 insertions(+), 18 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/alias.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/alias.c
-+++ multipath-tools-130222/libmultipath/alias.c
-@@ -149,13 +149,11 @@ rlookup_binding(FILE *f, char *buff, cha
- {
- char line[LINE_MAX];
- unsigned int line_nr = 0;
-- int id = 0;
-
- buff[0] = '\0';
-
- while (fgets(line, LINE_MAX, f)) {
- char *c, *alias, *wwid;
-- int curr_id;
-
- line_nr++;
- c = strpbrk(line, "#\n\r");
-@@ -164,9 +162,6 @@ rlookup_binding(FILE *f, char *buff, cha
- alias = strtok(line, " \t");
- if (!alias) /* blank line */
- continue;
-- curr_id = scan_devname(alias, prefix);
-- if (curr_id >= id)
-- id = curr_id + 1;
- wwid = strtok(NULL, " \t");
- if (!wwid){
- condlog(3,
-@@ -184,16 +179,12 @@ rlookup_binding(FILE *f, char *buff, cha
- "\nSetting wwid to %s", alias, wwid);
- strncpy(buff, wwid, WWID_SIZE);
- buff[WWID_SIZE - 1] = '\0';
-- return id;
-+ return 0;
- }
- }
- condlog(3, "No matching alias [%s] in bindings file.", map_alias);
-
-- /* Get the theoretical id for this map alias.
-- * Used by use_existing_alias
-- */
-- id = scan_devname(map_alias, prefix);
-- return id;
-+ return -1;
- }
-
- static char *
-@@ -264,9 +255,7 @@ use_existing_alias (char *wwid, char *fi
- /* lookup the binding. if it exsists, the wwid will be in buff
- * either way, id contains the id for the alias
- */
-- id = rlookup_binding(f , buff, alias_old, prefix);
-- if (id < 0)
-- goto out;
-+ rlookup_binding(f, buff, alias_old, prefix);
-
- if (strlen(buff) > 0) {
- /* if buff is our wwid, it's already
-@@ -279,11 +268,21 @@ use_existing_alias (char *wwid, char *fi
- condlog(0, "alias %s already bound to wwid %s, cannot reuse",
- alias_old, buff);
- }
-- goto out;
-+ goto out;
- }
-
- /* allocate the existing alias in the bindings file */
-- if (can_write && id && !bindings_read_only) {
-+ id = scan_devname(alias_old, prefix);
-+ if (id <= 0)
-+ goto out;
-+
-+ if (fflush(f) != 0) {
-+ condlog(0, "cannot fflush bindings file stream : %s",
-+ strerror(errno));
-+ goto out;
-+ }
-+
-+ if (can_write && !bindings_read_only) {
- alias = allocate_binding(fd, wwid, id, prefix);
- condlog(0, "Allocated existing binding [%s] for WWID [%s]",
- alias, wwid);
-Index: multipath-tools-130222/libmultipath/propsel.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.c
-+++ multipath-tools-130222/libmultipath/propsel.c
-@@ -263,13 +263,13 @@ select_alias (struct multipath * mp)
- goto out;
-
- select_alias_prefix(mp);
--
-+
- if (strlen(mp->alias_old) > 0) {
- mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
- mp->alias_old, mp->alias_prefix,
- conf->bindings_read_only);
- memset (mp->alias_old, 0, WWID_SIZE);
-- }
-+ }
-
- if (mp->alias == NULL)
- mp->alias = get_user_friendly_alias(mp->wwid,
+++ /dev/null
----
- libmultipath/hwtable.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/hwtable.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/hwtable.c
-+++ multipath-tools-130222/libmultipath/hwtable.c
-@@ -1121,6 +1121,19 @@ static struct hwentry default_hw[] = {
- .prio_name = PRIO_ALUA,
- .prio_args = NULL,
- },
-+ {
-+ .vendor = "XtremIO",
-+ .product = "XtremApp",
-+ .features = DEFAULT_FEATURES,
-+ .hwhandler = DEFAULT_HWHANDLER,
-+ .selector = "queue-length 0",
-+ .pgpolicy = MULTIBUS,
-+ .pgfailback = -FAILBACK_IMMEDIATE,
-+ .checker_name = DIRECTIO,
-+ .fast_io_fail = 15,
-+ .prio_name = DEFAULT_PRIO,
-+ .prio_args = NULL,
-+ },
- /*
- * EOL
- */
+++ /dev/null
----
- libmultipath/print.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 83 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/print.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/print.c
-+++ multipath-tools-130222/libmultipath/print.c
-@@ -10,6 +10,7 @@
- #include <unistd.h>
- #include <string.h>
- #include <errno.h>
-+#include <libudev.h>
-
- #include "checkers.h"
- #include "vector.h"
-@@ -44,7 +45,7 @@
- * information printing helpers
- */
- static int
--snprint_str (char * buff, size_t len, char * str)
-+snprint_str (char * buff, size_t len, const char * str)
- {
- return snprintf(buff, len, "%s", str);
- }
-@@ -432,6 +433,83 @@ snprint_path_mpp (char * buff, size_t le
- }
-
- static int
-+snprint_host_attr (char * buff, size_t len, struct path * pp, char *attr)
-+{
-+ struct udev_device *host_dev = NULL;
-+ char host_id[32];
-+ const char *value = NULL;
-+ int ret;
-+
-+ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP)
-+ return snprintf(buff, len, "[undef]");
-+ sprintf(host_id, "host%d", pp->sg_id.host_no);
-+ host_dev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_host",
-+ host_id);
-+ if (!host_dev) {
-+ condlog(1, "%s: No fc_host device for '%s'", pp->dev, host_id);
-+ goto out;
-+ }
-+ value = udev_device_get_sysattr_value(host_dev, attr);
-+ if (value)
-+ ret = snprint_str(buff, len, value);
-+ udev_device_unref(host_dev);
-+out:
-+ if (!value)
-+ ret = snprintf(buff, len, "[unknown]");
-+ return ret;
-+}
-+
-+static int
-+snprint_host_wwnn (char * buff, size_t len, struct path * pp)
-+{
-+ return snprint_host_attr(buff, len, pp, "node_name");
-+}
-+
-+static int
-+snprint_host_wwpn (char * buff, size_t len, struct path * pp)
-+{
-+ return snprint_host_attr(buff, len, pp, "port_name");
-+}
-+
-+static int
-+snprint_tgt_wwpn (char * buff, size_t len, struct path * pp)
-+{
-+ struct udev_device *rport_dev = NULL;
-+ char rport_id[32];
-+ const char *value = NULL;
-+ int ret;
-+
-+ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP)
-+ return snprintf(buff, len, "[undef]");
-+ sprintf(rport_id, "rport-%d:%d-%d",
-+ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
-+ rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
-+ "fc_remote_ports", rport_id);
-+ if (!rport_dev) {
-+ condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
-+ rport_id);
-+ goto out;
-+ }
-+ value = udev_device_get_sysattr_value(rport_dev, "port_name");
-+ if (value)
-+ ret = snprint_str(buff, len, value);
-+ udev_device_unref(rport_dev);
-+out:
-+ if (!value)
-+ ret = snprintf(buff, len, "[unknown]");
-+ return ret;
-+}
-+
-+
-+static int
-+snprint_tgt_wwnn (char * buff, size_t len, struct path * pp)
-+{
-+ if (pp->tgt_node_name[0] == '\0')
-+ return snprintf(buff, len, "[undef]");
-+ return snprint_str(buff, len, pp->tgt_node_name);
-+}
-+
-+static int
- snprint_path_checker (char * buff, size_t len, struct path * pp)
- {
- struct checker * c = &pp->checker;
-@@ -475,6 +553,10 @@ struct path_data pd[] = {
- {'S', "size", 0, snprint_path_size},
- {'z', "serial", 0, snprint_path_serial},
- {'m', "multipath", 0, snprint_path_mpp},
-+ {'N', "host WWNN", 0, snprint_host_wwnn},
-+ {'n', "target WWNN", 0, snprint_tgt_wwnn},
-+ {'R', "host WWPN", 0, snprint_host_wwpn},
-+ {'r', "target WWPN", 0, snprint_tgt_wwpn},
- {0, NULL, 0 , NULL}
- };
-
+++ /dev/null
----
- kpartx/devmapper.c | 3 ++-
- libmultipath/alias.c | 1 +
- libmultipath/blacklist.c | 7 +++++++
- libmultipath/prioritizers/iet.c | 2 ++
- libmultipath/prioritizers/weightedpath.c | 5 ++++-
- libmultipath/regex.c | 5 ++++-
- libmultipath/sysfs.c | 3 ++-
- libmultipath/util.c | 2 +-
- 8 files changed, 23 insertions(+), 5 deletions(-)
-
-Index: multipath-tools-130222/kpartx/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/kpartx/devmapper.c
-+++ multipath-tools-130222/kpartx/devmapper.c
-@@ -132,8 +132,9 @@ dm_addmap (int task, const char *name, c
- goto addout;
- r = dm_task_run (dmt);
-
-- addout:
-+addout:
- dm_task_destroy (dmt);
-+ free(prefixed_uuid);
-
- return r;
- }
-Index: multipath-tools-130222/libmultipath/alias.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/alias.c
-+++ multipath-tools-130222/libmultipath/alias.c
-@@ -328,6 +328,7 @@ get_user_friendly_alias(char *wwid, char
- if (fflush(f) != 0) {
- condlog(0, "cannot fflush bindings file stream : %s",
- strerror(errno));
-+ free(alias);
- fclose(f);
- return NULL;
- }
-Index: multipath-tools-130222/libmultipath/blacklist.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/blacklist.c
-+++ multipath-tools-130222/libmultipath/blacklist.c
-@@ -79,6 +79,8 @@ set_ble_device (vector blist, char * ven
- if (regcomp(&ble->vendor_reg, vendor,
- REG_EXTENDED|REG_NOSUB)) {
- FREE(vendor);
-+ if (product)
-+ FREE(product);
- return 1;
- }
- ble->vendor = vendor;
-@@ -87,6 +89,10 @@ set_ble_device (vector blist, char * ven
- if (regcomp(&ble->product_reg, product,
- REG_EXTENDED|REG_NOSUB)) {
- FREE(product);
-+ if (vendor) {
-+ ble->vendor = NULL;
-+ FREE(vendor);
-+ }
- return 1;
- }
- ble->product = product;
-@@ -189,6 +195,7 @@ setup_default_blist (struct config * con
- STRDUP(hwe->bl_product),
- ORIGIN_DEFAULT)) {
- FREE(ble);
-+ vector_del_slot(conf->blist_device, VECTOR_SIZE(conf->blist_device) - 1);
- return 1;
- }
- }
-Index: multipath-tools-130222/libmultipath/prioritizers/iet.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/iet.c
-+++ multipath-tools-130222/libmultipath/prioritizers/iet.c
-@@ -109,6 +109,7 @@ int iet_prio(const char *dev, char * arg
- ssize_t nchars = readlink(path, buffer, sizeof(buffer)-1);
- if (nchars != -1) {
- char *device;
-+ buffer[nchars] = '\0';
- device = find_regex(buffer,"(sd[a-z]+)");
- // if device parsed is the right one
- if (device!=NULL && strncmp(device, dev, strlen(device)) == 0) {
-@@ -118,6 +119,7 @@ int iet_prio(const char *dev, char * arg
- if (ip!=NULL && strncmp(ip, preferredip, strlen(ip)) == 0) {
- // high prio
- free(ip);
-+ free(device);
- closedir(dir_p);
- return 20;
- }
-Index: multipath-tools-130222/libmultipath/prioritizers/weightedpath.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/prioritizers/weightedpath.c
-+++ multipath-tools-130222/libmultipath/prioritizers/weightedpath.c
-@@ -61,8 +61,10 @@ int prio_path_weight(struct path *pp, ch
- regex = get_next_string(&temp, split_char);
-
- /* Return default priority if the argument is not parseable */
-- if (!regex)
-+ if (!regex) {
-+ FREE(arg);
- return priority;
-+ }
-
- if (!strcmp(regex, HBTL)) {
- sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no,
-@@ -72,6 +74,7 @@ int prio_path_weight(struct path *pp, ch
- } else {
- condlog(0, "%s: %s - Invalid arguments", pp->dev,
- pp->prio.name);
-+ FREE(arg);
- return priority;
- }
-
-Index: multipath-tools-130222/libmultipath/regex.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/regex.c
-+++ multipath-tools-130222/libmultipath/regex.c
-@@ -3936,8 +3936,11 @@ int eflags;
- regs.num_regs = nmatch;
- regs.start = TALLOC(nmatch, regoff_t);
- regs.end = TALLOC(nmatch, regoff_t);
-- if (regs.start == NULL || regs.end == NULL)
-+ if (regs.start == NULL || regs.end == NULL) {
-+ free(regs.start);
-+ free(regs.end);
- return (int) REG_NOMATCH;
-+ }
- }
-
- /* Perform the searching operation. */
-Index: multipath-tools-130222/libmultipath/sysfs.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/sysfs.c
-+++ multipath-tools-130222/libmultipath/sysfs.c
-@@ -88,7 +88,8 @@ ssize_t sysfs_attr_get_value(struct udev
- } else if (size == value_len) {
- condlog(4, "overflow while reading from %s", devpath);
- size = 0;
-- }
-+ } else
-+ value[size] = '\0';
-
- close(fd);
- return size;
-Index: multipath-tools-130222/libmultipath/util.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/util.c
-+++ multipath-tools-130222/libmultipath/util.c
-@@ -175,7 +175,7 @@ devt2devname (char *devname, int devname
- sprintf(block_path,"/sys/dev/block/%u:%u", major, minor);
- if (lstat(block_path, &statbuf) == 0) {
- if (S_ISLNK(statbuf.st_mode) &&
-- readlink(block_path, dev, FILE_NAME_SIZE) > 0) {
-+ readlink(block_path, dev, FILE_NAME_SIZE-1) > 0) {
- char *p = strrchr(dev, '/');
-
- if (!p) {
+++ /dev/null
----
- libmultipath/config.h | 15 ++++++++-
- libmultipath/configure.c | 2 -
- libmultipath/discovery.c | 5 +--
- multipath/main.c | 75 +++++++++++++++++++++++++----------------------
- multipath/multipath.8 | 5 ++-
- 5 files changed, 61 insertions(+), 41 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -23,6 +23,17 @@ enum devtypes {
- DEV_DEVMAP
- };
-
-+enum mpath_cmds {
-+ CMD_CREATE,
-+ CMD_DRY_RUN,
-+ CMD_LIST_SHORT,
-+ CMD_LIST_LONG,
-+ CMD_VALID_PATH,
-+ CMD_REMOVE_WWID,
-+ CMD_RESET_WWIDS,
-+ CMD_ADD_WWID,
-+};
-+
- struct hwentry {
- char * vendor;
- char * product;
-@@ -79,8 +90,7 @@ struct mpentry {
-
- struct config {
- int verbosity;
-- int dry_run;
-- int list;
-+ enum mpath_cmds cmd;
- int pgpolicy_flag;
- int pgpolicy;
- enum devtypes dev_type;
-@@ -98,6 +108,7 @@ struct config {
- int max_fds;
- int force_reload;
- int queue_without_daemon;
-+ int ignore_wwids;
- int checker_timeout;
- int daemon;
- int flush_on_last_del;
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -85,7 +85,7 @@ usage (char * progname)
- {
- fprintf (stderr, VERSION_STRING);
- fprintf (stderr, "Usage:\n");
-- fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
-+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-T tm:val] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
- fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
- fprintf (stderr, " %s -F [-v lvl]\n", progname);
- fprintf (stderr, " %s -t\n", progname);
-@@ -109,6 +109,7 @@ usage (char * progname)
- " -d dry run, do not create or update devmaps\n" \
- " -t dump internal hardware table\n" \
- " -r force devmap reload\n" \
-+ " -i ignore wwids file\n" \
- " -B treat the bindings file as read only\n" \
- " -p policy failover|multibus|group_by_serial|group_by_prio\n" \
- " -b fil bindings file location\n" \
-@@ -209,18 +210,19 @@ get_dm_mpvec (vector curmp, vector pathv
- * If not in "fast list mode", we need to fetch information
- * about them
- */
-- if (conf->list != 1)
-+ if (conf->cmd != CMD_LIST_SHORT)
- update_paths(mpp);
-
-- if (conf->list > 1)
-+ if (conf->cmd == CMD_LIST_LONG)
- mpp->bestpg = select_path_group(mpp);
-
- disassemble_status(status, mpp);
-
-- if (conf->list)
-+ if (conf->cmd == CMD_LIST_SHORT ||
-+ conf->cmd == CMD_LIST_LONG)
- print_multipath_topology(mpp, conf->verbosity);
-
-- if (!conf->dry_run)
-+ if (conf->cmd == CMD_CREATE)
- reinstate_paths(mpp);
- }
- return 0;
-@@ -262,10 +264,11 @@ configure (void)
- /*
- * if we have a blacklisted device parameter, exit early
- */
-- if (dev && conf->dev_type == DEV_DEVNODE && conf->dry_run != 3 &&
-+ if (dev && conf->dev_type == DEV_DEVNODE &&
-+ conf->cmd != CMD_REMOVE_WWID &&
- (filter_devnode(conf->blist_devnode,
- conf->elist_devnode, dev) > 0)) {
-- if (conf->dry_run == 2)
-+ if (conf->cmd == CMD_VALID_PATH)
- printf("%s is not a valid multipath device path\n",
- conf->dev);
- goto out;
-@@ -278,13 +281,13 @@ configure (void)
- int failed = get_refwwid(conf->dev, conf->dev_type, pathvec,
- &refwwid);
- if (!refwwid) {
-- if (failed == 2 && conf->dry_run == 2)
-+ if (failed == 2 && conf->cmd == CMD_VALID_PATH)
- printf("%s is not a valid multipath device path\n", conf->dev);
- else
- condlog(3, "scope is nul");
- goto out;
- }
-- if (conf->dry_run == 3) {
-+ if (conf->cmd == CMD_REMOVE_WWID) {
- r = remove_wwid(refwwid);
- if (r == 0)
- printf("wwid '%s' removed\n", refwwid);
-@@ -295,7 +298,7 @@ configure (void)
- }
- goto out;
- }
-- if (conf->dry_run == 5) {
-+ if (conf->cmd == CMD_ADD_WWID) {
- r = remember_wwid(refwwid);
- if (r == 0)
- printf("wwid '%s' added\n", refwwid);
-@@ -305,13 +308,13 @@ configure (void)
- goto out;
- }
- condlog(3, "scope limited to %s", refwwid);
-- if (conf->dry_run == 2) {
-- if (check_wwids_file(refwwid, 0) == 0){
-- printf("%s is a valid multipath device path\n", conf->dev);
-+ if (conf->cmd == CMD_VALID_PATH) {
-+ if (conf->ignore_wwids ||
-+ check_wwids_file(refwwid, 0) == 0)
- r = 0;
-- }
-- else
-- printf("%s is not a valid multipath device path\n", conf->dev);
-+
-+ printf("%s %s a valid multipath device path\n",
-+ conf->dev, r == 0 ? "is" : "is not");
- goto out;
- }
- }
-@@ -319,13 +322,13 @@ configure (void)
- /*
- * get a path list
- */
-- if (conf->dev && !conf->list)
-+ if (conf->dev)
- di_flag = DI_WWID;
-
-- if (conf->list > 1)
-+ if (conf->cmd == CMD_LIST_LONG)
- /* extended path info '-ll' */
- di_flag |= DI_SYSFS | DI_CHECKER;
-- else if (conf->list)
-+ else if (conf->cmd == CMD_LIST_SHORT)
- /* minimum path info '-l' */
- di_flag |= DI_SYSFS;
- else
-@@ -345,7 +348,7 @@ configure (void)
-
- filter_pathvec(pathvec, refwwid);
-
-- if (conf->list) {
-+ if (conf->cmd != CMD_CREATE && conf->cmd != CMD_DRY_RUN) {
- r = 0;
- goto out;
- }
-@@ -440,7 +443,7 @@ main (int argc, char *argv[])
- int r = 1;
- long int timestamp = -1;
- int valid = -1;
-- while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BritT:qwW")) != EOF ) {
- switch(arg) {
- case 'T':
- if (optarg[0] == ':')
-@@ -476,7 +479,7 @@ main (int argc, char *argv[])
- if (dm_prereq())
- exit(1);
-
-- while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrtT:qwW")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BritT:qwW")) != EOF ) {
- switch(arg) {
- case 1: printf("optarg : %s\n",optarg);
- break;
-@@ -499,11 +502,11 @@ main (int argc, char *argv[])
- conf->allow_queueing = 1;
- break;
- case 'c':
-- conf->dry_run = 2;
-+ conf->cmd = CMD_VALID_PATH;
- break;
- case 'd':
-- if (!conf->dry_run)
-- conf->dry_run = 1;
-+ if (conf->cmd == CMD_CREATE)
-+ conf->cmd = CMD_DRY_RUN;
- break;
- case 'f':
- conf->remove = FLUSH_ONE;
-@@ -512,11 +515,10 @@ main (int argc, char *argv[])
- conf->remove = FLUSH_ALL;
- break;
- case 'l':
-- conf->list = 1;
-- conf->dry_run = 1;
--
- if (optarg && !strncmp(optarg, "l", 1))
-- conf->list++;
-+ conf->cmd = CMD_LIST_LONG;
-+ else
-+ conf->cmd = CMD_LIST_SHORT;
-
- break;
- case 'M':
-@@ -535,6 +537,9 @@ main (int argc, char *argv[])
- case 'r':
- conf->force_reload = 1;
- break;
-+ case 'i':
-+ conf->ignore_wwids = 1;
-+ break;
- case 't':
- r = dump_config();
- goto out;
-@@ -548,13 +553,13 @@ main (int argc, char *argv[])
- usage(argv[0]);
- exit(0);
- case 'w':
-- conf->dry_run = 3;
-+ conf->cmd = CMD_REMOVE_WWID;
- break;
- case 'W':
-- conf->dry_run = 4;
-+ conf->cmd = CMD_RESET_WWIDS;
- break;
- case 'a':
-- conf->dry_run = 5;
-+ conf->cmd = CMD_ADD_WWID;
- break;
- case ':':
- fprintf(stderr, "Missing option argument\n");
-@@ -600,16 +605,16 @@ main (int argc, char *argv[])
- }
- dm_init();
-
-- if (conf->dry_run == 2 &&
-+ if (conf->cmd == CMD_VALID_PATH &&
- (!conf->dev || conf->dev_type == DEV_DEVMAP)) {
- condlog(0, "the -c option requires a path to check");
- goto out;
- }
-- if (conf->dry_run == 3 && !conf->dev) {
-+ if (conf->cmd == CMD_REMOVE_WWID && !conf->dev) {
- condlog(0, "the -w option requires a device");
- goto out;
- }
-- if (conf->dry_run == 4) {
-+ if (conf->cmd == CMD_RESET_WWIDS) {
- struct multipath * mpp;
- int i;
- vector curmp;
-Index: multipath-tools-130222/multipath/multipath.8
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.8
-+++ multipath-tools-130222/multipath/multipath.8
-@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
- .RB [\| \-b\ \c
- .IR bindings_file \|]
- .RB [\| \-d \|]
--.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-a | \-A | \-w | \-W \|]
-+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-r | \-a | \-A | \-w | \-W \|]
- .RB [\| \-p\ \c
- .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
- .RB [\| device \|]
-@@ -55,6 +55,9 @@ print internal hardware table to stdout
- .B \-r
- force devmap reload
- .TP
-+.B \-i
-+ignore wwids file when processing devices
-+.TP
- .B \-B
- treat the bindings file as read only
- .TP
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -580,7 +580,7 @@ domap (struct multipath * mpp, char * pa
- /*
- * last chance to quit before touching the devmaps
- */
-- if (conf->dry_run && mpp->action != ACT_NOTHING) {
-+ if (conf->cmd == CMD_DRY_RUN && mpp->action != ACT_NOTHING) {
- print_multipath_topology(mpp, conf->verbosity);
- return DOMAP_DRY;
- }
-Index: multipath-tools-130222/libmultipath/discovery.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/discovery.c
-+++ multipath-tools-130222/libmultipath/discovery.c
-@@ -54,7 +54,8 @@ store_pathinfo (vector pathvec, vector h
- }
- pp->udev = udev_device_ref(udevice);
- err = pathinfo(pp, hwtable,
-- (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST));
-+ (conf->cmd == CMD_REMOVE_WWID)? flag :
-+ (flag | DI_BLACKLIST));
- if (err)
- goto out;
-
-@@ -1101,7 +1102,7 @@ get_uid (struct path * pp)
-
- memset(pp->wwid, 0, WWID_SIZE);
- value = udev_device_get_property_value(pp->udev, pp->uid_attribute);
-- if ((!value || strlen(value) == 0) && conf->dry_run == 2)
-+ if ((!value || strlen(value) == 0) && conf->cmd == CMD_VALID_PATH)
- value = getenv(pp->uid_attribute);
- if (value && strlen(value)) {
- size_t len = WWID_SIZE;
+++ /dev/null
----
- libmultipath/config.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-
- libmultipath/config.h | 1
- libmultipath/dict.c | 38 +++++++++++++++++++++++++++++
- 3 files changed, 102 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -113,6 +113,8 @@ find_hwe (vector hwtable, char * vendor,
- * continuing to the generic entries
- */
- vector_foreach_slot_backwards (hwtable, tmp, i) {
-+ if (tmp->all_devs == 1)
-+ continue;
- if (hwe_regmatch(tmp, &hwe))
- continue;
- ret = tmp;
-@@ -348,6 +350,62 @@ merge_hwe (struct hwentry * dst, struct
- return 0;
- }
-
-+#define overwrite_str(s) \
-+do { \
-+ if (src->s) { \
-+ if (dst->s) \
-+ FREE(dst->s); \
-+ if (!(dst->s = set_param_str(src->s))) \
-+ return 1; \
-+ } \
-+} while(0)
-+
-+#define overwrite_num(s) \
-+do { \
-+ if (src->s) \
-+ dst->s = src->s; \
-+} while(0)
-+
-+static int
-+overwrite_hwe (struct hwentry * dst, struct hwentry * src)
-+{
-+ overwrite_str(vendor);
-+ overwrite_str(product);
-+ overwrite_str(revision);
-+ overwrite_str(uid_attribute);
-+ overwrite_str(features);
-+ overwrite_str(hwhandler);
-+ overwrite_str(selector);
-+ overwrite_str(checker_name);
-+ overwrite_str(prio_name);
-+ overwrite_str(prio_args);
-+ overwrite_str(alias_prefix);
-+ overwrite_str(bl_product);
-+ overwrite_num(pgpolicy);
-+ overwrite_num(pgfailback);
-+ overwrite_num(rr_weight);
-+ overwrite_num(no_path_retry);
-+ overwrite_num(minio);
-+ overwrite_num(minio_rq);
-+ overwrite_num(pg_timeout);
-+ overwrite_num(flush_on_last_del);
-+ overwrite_num(fast_io_fail);
-+ overwrite_num(dev_loss);
-+ overwrite_num(user_friendly_names);
-+ overwrite_num(retain_hwhandler);
-+ overwrite_num(detect_prio);
-+
-+ /*
-+ * Make sure features is consistent with
-+ * no_path_retry
-+ */
-+ if (dst->no_path_retry == NO_PATH_RETRY_FAIL)
-+ remove_feature(&dst->features, "queue_if_no_path");
-+ else if (dst->no_path_retry != NO_PATH_RETRY_UNDEF)
-+ add_feature(&dst->features, "queue_if_no_path");
-+ return 0;
-+}
-+
- int
- store_hwe (vector hwtable, struct hwentry * dhwe)
- {
-@@ -431,7 +489,11 @@ restart:
- break;
- j = n;
- vector_foreach_slot_after(hw, hwe2, j) {
-- if (conf->hw_strmatch) {
-+ if (hwe2->all_devs == 1) {
-+ overwrite_hwe(hwe1, hwe2);
-+ continue;
-+ }
-+ else if (conf->hw_strmatch) {
- if (hwe_strmatch(hwe2, hwe1))
- continue;
- }
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -47,6 +47,7 @@ struct hwentry {
- char * prio_args;
- char * alias_prefix;
-
-+ int all_devs;
- int pgpolicy;
- int pgfailback;
- int rr_weight;
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -918,6 +918,32 @@ device_handler(vector strvec)
- }
-
- static int
-+all_devs_handler(vector strvec)
-+{
-+ char * buff;
-+ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
-+
-+ if (!hwe)
-+ return 1;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ hwe->all_devs = 0;
-+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "1")))
-+ hwe->all_devs = 1;
-+ else
-+ hwe->all_devs = 0;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
-+static int
- vendor_handler(vector strvec)
- {
- struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
-@@ -2182,6 +2208,17 @@ snprint_hw_dev_loss(char * buff, int len
- }
-
- static int
-+snprint_hw_all_devs (char *buff, int len, void *data)
-+{
-+ struct hwentry * hwe = (struct hwentry *)data;
-+
-+ if (!hwe->all_devs)
-+ return 0;
-+
-+ return snprintf(buff, len, "yes");
-+}
-+
-+static int
- snprint_hw_vendor (char * buff, int len, void * data)
- {
- struct hwentry * hwe = (struct hwentry *)data;
-@@ -2968,6 +3005,7 @@ init_keywords(void)
- install_keyword_root("devices", &devices_handler);
- install_keyword_multi("device", &device_handler, NULL);
- install_sublevel();
-+ install_keyword("all_devs", &all_devs_handler, &snprint_hw_all_devs);
- install_keyword("vendor", &vendor_handler, &snprint_hw_vendor);
- install_keyword("product", &product_handler, &snprint_hw_product);
- install_keyword("revision", &revision_handler, &snprint_hw_revision);
+++ /dev/null
----
- multipath/main.c | 25 ++++++++++++++++++++++++-
- 1 file changed, 24 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipath/main.c
-===================================================================
---- multipath-tools-130222.orig/multipath/main.c
-+++ multipath-tools-130222/multipath/main.c
-@@ -198,6 +198,9 @@ get_dm_mpvec (vector curmp, vector pathv
- continue;
- }
-
-+ if (conf->cmd == CMD_VALID_PATH)
-+ continue;
-+
- dm_get_map(mpp->alias, &mpp->size, params);
- condlog(3, "params = %s", params);
- dm_get_status(mpp->alias, status);
-@@ -308,7 +311,13 @@ configure (void)
- goto out;
- }
- condlog(3, "scope limited to %s", refwwid);
-- if (conf->cmd == CMD_VALID_PATH) {
-+ /* If you are ignoring the wwids file and find_multipaths is
-+ * set, you need to actually check if there are two available
-+ * paths to determine if this path should be multipathed. To
-+ * do this, we put off the check until after discovering all
-+ * the paths */
-+ if (conf->cmd == CMD_VALID_PATH &&
-+ (!conf->find_multipaths || !conf->ignore_wwids)) {
- if (conf->ignore_wwids ||
- check_wwids_file(refwwid, 0) == 0)
- r = 0;
-@@ -348,6 +357,20 @@ configure (void)
-
- filter_pathvec(pathvec, refwwid);
-
-+
-+ if (conf->cmd == CMD_VALID_PATH) {
-+ /* This only happens if find_multipaths is and
-+ * ignore_wwids is set.
-+ * If there is currently a multipath device matching
-+ * the refwwid, or there is more than one path matching
-+ * the refwwid, then the path is valid */
-+ if (VECTOR_SIZE(curmp) != 0 || VECTOR_SIZE(pathvec) > 1)
-+ r = 0;
-+ printf("%s %s a valid multipath device path\n",
-+ conf->dev, r == 0 ? "is" : "is not");
-+ goto out;
-+ }
-+
- if (conf->cmd != CMD_CREATE && conf->cmd != CMD_DRY_RUN) {
- r = 0;
- goto out;
+++ /dev/null
----
- libmultipath/print.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/print.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/print.c
-+++ multipath-tools-130222/libmultipath/print.c
-@@ -510,6 +510,16 @@ snprint_tgt_wwnn (char * buff, size_t le
- }
-
- static int
-+snprint_host_adapter (char * buff, size_t len, struct path * pp)
-+{
-+ char adapter[SLOT_NAME_SIZE];
-+
-+ if (sysfs_get_host_adapter_name(pp, adapter))
-+ return snprintf(buff, len, "[undef]");
-+ return snprint_str(buff, len, adapter);
-+}
-+
-+static int
- snprint_path_checker (char * buff, size_t len, struct path * pp)
- {
- struct checker * c = &pp->checker;
-@@ -557,6 +567,7 @@ struct path_data pd[] = {
- {'n', "target WWNN", 0, snprint_tgt_wwnn},
- {'R', "host WWPN", 0, snprint_host_wwpn},
- {'r', "target WWPN", 0, snprint_tgt_wwpn},
-+ {'a', "host adapter", 0, snprint_host_adapter},
- {0, NULL, 0 , NULL}
- };
-
+++ /dev/null
----
- multipath/mpathconf | 26 ++++++++++++++++++++------
- 1 file changed, 20 insertions(+), 6 deletions(-)
-
-Index: multipath-tools-130222/multipath/mpathconf
-===================================================================
---- multipath-tools-130222.orig/multipath/mpathconf
-+++ multipath-tools-130222/multipath/mpathconf
-@@ -19,10 +19,27 @@
-
- unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE SHOW_STATUS CHANGED_CONFIG
-
--DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf"
-+DEFAULT_CONFIG="# device-mapper-multipath configuration file
-+
-+# For a complete list of the default configuration values, run either:
-+# # multipath -t
-+# or
-+# # multipathd show config
-+
-+# For a list of configuration options with descriptions, see the
-+# multipath.conf man page.
-+
-+# For an example configuration file, see:
-+# /user/share/doc/device-mapper-multipath/multipath.conf
-+
-+defaults {
-+ user_friendly_names yes
-+ find_multipaths yes
-+}"
-+
- CONFIGFILE="/etc/multipath.conf"
- MULTIPATHDIR="/etc/multipath"
--TMPFILE=/etc/multipath/.multipath.conf.tmp
-+TMPFILE="/etc/multipath/.multipath.conf.tmp"
-
- function usage
- {
-@@ -134,12 +151,9 @@ if [ ! -d "$MULTIPATHDIR" ]; then
- fi
-
- rm $TMPFILE 2> /dev/null
-+echo "$DEFAULT_CONFIG" > $TMPFILE
- if [ -f "$CONFIGFILE" ]; then
- cp $CONFIGFILE $TMPFILE
--elif [ -f "$DEFAULT_CONFIGFILE" ]; then
-- cp $DEFAULT_CONFIGFILE $TMPFILE
--else
-- touch $TMPFILE
- fi
-
- if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
+++ /dev/null
----
- libmultipath/devmapper.c | 155 ++++++++++++++++++-----------------------------
- 1 file changed, 61 insertions(+), 94 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -1006,8 +1006,9 @@ bad:
- return NULL;
- }
-
--int
--dm_remove_partmaps (const char * mapname, int need_sync)
-+static int
-+do_foreach_partmaps (const char * mapname, int (*partmap_func)(char *, void *),
-+ void *data)
- {
- struct dm_task *dmt;
- struct dm_names *names;
-@@ -1059,26 +1060,8 @@ dm_remove_partmaps (const char * mapname
- */
- strstr(params, dev_t)
- ) {
-- /*
-- * then it's a kpartx generated partition.
-- * remove it.
-- */
-- /*
-- * if the opencount is 0 maybe some other
-- * partitions depend on it.
-- */
-- if (dm_get_opencount(names->name)) {
-- dm_remove_partmaps(names->name, need_sync);
-- if (dm_get_opencount(names->name)) {
-- condlog(2, "%s: map in use",
-- names->name);
-- goto out;
-- }
-- }
-- condlog(4, "partition map %s removed",
-- names->name);
-- dm_simplecmd_flush(DM_DEVICE_REMOVE, names->name,
-- need_sync, 0);
-+ if (partmap_func(names->name, data) != 0)
-+ goto out;
- }
-
- next = names->next;
-@@ -1091,6 +1074,35 @@ out:
- return r;
- }
-
-+struct remove_data {
-+ int need_sync;
-+};
-+
-+static int
-+remove_partmap(char *name, void *data)
-+{
-+ struct remove_data *rd = (struct remove_data *)data;
-+
-+ if (dm_get_opencount(name)) {
-+ dm_remove_partmaps(name, rd->need_sync);
-+ if (dm_get_opencount(name)) {
-+ condlog(2, "%s: map in use", name);
-+ return 1;
-+ }
-+ }
-+ condlog(4, "partition map %s removed", name);
-+ dm_simplecmd_flush(DM_DEVICE_REMOVE, name,
-+ rd->need_sync, 0);
-+ return 0;
-+}
-+
-+int
-+dm_remove_partmaps (const char * mapname, int need_sync)
-+{
-+ struct remove_data rd = { need_sync };
-+ return do_foreach_partmaps(mapname, remove_partmap, &rd);
-+}
-+
- static struct dm_info *
- alloc_dminfo (void)
- {
-@@ -1140,86 +1152,41 @@ out:
- return r;
- }
-
--int
--dm_rename_partmaps (char * old, char * new)
-+struct rename_data {
-+ char *old;
-+ char *new;
-+ char *delim;
-+};
-+
-+static int
-+rename_partmap (char *name, void *data)
- {
-- struct dm_task *dmt;
-- struct dm_names *names;
-- unsigned next = 0;
- char buff[PARAMS_SIZE];
-- unsigned long long size;
-- char dev_t[32];
-- int r = 1;
- int offset;
-- char *delim;
--
-- if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
-- return 1;
-+ struct rename_data *rd = (struct rename_data *)data;
-
-- dm_task_no_open_count(dmt);
--
-- if (!dm_task_run(dmt))
-- goto out;
--
-- if (!(names = dm_task_get_names(dmt)))
-- goto out;
--
-- if (!names->dev) {
-- r = 0; /* this is perfectly valid */
-- goto out;
-- }
-+ if (strncmp(name, rd->old, strlen(rd->old)) != 0)
-+ return 0;
-+ for (offset = strlen(rd->old); name[offset] && !(isdigit(name[offset])); offset++); /* do nothing */
-+ snprintf(buff, PARAMS_SIZE, "%s%s%s", rd->new, rd->delim,
-+ name + offset);
-+ dm_rename(name, buff);
-+ condlog(4, "partition map %s renamed", name);
-+ return 0;
-+}
-
-- if (dm_dev_t(old, &dev_t[0], 32))
-- goto out;
-+int
-+dm_rename_partmaps (char * old, char * new)
-+{
-+ struct rename_data rd;
-
-+ rd.old = old;
-+ rd.new = new;
- if (isdigit(new[strlen(new)-1]))
-- delim = "p";
-+ rd.delim = "p";
- else
-- delim = "";
--
-- do {
-- if (
-- /*
-- * if devmap target is "linear"
-- */
-- (dm_type(names->name, TGT_PART) > 0) &&
--
-- /*
-- * and the multipath mapname and the part mapname start
-- * the same
-- */
-- !strncmp(names->name, old, strlen(old)) &&
--
-- /*
-- * and we can fetch the map table from the kernel
-- */
-- !dm_get_map(names->name, &size, &buff[0]) &&
--
-- /*
-- * and the table maps over the multipath map
-- */
-- strstr(buff, dev_t)
-- ) {
-- /*
-- * then it's a kpartx generated partition.
-- * Rename it.
-- */
-- for (offset = strlen(old); names->name[offset] && !(isdigit(names->name[offset])); offset++); /* do nothing */
-- snprintf(buff, PARAMS_SIZE, "%s%s%s",
-- new, delim, names->name + offset);
-- dm_rename(names->name, buff);
-- condlog(4, "partition map %s renamed",
-- names->name);
-- }
--
-- next = names->next;
-- names = (void *) names + next;
-- } while (next);
--
-- r = 0;
--out:
-- dm_task_destroy (dmt);
-- return r;
-+ rd.delim = "";
-+ return do_foreach_partmaps(old, rename_partmap, &rd);
- }
-
- int
+++ /dev/null
----
- libmultipath/Makefile | 6 ++
- libmultipath/config.c | 3 +
- libmultipath/config.h | 3 +
- libmultipath/configure.c | 1
- libmultipath/defaults.h | 1
- libmultipath/devmapper.c | 130 +++++++++++++++++++++++++++++++++++++++------
- libmultipath/devmapper.h | 12 ++--
- libmultipath/dict.c | 116 +++++++++++++++++++++++++++++++++++++++-
- libmultipath/propsel.c | 28 +++++++++
- libmultipath/propsel.h | 1
- libmultipath/structs.h | 8 ++
- libmultipath/structs_vec.c | 3 -
- multipath/multipath.conf.5 | 14 ++++
- multipathd/main.c | 23 +++++--
- 14 files changed, 322 insertions(+), 27 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -337,6 +337,7 @@ merge_hwe (struct hwentry * dst, struct
- merge_num(user_friendly_names);
- merge_num(retain_hwhandler);
- merge_num(detect_prio);
-+ merge_num(deferred_remove);
-
- /*
- * Make sure features is consistent with
-@@ -394,6 +395,7 @@ overwrite_hwe (struct hwentry * dst, str
- overwrite_num(user_friendly_names);
- overwrite_num(retain_hwhandler);
- overwrite_num(detect_prio);
-+ overwrite_num(deferred_remove);
-
- /*
- * Make sure features is consistent with
-@@ -617,6 +619,7 @@ load_config (char * file, struct udev *u
- conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
- conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
- conf->detect_prio = DEFAULT_DETECT_PRIO;
-+ conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
- conf->hw_strmatch = 0;
- conf->force_sync = 0;
-
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -61,6 +61,7 @@ struct hwentry {
- int user_friendly_names;
- int retain_hwhandler;
- int detect_prio;
-+ int deferred_remove;
- char * bl_product;
- };
-
-@@ -84,6 +85,7 @@ struct mpentry {
- int flush_on_last_del;
- int attribute_flags;
- int user_friendly_names;
-+ int deferred_remove;
- uid_t uid;
- gid_t gid;
- mode_t mode;
-@@ -128,6 +130,7 @@ struct config {
- int retain_hwhandler;
- int detect_prio;
- int force_sync;
-+ int deferred_remove;
- unsigned int version[3];
-
- char * dev;
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -290,6 +290,7 @@ setup_map (struct multipath * mpp, char
- select_dev_loss(mpp);
- select_reservation_key(mpp);
- select_retain_hwhandler(mpp);
-+ select_deferred_remove(mpp);
-
- sysfs_set_scsi_tmo(mpp);
- /*
-Index: multipath-tools-130222/libmultipath/defaults.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/defaults.h
-+++ multipath-tools-130222/libmultipath/defaults.h
-@@ -19,6 +19,7 @@
- #define DEFAULT_FAST_IO_FAIL 5
- #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
- #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
-+#define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF
-
- #define DEFAULT_CHECKINT 5
- #define MAX_CHECKINT(a) (a << 2)
-Index: multipath-tools-130222/libmultipath/devmapper.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.c
-+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -103,7 +103,9 @@ dm_lib_prereq (void)
- {
- char version[64];
- int v[3];
--#if defined(DM_SUBSYSTEM_UDEV_FLAG0)
-+#if defined(LIBDM_API_DEFERRED)
-+ int minv[3] = {1, 2, 89};
-+#elif defined(DM_SUBSYSTEM_UDEV_FLAG0)
- int minv[3] = {1, 2, 82};
- #elif defined(LIBDM_API_COOKIE)
- int minv[3] = {1, 2, 38};
-@@ -202,7 +204,7 @@ dm_prereq (void)
- }
-
- static int
--dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags) {
-+dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags, int deferred_remove) {
- int r = 0;
- int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME ||
- task == DM_DEVICE_REMOVE));
-@@ -220,7 +222,10 @@ dm_simplecmd (int task, const char *name
- if (no_flush)
- dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */
- #endif
--
-+#ifdef LIBDM_API_DEFERRED
-+ if (deferred_remove)
-+ dm_task_deferred_remove(dmt);
-+#endif
- if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags))
- goto out;
- r = dm_task_run (dmt);
-@@ -232,12 +237,18 @@ dm_simplecmd (int task, const char *name
-
- extern int
- dm_simplecmd_flush (int task, const char *name, int needsync, uint16_t udev_flags) {
-- return dm_simplecmd(task, name, 0, needsync, udev_flags);
-+ return dm_simplecmd(task, name, 0, needsync, udev_flags, 0);
- }
-
- extern int
- dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) {
-- return dm_simplecmd(task, name, 1, 1, udev_flags);
-+ return dm_simplecmd(task, name, 1, 1, udev_flags, 0);
-+}
-+
-+extern int
-+dm_device_remove (const char *name, int needsync, int deferred_remove) {
-+ return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0,
-+ deferred_remove);
- }
-
- extern int
-@@ -653,7 +664,7 @@ out:
- }
-
- extern int
--_dm_flush_map (const char * mapname, int need_sync)
-+_dm_flush_map (const char * mapname, int need_sync, int deferred_remove)
- {
- int r;
-
-@@ -663,23 +674,46 @@ _dm_flush_map (const char * mapname, int
- if (dm_type(mapname, TGT_MPATH) <= 0)
- return 0; /* nothing to do */
-
-- if (dm_remove_partmaps(mapname, need_sync))
-+ if (dm_remove_partmaps(mapname, need_sync, deferred_remove))
- return 1;
-
-- if (dm_get_opencount(mapname)) {
-+ if (!deferred_remove && dm_get_opencount(mapname)) {
- condlog(2, "%s: map in use", mapname);
- return 1;
- }
-
-- r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname, need_sync, 0);
-+ r = dm_device_remove(mapname, need_sync, deferred_remove);
-
- if (r) {
-+ if (deferred_remove && dm_map_present(mapname)) {
-+ condlog(4, "multipath map %s remove deferred",
-+ mapname);
-+ return 2;
-+ }
- condlog(4, "multipath map %s removed", mapname);
- return 0;
- }
- return 1;
- }
-
-+#ifdef LIBDM_API_DEFERRED
-+
-+int
-+dm_flush_map_nopaths(const char * mapname, int deferred_remove)
-+{
-+ return _dm_flush_map(mapname, 1, deferred_remove);
-+}
-+
-+#else
-+
-+int
-+dm_flush_map_nopaths(const char * mapname, int deferred_remove)
-+{
-+ return _dm_flush_map(mapname, 1, 0);
-+}
-+
-+#endif
-+
- extern int
- dm_suspend_and_flush_map (const char * mapname)
- {
-@@ -1076,6 +1110,7 @@ out:
-
- struct remove_data {
- int need_sync;
-+ int deferred_remove;
- };
-
- static int
-@@ -1084,25 +1119,90 @@ remove_partmap(char *name, void *data)
- struct remove_data *rd = (struct remove_data *)data;
-
- if (dm_get_opencount(name)) {
-- dm_remove_partmaps(name, rd->need_sync);
-- if (dm_get_opencount(name)) {
-+ dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove);
-+ if (!rd->deferred_remove && dm_get_opencount(name)) {
- condlog(2, "%s: map in use", name);
- return 1;
- }
- }
- condlog(4, "partition map %s removed", name);
-- dm_simplecmd_flush(DM_DEVICE_REMOVE, name,
-- rd->need_sync, 0);
-+ dm_device_remove(name, rd->need_sync, rd->deferred_remove);
- return 0;
- }
-
- int
--dm_remove_partmaps (const char * mapname, int need_sync)
-+dm_remove_partmaps (const char * mapname, int need_sync, int deferred_remove)
- {
-- struct remove_data rd = { need_sync };
-+ struct remove_data rd = { need_sync, deferred_remove };
- return do_foreach_partmaps(mapname, remove_partmap, &rd);
- }
-
-+#ifdef LIBDM_API_DEFERRED
-+
-+static int
-+cancel_remove_partmap (char *name, void *unused)
-+{
-+ if (dm_message(name, "@cancel_deferred_remove") != 0)
-+ condlog(0, "%s: can't cancel deferred remove: %s", name,
-+ strerror(errno));
-+ return 0;
-+}
-+
-+static int
-+dm_get_deferred_remove (char * mapname)
-+{
-+ int r = -1;
-+ struct dm_task *dmt;
-+ struct dm_info info;
-+
-+ if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
-+ return -1;
-+
-+ if (!dm_task_set_name(dmt, mapname))
-+ goto out;
-+
-+ if (!dm_task_run(dmt))
-+ goto out;
-+
-+ if (!dm_task_get_info(dmt, &info))
-+ goto out;
-+
-+ r = info.deferred_remove;
-+out:
-+ dm_task_destroy(dmt);
-+ return r;
-+}
-+
-+int
-+dm_cancel_deferred_remove (struct multipath *mpp)
-+{
-+ int r = 0;
-+
-+ if (!dm_get_deferred_remove(mpp->alias))
-+ return 0;
-+ if (mpp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS)
-+ mpp->deferred_remove = DEFERRED_REMOVE_ON;
-+
-+ do_foreach_partmaps(mpp->alias, cancel_remove_partmap, NULL);
-+ r = dm_message(mpp->alias, "@cancel_deferred_remove");
-+ if (r)
-+ condlog(0, "%s: can't cancel deferred remove: %s", mpp->alias,
-+ strerror(errno));
-+ else
-+ condlog(2, "%s: canceled deferred remove", mpp->alias);
-+ return r;
-+}
-+
-+#else
-+
-+int
-+dm_cancel_deferred_remove (struct multipath *mpp)
-+{
-+ return 0;
-+}
-+
-+#endif
-+
- static struct dm_info *
- alloc_dminfo (void)
- {
-Index: multipath-tools-130222/libmultipath/devmapper.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/devmapper.h
-+++ multipath-tools-130222/libmultipath/devmapper.h
-@@ -17,15 +17,18 @@ int dm_prereq (void);
- int dm_drv_version (unsigned int * version, char * str);
- int dm_simplecmd_flush (int, const char *, int, uint16_t);
- int dm_simplecmd_noflush (int, const char *, uint16_t);
-+int dm_device_remove (const char *, int, int);
- int dm_addmap_create (struct multipath *mpp, char *params);
- int dm_addmap_reload (struct multipath *mpp, char *params);
- int dm_map_present (const char *);
- int dm_get_map(const char *, unsigned long long *, char *);
- int dm_get_status(char *, char *);
- int dm_type(const char *, char *);
--int _dm_flush_map (const char *, int);
--#define dm_flush_map(mapname) _dm_flush_map(mapname, 1)
--#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0)
-+int _dm_flush_map (const char *, int, int);
-+int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
-+#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0)
-+#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0, 0)
-+int dm_cancel_deferred_remove(struct multipath *mpp);
- int dm_suspend_and_flush_map(const char * mapname);
- int dm_flush_maps (void);
- int dm_fail_path(char * mapname, char * path);
-@@ -40,7 +43,8 @@ int dm_geteventnr (char *name);
- int dm_get_major (char *name);
- int dm_get_minor (char *name);
- char * dm_mapname(int major, int minor);
--int dm_remove_partmaps (const char * mapname, int need_sync);
-+int dm_remove_partmaps (const char * mapname, int need_sync,
-+ int deferred_remove);
- int dm_get_uuid(char *name, char *uuid);
- int dm_get_info (char * mapname, struct dm_info ** dmi);
- int dm_rename (char * old, char * new);
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -738,6 +738,29 @@ def_force_sync_handler(vector strvec)
- return 0;
- }
-
-+static int
-+def_deferred_remove_handler(vector strvec)
-+{
-+ char * buff;
-+
-+ buff = set_value(strvec);
-+
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ conf->deferred_remove = DEFERRED_REMOVE_OFF;
-+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "1")))
-+ conf->deferred_remove = DEFERRED_REMOVE_ON;
-+ else
-+ conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * blacklist block handlers
- */
-@@ -1445,6 +1468,33 @@ hw_detect_prio_handler(vector strvec)
- return 0;
- }
-
-+static int
-+hw_deferred_remove_handler(vector strvec)
-+{
-+ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
-+ char * buff;
-+
-+ if (!hwe)
-+ return 1;
-+
-+ buff = set_value(strvec);
-+
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ hwe->deferred_remove = DEFERRED_REMOVE_OFF;
-+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "1")))
-+ hwe->deferred_remove = DEFERRED_REMOVE_ON;
-+ else
-+ hwe->deferred_remove = DEFERRED_REMOVE_UNDEF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * multipaths block handlers
- */
-@@ -1920,6 +1970,32 @@ mp_names_handler(vector strvec)
- return 0;
- }
-
-+static int
-+mp_deferred_remove_handler(vector strvec)
-+{
-+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
-+ char * buff;
-+
-+ if (!mpe)
-+ return 1;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
-+ (strlen(buff) == 1 && strcmp(buff, "0") == 0))
-+ mpe->deferred_remove = DEFERRED_REMOVE_OFF;
-+ else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
-+ (strlen(buff) == 1 && strcmp(buff, "1") == 0))
-+ mpe->deferred_remove = DEFERRED_REMOVE_ON;
-+ else
-+ mpe->deferred_remove = DEFERRED_REMOVE_UNDEF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * config file keywords printing
- */
-@@ -2165,7 +2241,7 @@ snprint_mp_reservation_key (char * buff,
- return snprintf(buff, len, "0x%" PRIx64, prkey);
- }
-
-- static int
-+static int
- snprint_mp_user_friendly_names (char * buff, int len, void * data)
- {
- struct mpentry * mpe = (struct mpentry *)data;
-@@ -2179,6 +2255,19 @@ snprint_mp_user_friendly_names (char * b
- }
-
- static int
-+snprint_mp_deferred_remove (char * buff, int len, void * data)
-+{
-+ struct mpentry * mpe = (struct mpentry *)data;
-+
-+ if (mpe->deferred_remove == DEFERRED_REMOVE_UNDEF)
-+ return 0;
-+ else if (mpe->deferred_remove == DEFERRED_REMOVE_OFF)
-+ return snprintf(buff, len, "no");
-+ else
-+ return snprintf(buff, len, "yes");
-+}
-+
-+static int
- snprint_hw_fast_io_fail(char * buff, int len, void * data)
- {
- struct hwentry * hwe = (struct hwentry *)data;
-@@ -2507,6 +2596,19 @@ snprint_hw_retain_hwhandler_handler(char
- }
-
- static int
-+snprint_hw_deferred_remove(char * buff, int len, void * data)
-+{
-+ struct hwentry * hwe = (struct hwentry *)data;
-+
-+ if (hwe->deferred_remove == DEFERRED_REMOVE_ON)
-+ return snprintf(buff, len, "yes");
-+ else if (hwe->deferred_remove == DEFERRED_REMOVE_OFF)
-+ return snprintf(buff, len, "no");
-+ else
-+ return 0;
-+}
-+
-+static int
- snprint_detect_prio(char * buff, int len, void * data)
- {
- struct hwentry * hwe = (struct hwentry *)data;
-@@ -2900,6 +3002,15 @@ snprint_def_force_sync(char * buff, int
- }
-
- static int
-+snprint_def_deferred_remove(char * buff, int len, void * data)
-+{
-+ if (conf->deferred_remove == DEFERRED_REMOVE_ON)
-+ return snprintf(buff, len, "yes");
-+ else
-+ return snprintf(buff, len, "no");
-+}
-+
-+static int
- snprint_ble_simple (char * buff, int len, void * data)
- {
- struct blentry * ble = (struct blentry *)data;
-@@ -2968,6 +3079,7 @@ init_keywords(void)
- install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
- install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
- install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
-+ install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
- __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);
-@@ -3032,6 +3144,7 @@ init_keywords(void)
- install_keyword("user_friendly_names", &hw_names_handler, &snprint_hw_user_friendly_names);
- install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
- install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
-+ install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
- install_sublevel_end();
-
- install_keyword_root("multipaths", &multipaths_handler);
-@@ -3056,5 +3169,6 @@ init_keywords(void)
- install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
- install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
- install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names);
-+ install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove);
- install_sublevel_end();
- }
-Index: multipath-tools-130222/libmultipath/propsel.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.c
-+++ multipath-tools-130222/libmultipath/propsel.c
-@@ -744,6 +744,34 @@ select_retain_hwhandler (struct multipat
- }
-
- extern int
-+select_deferred_remove (struct multipath *mp)
-+{
-+ if (mp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) {
-+ condlog(3, "%s: deferred_remove in progress", mp->alias);
-+ return 0;
-+ }
-+ if (mp->mpe && mp->mpe->deferred_remove) {
-+ mp->deferred_remove = mp->mpe->deferred_remove;
-+ condlog(3, "%s: deferred_remove = %i (multipath setting)",
-+ mp->alias, mp->deferred_remove);
-+ return 0;
-+ }
-+ if (mp->hwe && mp->hwe->deferred_remove) {
-+ mp->deferred_remove = mp->hwe->deferred_remove;
-+ condlog(3, "%s: deferred_remove = %d (controller default)", mp->alias, mp->deferred_remove);
-+ return 0;
-+ }
-+ if (conf->deferred_remove) {
-+ mp->deferred_remove = conf->deferred_remove;
-+ condlog(3, "%s: deferred_remove = %d (config file default)", mp->alias, mp->deferred_remove);
-+ return 0;
-+ }
-+ mp->deferred_remove = DEFAULT_DEFERRED_REMOVE;
-+ condlog(3, "%s: deferred_remove = %d (compiled in default)", mp->alias, mp->deferred_remove);
-+ return 0;
-+}
-+
-+extern int
- select_detect_prio (struct path * pp)
- {
- if (pp->hwe && pp->hwe->detect_prio) {
-Index: multipath-tools-130222/libmultipath/propsel.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.h
-+++ multipath-tools-130222/libmultipath/propsel.h
-@@ -20,3 +20,4 @@ int select_dev_loss(struct multipath *mp
- int select_reservation_key(struct multipath *mp);
- int select_retain_hwhandler (struct multipath * mp);
- int select_detect_prio(struct path * pp);
-+int select_deferred_remove(struct multipath *mp);
-Index: multipath-tools-130222/libmultipath/structs.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs.h
-+++ multipath-tools-130222/libmultipath/structs.h
-@@ -114,6 +114,13 @@ enum detect_prio_states {
- DETECT_PRIO_ON,
- };
-
-+enum deferred_remove_states {
-+ DEFERRED_REMOVE_UNDEF,
-+ DEFERRED_REMOVE_OFF,
-+ DEFERRED_REMOVE_ON,
-+ DEFERRED_REMOVE_IN_PROGRESS,
-+};
-+
- enum scsi_protocol {
- SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */
- SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */
-@@ -207,6 +214,7 @@ struct multipath {
- int attribute_flags;
- int fast_io_fail;
- int retain_hwhandler;
-+ int deferred_remove;
- unsigned int dev_loss;
- uid_t uid;
- gid_t gid;
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -214,19 +214,30 @@ sync_maps_state(vector mpvec)
- }
-
- static int
--flush_map(struct multipath * mpp, struct vectors * vecs)
-+flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
- {
-+ int r;
-+
-+ if (nopaths)
-+ r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
-+ else
-+ r = dm_flush_map(mpp->alias);
- /*
- * clear references to this map before flushing so we can ignore
- * the spurious uevent we may generate with the dm_flush_map call below
- */
-- if (dm_flush_map(mpp->alias)) {
-+ if (r) {
- /*
- * May not really be an error -- if the map was already flushed
- * from the device mapper by dmsetup(8) for instance.
- */
-- condlog(0, "%s: can't flush", mpp->alias);
-- return 1;
-+ if (r == 1)
-+ condlog(0, "%s: can't flush", mpp->alias);
-+ else {
-+ condlog(2, "%s: devmap deferred remove", mpp->alias);
-+ mpp->deferred_remove = DEFERRED_REMOVE_IN_PROGRESS;
-+ }
-+ return r;
- }
- else {
- dm_lib_release();
-@@ -372,7 +383,7 @@ ev_remove_map (char * devname, char * al
- mpp->alias, mpp->dmi->minor, minor);
- return 0;
- }
-- return flush_map(mpp, vecs);
-+ return flush_map(mpp, vecs, 0);
- }
-
- static int
-@@ -628,7 +639,7 @@ ev_remove_path (struct path *pp, struct
- mpp->flush_on_last_del = FLUSH_IN_PROGRESS;
- dm_queue_if_no_path(mpp->alias, 0);
- }
-- if (!flush_map(mpp, vecs)) {
-+ if (!flush_map(mpp, vecs, 1)) {
- condlog(2, "%s: removed map after"
- " removing all paths",
- alias);
-Index: multipath-tools-130222/libmultipath/structs_vec.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs_vec.c
-+++ multipath-tools-130222/libmultipath/structs_vec.c
-@@ -392,6 +392,8 @@ __setup_multipath (struct vectors * vecs
- set_no_path_retry(mpp);
- select_pg_timeout(mpp);
- select_flush_on_last_del(mpp);
-+ if (VECTOR_SIZE(mpp->paths) != 0)
-+ dm_cancel_deferred_remove(mpp);
- }
-
- return 0;
-@@ -565,7 +567,6 @@ int update_multipath (struct vectors *ve
- }
- }
- }
--
- return 0;
- }
-
-Index: multipath-tools-130222/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.conf.5
-+++ multipath-tools-130222/multipath/multipath.conf.5
-@@ -420,6 +420,16 @@ only one checker will run at a time. Th
- multipathd checkers running in parallel causes significant CPU pressure. The
- Default is
- .I no
-+.TP
-+.B deferred_remove
-+If set to
-+.I yes
-+, multipathd will do a deferred remove instead of a regular remove when the
-+last path device has been deleted. This means that if the multipath device is
-+still in use, it will be freed when the last user closes it. If path is added
-+to the multipath device before the last user closes it, the deferred remove
-+will be canceled. Default is
-+.I no
- .
- .SH "blacklist section"
- The
-@@ -521,6 +531,8 @@ section:
- .B features
- .TP
- .B reservation_key
-+.TP
-+.B deferred_remove
- .RE
- .PD
- .LP
-@@ -611,6 +623,8 @@ section:
- .B retain_attached_hw_handler
- .TP
- .B detect_prio
-+.TP
-+.B deferred_remove
- .RE
- .PD
- .LP
-Index: multipath-tools-130222/libmultipath/Makefile
-===================================================================
---- multipath-tools-130222.orig/libmultipath/Makefile
-+++ multipath-tools-130222/libmultipath/Makefile
-@@ -36,6 +36,12 @@ ifneq ($(strip $(LIBUDEV_API_RECVBUF)),0
- CFLAGS += -DLIBUDEV_API_RECVBUF
- endif
-
-+LIBDM_API_DEFERRED = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_deferred_remove' /usr/include/libdevmapper.h)
-+
-+ifneq ($(strip $(LIBDM_API_DEFERRED)),0)
-+ CFLAGS += -DLIBDM_API_DEFERRED
-+endif
-+
-
- all: $(LIBS)
-
+++ /dev/null
-diff -purN multipath-tools-130222.orig/multipath/multipath.rules multipath-tools-130222/multipath/multipath.rules
---- multipath-tools-130222.orig/multipath/multipath.rules 2014-11-03 14:37:41.269413134 +0100
-+++ multipath-tools-130222/multipath/multipath.rules 2014-11-03 14:38:43.694281901 +0100
-@@ -45,5 +45,5 @@ ACTION!="change", GOTO="end_mpath"
- ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
- ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
- ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
--RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
-+ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
- LABEL="end_mpath"
+++ /dev/null
----
- multipathd/main.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -669,9 +669,8 @@ ev_remove_path (struct path *pp, struct
- /*
- * update our state from kernel
- */
-- if (setup_multipath(vecs, mpp)) {
-- goto fail;
-- }
-+ if (setup_multipath(vecs, mpp))
-+ return 1;
- sync_map_state(mpp);
-
- condlog(2, "%s [%s]: path removed from map %s",
+++ /dev/null
----
- libmultipath/config.c | 4 ++++
- libmultipath/config.h | 1 +
- libmultipath/configure.c | 5 ++---
- libmultipath/dict.c | 33 +++++++++++++++++++++++++++++++++
- libmultipath/util.c | 30 ++++++++++++++++++++++++++++++
- libmultipath/util.h | 1 +
- libmultipath/wwids.c | 21 ++++++++++++++-------
- multipathd/main.c | 3 +--
- 8 files changed, 86 insertions(+), 12 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -131,6 +131,7 @@ struct config {
- int detect_prio;
- int force_sync;
- int deferred_remove;
-+ int ignore_new_boot_devs;
- unsigned int version[3];
-
- char * dev;
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -775,9 +775,8 @@ coalesce_paths (struct vectors * vecs, v
- if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
- continue;
-
-- /* If find_multipaths was selected check if the path is valid */
-- if (conf->find_multipaths && !refwwid &&
-- !should_multipath(pp1, pathvec)) {
-+ /* check if the path is valid */
-+ if (!refwwid && !should_multipath(pp1, pathvec)) {
- orphan_path(pp1);
- continue;
- }
-Index: multipath-tools-130222/libmultipath/wwids.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/wwids.c
-+++ multipath-tools-130222/libmultipath/wwids.c
-@@ -15,6 +15,7 @@
- #include "wwids.h"
- #include "defaults.h"
- #include "config.h"
-+#include "util.h"
-
- /*
- * Copyright (c) 2010 Benjamin Marzinski, Redhat
-@@ -268,15 +269,21 @@ should_multipath(struct path *pp1, vecto
- {
- int i;
- struct path *pp2;
-+ int ignore_new_devs = (conf->ignore_new_boot_devs && in_initrd());
-+
-+ if (!conf->find_multipaths && !ignore_new_devs)
-+ return 1;
-
- condlog(4, "checking if %s should be multipathed", pp1->dev);
-- vector_foreach_slot(pathvec, pp2, i) {
-- if (pp1->dev == pp2->dev)
-- continue;
-- if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
-- condlog(3, "found multiple paths with wwid %s, "
-- "multipathing %s", pp1->wwid, pp1->dev);
-- return 1;
-+ if (!ignore_new_devs) {
-+ vector_foreach_slot(pathvec, pp2, i) {
-+ if (pp1->dev == pp2->dev)
-+ continue;
-+ if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
-+ condlog(3, "found multiple paths with wwid %s, "
-+ "multipathing %s", pp1->wwid, pp1->dev);
-+ return 1;
-+ }
- }
- }
- if (check_wwids_file(pp1->wwid, 0) < 0) {
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -503,8 +503,7 @@ rescan:
- return 1;
- }
-
-- if (conf->find_multipaths &&
-- !should_multipath(pp, vecs->pathvec)) {
-+ if (!should_multipath(pp, vecs->pathvec)) {
- orphan_path(pp);
- return 0;
- }
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -622,6 +622,7 @@ load_config (char * file, struct udev *u
- conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
- conf->hw_strmatch = 0;
- conf->force_sync = 0;
-+ conf->ignore_new_boot_devs = 0;
-
- /*
- * preload default hwtable
-@@ -732,6 +733,9 @@ load_config (char * file, struct udev *u
- !conf->wwids_file)
- goto out;
-
-+ if (conf->ignore_new_boot_devs)
-+ in_initrd();
-+
- return 0;
- out:
- free_config(conf);
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -761,6 +761,29 @@ def_deferred_remove_handler(vector strve
- return 0;
- }
-
-+static int
-+def_ignore_new_boot_devs_handler(vector strvec)
-+{
-+ char * buff;
-+
-+ buff = set_value(strvec);
-+
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ conf->ignore_new_boot_devs = 0;
-+ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "1")))
-+ conf->ignore_new_boot_devs = 1;
-+ else
-+ conf->ignore_new_boot_devs = 0;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * blacklist block handlers
- */
-@@ -3011,6 +3034,15 @@ snprint_def_deferred_remove(char * buff,
- }
-
- static int
-+snprint_def_ignore_new_boot_devs(char * buff, int len, void * data)
-+{
-+ if (conf->ignore_new_boot_devs == 1)
-+ return snprintf(buff, len, "yes");
-+ else
-+ return snprintf(buff, len, "no");
-+}
-+
-+static int
- snprint_ble_simple (char * buff, int len, void * data)
- {
- struct blentry * ble = (struct blentry *)data;
-@@ -3080,6 +3112,7 @@ init_keywords(void)
- install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
- install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
- install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
-+ install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
- __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);
-Index: multipath-tools-130222/libmultipath/util.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/util.c
-+++ multipath-tools-130222/libmultipath/util.c
-@@ -3,6 +3,8 @@
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
-+#include <sys/vfs.h>
-+#include <linux/magic.h>
-
- #include "debug.h"
- #include "memory.h"
-@@ -267,3 +269,31 @@ dev_t parse_devt(const char *dev_t)
-
- return makedev(maj, min);
- }
-+
-+/* This define was taken from systemd. src/shared/macro.h */
-+#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
-+
-+/* This function was taken from systemd. src/shared/util.c */
-+int in_initrd(void) {
-+ static int saved = -1;
-+ struct statfs s;
-+
-+ if (saved >= 0)
-+ return saved;
-+
-+ /* We make two checks here:
-+ *
-+ * 1. the flag file /etc/initrd-release must exist
-+ * 2. the root file system must be a memory file system
-+ * The second check is extra paranoia, since misdetecting an
-+ * initrd can have bad bad consequences due the initrd
-+ * emptying when transititioning to the main systemd.
-+ */
-+
-+ saved = access("/etc/initrd-release", F_OK) >= 0 &&
-+ statfs("/", &s) >= 0 &&
-+ (F_TYPE_EQUAL(s.f_type, TMPFS_MAGIC) ||
-+ F_TYPE_EQUAL(s.f_type, RAMFS_MAGIC));
-+
-+ return saved;
-+}
-Index: multipath-tools-130222/libmultipath/util.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/util.h
-+++ multipath-tools-130222/libmultipath/util.h
-@@ -11,6 +11,7 @@ void remove_trailing_chars(char *path, c
- int devt2devname (char *, int, char *);
- dev_t parse_devt(const char *dev_t);
- char *convert_dev(char *dev, int is_path_device);
-+int in_initrd(void);
-
- #define safe_sprintf(var, format, args...) \
- snprintf(var, sizeof(var), format, ##args) >= sizeof(var)
+++ /dev/null
----
- multipath/multipath.rules | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipath/multipath.rules
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.rules
-+++ multipath-tools-130222/multipath/multipath.rules
-@@ -45,5 +45,5 @@ ACTION!="change", GOTO="end_mpath"
- ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
- ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
- ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
--ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode"
-+ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -u $tempnode"
- LABEL="end_mpath"
+++ /dev/null
----
- multipathd/main.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -1879,7 +1879,7 @@ main (int argc, char *argv[])
- if (!conf)
- exit(1);
-
-- while ((arg = getopt(argc, argv, ":dv:k::")) != EOF ) {
-+ while ((arg = getopt(argc, argv, ":dv:k::B")) != EOF ) {
- switch(arg) {
- case 'd':
- logsink = 0;
-@@ -1895,6 +1895,9 @@ main (int argc, char *argv[])
- case 'k':
- uxclnt(optarg);
- exit(0);
-+ case 'B':
-+ conf->bindings_read_only = 1;
-+ break;
- default:
- ;
- }
+++ /dev/null
----
- libmultipath/blacklist.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: multipath-tools-130222/libmultipath/blacklist.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/blacklist.c
-+++ multipath-tools-130222/libmultipath/blacklist.c
-@@ -169,7 +169,7 @@ setup_default_blist (struct config * con
- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
- return 1;
-
-- str = STRDUP("^(td|hd)[a-z]");
-+ str = STRDUP("^(td|hd|vd)[a-z]");
- if (!str)
- return 1;
- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
+++ /dev/null
----
- libmultipath/dict.c | 97 ----------------------------------------------------
- 1 file changed, 97 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -473,26 +473,6 @@ def_checker_timeout_handler(vector strve
- static int
- def_pg_timeout_handler(vector strvec)
- {
-- int pg_timeout;
-- char * buff;
--
-- buff = set_value(strvec);
--
-- if (!buff)
-- return 1;
--
-- if (strlen(buff) == 4 && !strcmp(buff, "none"))
-- conf->pg_timeout = -PGTIMEOUT_NONE;
-- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
-- if (pg_timeout == 0)
-- conf->pg_timeout = -PGTIMEOUT_NONE;
-- else
-- conf->pg_timeout = pg_timeout;
-- }
-- else
-- conf->pg_timeout = PGTIMEOUT_UNDEF;
--
-- FREE(buff);
- return 0;
- }
-
-@@ -1358,30 +1338,6 @@ hw_minio_rq_handler(vector strvec)
- static int
- hw_pg_timeout_handler(vector strvec)
- {
-- int pg_timeout;
-- struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
-- char *buff;
--
-- if (!hwe)
-- return 1;
--
-- buff = set_value(strvec);
--
-- if (!buff)
-- return 1;
--
-- if (strlen(buff) == 4 && !strcmp(buff, "none"))
-- hwe->pg_timeout = -PGTIMEOUT_NONE;
-- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
-- if (pg_timeout == 0)
-- hwe->pg_timeout = -PGTIMEOUT_NONE;
-- else
-- hwe->pg_timeout = pg_timeout;
-- }
-- else
-- hwe->pg_timeout = PGTIMEOUT_UNDEF;
--
-- FREE(buff);
- return 0;
- }
-
-@@ -1819,29 +1775,6 @@ mp_minio_rq_handler(vector strvec)
- static int
- mp_pg_timeout_handler(vector strvec)
- {
-- int pg_timeout;
-- struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
-- char *buff;
--
-- if (!mpe)
-- return 1;
--
-- buff = set_value(strvec);
--
-- if (!buff)
-- return 1;
-- if (strlen(buff) == 4 && !strcmp(buff, "none"))
-- mpe->pg_timeout = -PGTIMEOUT_NONE;
-- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
-- if (pg_timeout == 0)
-- mpe->pg_timeout = -PGTIMEOUT_NONE;
-- else
-- mpe->pg_timeout = pg_timeout;
-- }
-- else
-- mpe->pg_timeout = PGTIMEOUT_UNDEF;
--
-- FREE(buff);
- return 0;
- }
-
-@@ -2180,16 +2113,6 @@ snprint_mp_rr_min_io_rq (char * buff, in
- static int
- snprint_mp_pg_timeout (char * buff, int len, void * data)
- {
-- struct mpentry * mpe = (struct mpentry *)data;
--
-- switch (mpe->pg_timeout) {
-- case PGTIMEOUT_UNDEF:
-- break;
-- case -PGTIMEOUT_NONE:
-- return snprintf(buff, len, "\"none\"");
-- default:
-- return snprintf(buff, len, "%i", mpe->pg_timeout);
-- }
- return 0;
- }
-
-@@ -2551,19 +2474,6 @@ snprint_hw_rr_min_io_rq (char * buff, in
- static int
- snprint_hw_pg_timeout (char * buff, int len, void * data)
- {
-- struct hwentry * hwe = (struct hwentry *)data;
--
-- if (!hwe->pg_timeout)
-- return 0;
--
-- switch (hwe->pg_timeout) {
-- case PGTIMEOUT_UNDEF:
-- break;
-- case -PGTIMEOUT_NONE:
-- return snprintf(buff, len, "\"none\"");
-- default:
-- return snprintf(buff, len, "%i", hwe->pg_timeout);
-- }
- return 0;
- }
-
-@@ -2895,13 +2805,6 @@ snprint_def_checker_timeout (char *buff,
- static int
- snprint_def_pg_timeout (char * buff, int len, void * data)
- {
-- switch (conf->pg_timeout) {
-- case PGTIMEOUT_UNDEF:
-- case -PGTIMEOUT_NONE:
-- return snprintf(buff, len, "\"none\"");
-- default:
-- return snprintf(buff, len, "%i", conf->pg_timeout);
-- }
- return 0;
- }
-
+++ /dev/null
----
- libmultipath/config.c | 56 +++++++++++++++++++++++++++++++-
- libmultipath/config.h | 2 +
- libmultipath/defaults.h | 1
- libmultipath/dict.c | 69 +++++++++++++++++++++++++++++++++++----
- libmultipath/parser.c | 78 +++++++++++++++++++++++----------------------
- libmultipath/parser.h | 3 -
- multipath.conf.annotated | 10 +++++
- multipath.conf.defaults | 1
- multipath/multipath.conf.5 | 7 ++++
- 9 files changed, 179 insertions(+), 48 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/parser.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/parser.c
-+++ multipath-tools-130222/libmultipath/parser.c
-@@ -18,6 +18,7 @@
- */
-
- #include <syslog.h>
-+#include <errno.h>
-
- #include "parser.h"
- #include "memory.h"
-@@ -453,14 +454,15 @@ set_value(vector strvec)
- /* non-recursive configuration stream handler */
- static int kw_level = 0;
-
--int warn_on_duplicates(vector uniques, char *str)
-+int warn_on_duplicates(vector uniques, char *str, char *file)
- {
- char *tmp;
- int i;
-
- vector_foreach_slot(uniques, tmp, i) {
- if (!strcmp(str, tmp)) {
-- condlog(1, "multipath.conf line %d, duplicate keyword: %s", line_nr, str);
-+ condlog(1, "%s line %d, duplicate keyword: %s",
-+ file, line_nr, str);
- return 0;
- }
- }
-@@ -496,65 +498,70 @@ is_sublevel_keyword(char *str)
- }
-
- int
--validate_config_strvec(vector strvec)
-+validate_config_strvec(vector strvec, char *file)
- {
- char *str;
- int i;
-
- str = VECTOR_SLOT(strvec, 0);
- if (str == NULL) {
-- condlog(0, "can't parse option on line %d of config file",
-- line_nr);
-+ condlog(0, "can't parse option on line %d of %s",
-+ line_nr, file);
- return -1;
- }
- if (*str == '}') {
- if (VECTOR_SIZE(strvec) > 1)
-- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr);
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 1), line_nr, file);
- return 0;
- }
- if (*str == '{') {
-- condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr);
-+ condlog(0, "invalid keyword '%s' on line %d of %s",
-+ str, line_nr, file);
- return -1;
- }
- if (is_sublevel_keyword(str)) {
- str = VECTOR_SLOT(strvec, 1);
- if (str == NULL)
-- condlog(0, "missing '{' on line %d of config file", line_nr);
-+ condlog(0, "missing '{' on line %d of %s",
-+ line_nr, file);
- else if (*str != '{')
-- condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str);
-+ condlog(0, "expecting '{' on line %d of %s. found '%s'",
-+ line_nr, file, str);
- else if (VECTOR_SIZE(strvec) > 2)
-- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file);
- return 0;
- }
- str = VECTOR_SLOT(strvec, 1);
- if (str == NULL) {
-- condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr);
-+ condlog(0, "missing value for option '%s' on line %d of %s",
-+ (char *)VECTOR_SLOT(strvec, 0), line_nr, file);
- return -1;
- }
- if (*str != '"') {
- if (VECTOR_SIZE(strvec) > 2)
-- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr);
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file);
- return 0;
- }
- for (i = 2; i < VECTOR_SIZE(strvec); i++) {
- str = VECTOR_SLOT(strvec, i);
- if (str == NULL) {
-- condlog(0, "can't parse value on line %d of config file", line_nr);
-+ condlog(0, "can't parse value on line %d of %s",
-+ line_nr, file);
- return -1;
- }
- if (*str == '"') {
- if (VECTOR_SIZE(strvec) > i + 1)
-- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr);
-+ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr, file);
- return 0;
- }
- }
-- condlog(0, "missing closing quotes on line %d of config file",
-- line_nr);
-+ condlog(0, "missing closing quotes on line %d of %s",
-+ line_nr, file);
- return 0;
- }
-
--int
--process_stream(vector keywords)
-+static int
-+process_stream(vector keywords, char *file)
- {
- int i;
- int r = 0;
-@@ -583,7 +590,7 @@ process_stream(vector keywords)
- if (!strvec)
- continue;
-
-- if (validate_config_strvec(strvec) != 0) {
-+ if (validate_config_strvec(strvec, file) != 0) {
- free_strvec(strvec);
- continue;
- }
-@@ -595,8 +602,8 @@ process_stream(vector keywords)
- free_strvec(strvec);
- break;
- }
-- condlog(0, "unmatched '%s' at line %d of config file",
-- EOB, line_nr);
-+ condlog(0, "unmatched '%s' at line %d of %s",
-+ EOB, line_nr, file);
- }
-
- for (i = 0; i < VECTOR_SIZE(keywords); i++) {
-@@ -604,7 +611,7 @@ process_stream(vector keywords)
-
- if (!strcmp(keyword->string, str)) {
- if (keyword->unique &&
-- warn_on_duplicates(uniques, str)) {
-+ warn_on_duplicates(uniques, str, file)) {
- r = 1;
- free_strvec(strvec);
- goto out;
-@@ -614,15 +621,15 @@ process_stream(vector keywords)
-
- if (keyword->sub) {
- kw_level++;
-- r += process_stream(keyword->sub);
-+ r += process_stream(keyword->sub, file);
- kw_level--;
- }
- break;
- }
- }
- if (i >= VECTOR_SIZE(keywords))
-- condlog(1, "multipath.conf +%d, invalid keyword: %s",
-- line_nr, str);
-+ condlog(1, "%s line %d, invalid keyword: %s",
-+ file, line_nr, str);
-
- free_strvec(strvec);
- }
-@@ -646,27 +653,24 @@ int alloc_keywords(void)
-
- /* Data initialization */
- int
--init_data(char *conf_file, void (*init_keywords) (void))
-+process_file(char *file)
- {
- int r;
-
-- stream = fopen(conf_file, "r");
-+ if (!keywords) {
-+ condlog(0, "No keywords alocated");
-+ return 1;
-+ }
-+ stream = fopen(file, "r");
- if (!stream) {
-- syslog(LOG_WARNING, "Configuration file open problem");
-+ condlog(0, "couldn't open configuration file '%s': %s",
-+ file, strerror(errno));
- return 1;
- }
-
-- /* Init Keywords structure */
-- (*init_keywords) ();
--
--/* Dump configuration *
-- vector_dump(keywords);
-- dump_keywords(keywords, 0);
--*/
--
- /* Stream handling */
- line_nr = 0;
-- r = process_stream(keywords);
-+ r = process_stream(keywords, file);
- fclose(stream);
- //free_keywords(keywords);
-
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -117,6 +117,8 @@ reassign_maps_handler(vector strvec)
- static int
- multipath_dir_handler(vector strvec)
- {
-+ if (conf->multipath_dir)
-+ FREE(conf->multipath_dir);
- conf->multipath_dir = set_value(strvec);
-
- if (!conf->multipath_dir)
-@@ -128,6 +130,8 @@ multipath_dir_handler(vector strvec)
- static int
- def_selector_handler(vector strvec)
- {
-+ if (conf->selector)
-+ FREE(conf->selector);
- conf->selector = set_value(strvec);
-
- if (!conf->selector)
-@@ -155,6 +159,8 @@ def_pgpolicy_handler(vector strvec)
- static int
- def_uid_attribute_handler(vector strvec)
- {
-+ if (conf->uid_attribute)
-+ FREE(conf->uid_attribute);
- conf->uid_attribute = set_value(strvec);
-
- if (!conf->uid_attribute)
-@@ -166,6 +172,8 @@ def_uid_attribute_handler(vector strvec)
- static int
- def_prio_handler(vector strvec)
- {
-+ if (conf->prio_name)
-+ FREE(conf->prio_name);
- conf->prio_name = set_value(strvec);
-
- if (!conf->prio_name)
-@@ -177,6 +185,8 @@ def_prio_handler(vector strvec)
- static int
- def_alias_prefix_handler(vector strvec)
- {
-+ if (conf->alias_prefix)
-+ FREE(conf->alias_prefix);
- conf->alias_prefix = set_value(strvec);
-
- if (!conf->alias_prefix)
-@@ -188,6 +198,8 @@ def_alias_prefix_handler(vector strvec)
- static int
- def_prio_args_handler(vector strvec)
- {
-+ if (conf->prio_args)
-+ FREE(conf->prio_args);
- conf->prio_args = set_value(strvec);
-
- if (!conf->prio_args)
-@@ -199,6 +211,8 @@ def_prio_args_handler(vector strvec)
- static int
- def_features_handler(vector strvec)
- {
-+ if (conf->features)
-+ FREE(conf->features);
- conf->features = set_value(strvec);
-
- if (!conf->features)
-@@ -210,6 +224,8 @@ def_features_handler(vector strvec)
- static int
- def_path_checker_handler(vector strvec)
- {
-+ if (conf->checker_name)
-+ FREE(conf->checker_name);
- conf->checker_name = set_value(strvec);
-
- if (!conf->checker_name)
-@@ -432,6 +448,23 @@ def_no_path_retry_handler(vector strvec)
- return 0;
- }
-
-+
-+static int
-+def_config_dir_handler(vector strvec)
-+{
-+ /* this is only valid in the main config file */
-+ if (conf->processed_main_config)
-+ return 0;
-+ if (conf->config_dir)
-+ FREE(conf->config_dir);
-+ conf->config_dir = set_value(strvec);
-+
-+ if (!conf->config_dir)
-+ return 1;
-+
-+ return 0;
-+}
-+
- static int
- def_queue_without_daemon(vector strvec)
- {
-@@ -611,6 +644,8 @@ def_names_handler(vector strvec)
- static int
- bindings_file_handler(vector strvec)
- {
-+ if (conf->bindings_file)
-+ FREE(conf->bindings_file);
- conf->bindings_file = set_value(strvec);
-
- if (!conf->bindings_file)
-@@ -622,6 +657,8 @@ bindings_file_handler(vector strvec)
- static int
- wwids_file_handler(vector strvec)
- {
-+ if (conf->wwids_file)
-+ FREE(conf->wwids_file);
- conf->wwids_file = set_value(strvec);
-
- if (!conf->wwids_file)
-@@ -770,9 +807,12 @@ def_ignore_new_boot_devs_handler(vector
- static int
- blacklist_handler(vector strvec)
- {
-- conf->blist_devnode = vector_alloc();
-- conf->blist_wwid = vector_alloc();
-- conf->blist_device = vector_alloc();
-+ if (!conf->blist_devnode)
-+ conf->blist_devnode = vector_alloc();
-+ if (!conf->blist_wwid)
-+ conf->blist_wwid = vector_alloc();
-+ if (!conf->blist_device)
-+ conf->blist_device = vector_alloc();
-
- if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device)
- return 1;
-@@ -783,9 +823,12 @@ blacklist_handler(vector strvec)
- static int
- blacklist_exceptions_handler(vector strvec)
- {
-- conf->elist_devnode = vector_alloc();
-- conf->elist_wwid = vector_alloc();
-- conf->elist_device = vector_alloc();
-+ if (!conf->elist_devnode)
-+ conf->elist_devnode = vector_alloc();
-+ if (!conf->elist_wwid)
-+ conf->elist_wwid = vector_alloc();
-+ if (!conf->elist_device)
-+ conf->elist_device = vector_alloc();
-
- if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device)
- return 1;
-@@ -1480,7 +1523,8 @@ hw_deferred_remove_handler(vector strvec
- static int
- multipaths_handler(vector strvec)
- {
-- conf->mptable = vector_alloc();
-+ if (!conf->mptable)
-+ conf->mptable = vector_alloc();
-
- if (!conf->mptable)
- return 1;
-@@ -2945,6 +2989,16 @@ snprint_def_ignore_new_boot_devs(char *
- return snprintf(buff, len, "no");
- }
-
-+
-+static int
-+snprint_def_config_dir (char * buff, int len, void * data)
-+{
-+ if (!conf->config_dir)
-+ return 0;
-+
-+ return snprintf(buff, len, "\"%s\"", conf->config_dir);
-+}
-+
- static int
- snprint_ble_simple (char * buff, int len, void * data)
- {
-@@ -3016,6 +3070,7 @@ init_keywords(void)
- install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
- install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
- install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
-+ install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
- __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);
-Index: multipath-tools-130222/libmultipath/parser.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/parser.h
-+++ multipath-tools-130222/libmultipath/parser.h
-@@ -76,9 +76,8 @@ extern int read_line(char *buf, int size
- extern vector read_value_block(void);
- extern int alloc_value_block(vector strvec, void (*alloc_func) (vector));
- extern void *set_value(vector strvec);
--extern int process_stream(vector keywords);
- extern int alloc_keywords(void);
--extern int init_data(char *conf_file, void (*init_keywords) (void));
-+extern int process_file(char *conf_file);
- extern struct keyword * find_keyword(vector v, char * name);
- void set_current_keywords (vector *k);
- int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw,
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -6,6 +6,9 @@
- #include <stdio.h>
- #include <string.h>
- #include <libudev.h>
-+#include <dirent.h>
-+#include <limits.h>
-+#include <errno.h>
-
- #include "checkers.h"
- #include "memory.h"
-@@ -556,6 +559,7 @@ free_config (struct config * conf)
-
- if (conf->wwids_file)
- FREE(conf->wwids_file);
-+
- if (conf->prio_name)
- FREE(conf->prio_name);
-
-@@ -567,6 +571,10 @@ free_config (struct config * conf)
-
- if (conf->checker_name)
- FREE(conf->checker_name);
-+
-+ if (conf->config_dir)
-+ FREE(conf->config_dir);
-+
- if (conf->reservation_key)
- FREE(conf->reservation_key);
-
-@@ -584,6 +592,43 @@ free_config (struct config * conf)
- FREE(conf);
- }
-
-+/* if multipath fails to process the config directory, it should continue,
-+ * with just a warning message */
-+static void
-+process_config_dir(vector keywords, char *dir)
-+{
-+ struct dirent **namelist;
-+ int i, n;
-+ char path[LINE_MAX];
-+ int old_hwtable_size;
-+
-+ if (dir[0] != '/') {
-+ condlog(1, "config_dir '%s' must be a fully qualified path",
-+ dir);
-+ return;
-+ }
-+ n = scandir(dir, &namelist, NULL, alphasort);
-+ if (n < 0) {
-+ if (errno == ENOENT)
-+ condlog(3, "No configuration dir '%s'", dir);
-+ else
-+ condlog(0, "couldn't open configuration dir '%s': %s",
-+ dir, strerror(errno));
-+ return;
-+ }
-+ for (i = 0; i < n; i++) {
-+ if (!strstr(namelist[i]->d_name, ".conf"))
-+ continue;
-+ old_hwtable_size = VECTOR_SIZE(conf->hwtable);
-+ snprintf(path, LINE_MAX, "%s/%s", dir, namelist[i]->d_name);
-+ path[LINE_MAX-1] = '\0';
-+ process_file(path);
-+ if (VECTOR_SIZE(conf->hwtable) > old_hwtable_size)
-+ factorize_hwtable(conf->hwtable, old_hwtable_size);
-+
-+ }
-+}
-+
- int
- load_config (char * file, struct udev *udev)
- {
-@@ -623,6 +668,7 @@ load_config (char * file, struct udev *u
- conf->hw_strmatch = 0;
- conf->force_sync = 0;
- conf->ignore_new_boot_devs = 0;
-+ conf->processed_main_config = 0;
-
- /*
- * preload default hwtable
-@@ -641,11 +687,12 @@ load_config (char * file, struct udev *u
- */
- set_current_keywords(&conf->keywords);
- alloc_keywords();
-+ init_keywords();
- if (filepresent(file)) {
- int builtin_hwtable_size;
-
- builtin_hwtable_size = VECTOR_SIZE(conf->hwtable);
-- if (init_data(file, init_keywords)) {
-+ if (process_file(file)) {
- condlog(0, "error parsing config file");
- goto out;
- }
-@@ -658,7 +705,6 @@ load_config (char * file, struct udev *u
- }
-
- } else {
-- init_keywords();
- condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
- condlog(0, "A default multipath.conf file is located at");
- condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
-@@ -677,6 +723,12 @@ load_config (char * file, struct udev *u
- }
- }
-
-+ conf->processed_main_config = 1;
-+ if (conf->config_dir == NULL)
-+ conf->config_dir = set_default(DEFAULT_CONFIG_DIR);
-+ if (conf->config_dir && conf->config_dir[0] != '\0')
-+ process_config_dir(conf->keywords, conf->config_dir);
-+
- /*
- * fill the voids left in the config file
- */
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -132,6 +132,7 @@ struct config {
- int force_sync;
- int deferred_remove;
- int ignore_new_boot_devs;
-+ int processed_main_config;
- unsigned int version[3];
-
- char * dev;
-@@ -147,6 +148,7 @@ struct config {
- char * prio_args;
- char * checker_name;
- char * alias_prefix;
-+ char * config_dir;
- unsigned char * reservation_key;
-
- vector keywords;
-Index: multipath-tools-130222/libmultipath/defaults.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/defaults.h
-+++ multipath-tools-130222/libmultipath/defaults.h
-@@ -31,5 +31,6 @@
- #define DEFAULT_CONFIGFILE "/etc/multipath.conf"
- #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
- #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
-+#define DEFAULT_CONFIG_DIR "/etc/multipath/conf.d"
-
- char * set_default (char * str);
-Index: multipath-tools-130222/multipath.conf.annotated
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.annotated
-+++ multipath-tools-130222/multipath.conf.annotated
-@@ -232,6 +232,16 @@
- # # values : yes|no
- # # default : no
- # force_sync yes
-+#
-+# #
-+# # name : config_dir
-+# # scope : multipath & multipathd
-+# # desc : If not set to an empty string, multipath will search
-+# # this directory alphabetically for files ending in ".conf"
-+# # and it will read configuration information from these
-+# # files, just as if it was in /etc/multipath.conf
-+# # values : "" or a fully qualified pathname
-+# # default : "/etc/multipath/conf.d"
- #}
- #
- ##
-Index: multipath-tools-130222/multipath.conf.defaults
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.defaults
-+++ multipath-tools-130222/multipath.conf.defaults
-@@ -26,6 +26,7 @@
- # log_checker_err always
- # retain_attached_hw_handler no
- # detect_prio no
-+# config_dir "/etc/multipath/conf.d"
- #}
- #blacklist {
- # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
-Index: multipath-tools-130222/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.conf.5
-+++ multipath-tools-130222/multipath/multipath.conf.5
-@@ -430,6 +430,13 @@ still in use, it will be freed when the
- to the multipath device before the last user closes it, the deferred remove
- will be canceled. Default is
- .I no
-+.TP
-+.B config_dir
-+If set to anything other than "", multipath will search this directory
-+alphabetically for file ending in ".conf" and it will read configuration
-+information from them, just as if it was in /etc/multipath.conf. config_dir
-+must either be "" or a fully qualified directory name. Default is
-+.I "/etc/multipath/conf.d"
- .
- .SH "blacklist section"
- The
+++ /dev/null
----
- libmultipath/parser.c | 103 +++-----------------------------------------------
- libmultipath/parser.h | 6 --
- 2 files changed, 8 insertions(+), 101 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/parser.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/parser.c
-+++ multipath-tools-130222/libmultipath/parser.c
-@@ -280,8 +280,8 @@ out:
- return NULL;
- }
-
--int
--read_line(char *buf, int size)
-+static int
-+read_line(FILE *stream, char *buf, int size)
- {
- int ch;
- int count = 0;
-@@ -297,95 +297,6 @@ read_line(char *buf, int size)
- return (ch == EOF) ? 0 : 1;
- }
-
--vector
--read_value_block(void)
--{
-- char *buf;
-- int i;
-- char *str = NULL;
-- char *dup;
-- vector vec = NULL;
-- vector elements = vector_alloc();
--
-- if (!elements)
-- return NULL;
--
-- buf = (char *) MALLOC(MAXBUF);
--
-- if (!buf) {
-- vector_free(elements);
-- return NULL;
-- }
--
-- while (read_line(buf, MAXBUF)) {
-- vec = alloc_strvec(buf);
-- if (vec) {
-- str = VECTOR_SLOT(vec, 0);
-- if (!strcmp(str, EOB)) {
-- free_strvec(vec);
-- break;
-- }
--
-- for (i = 0; i < VECTOR_SIZE(vec); i++) {
-- str = VECTOR_SLOT(vec, i);
-- dup = (char *) MALLOC(strlen(str) + 1);
-- if (!dup)
-- goto out;
-- memcpy(dup, str, strlen(str));
--
-- if (!vector_alloc_slot(elements)) {
-- free_strvec(vec);
-- goto out1;
-- }
--
-- vector_set_slot(elements, dup);
-- }
-- free_strvec(vec);
-- }
-- memset(buf, 0, MAXBUF);
-- }
-- FREE(buf);
-- return elements;
--out1:
-- FREE(dup);
--out:
-- FREE(buf);
-- vector_free(elements);
-- return NULL;
--}
--
--int
--alloc_value_block(vector strvec, void (*alloc_func) (vector))
--{
-- char *buf;
-- char *str = NULL;
-- vector vec = NULL;
--
-- buf = (char *) MALLOC(MAXBUF);
--
-- if (!buf)
-- return 1;
--
-- while (read_line(buf, MAXBUF)) {
-- vec = alloc_strvec(buf);
-- if (vec) {
-- str = VECTOR_SLOT(vec, 0);
-- if (!strcmp(str, EOB)) {
-- free_strvec(vec);
-- break;
-- }
--
-- if (VECTOR_SIZE(vec))
-- (*alloc_func) (vec);
--
-- free_strvec(vec);
-- }
-- memset(buf, 0, MAXBUF);
-- }
-- FREE(buf);
-- return 0;
--}
--
- void *
- set_value(vector strvec)
- {
-@@ -561,7 +472,7 @@ validate_config_strvec(vector strvec, ch
- }
-
- static int
--process_stream(vector keywords, char *file)
-+process_stream(FILE *stream, vector keywords, char *file)
- {
- int i;
- int r = 0;
-@@ -582,7 +493,7 @@ process_stream(vector keywords, char *fi
- return 1;
- }
-
-- while (read_line(buf, MAXBUF)) {
-+ while (read_line(stream, buf, MAXBUF)) {
- line_nr++;
- strvec = alloc_strvec(buf);
- memset(buf,0, MAXBUF);
-@@ -621,7 +532,8 @@ process_stream(vector keywords, char *fi
-
- if (keyword->sub) {
- kw_level++;
-- r += process_stream(keyword->sub, file);
-+ r += process_stream(stream,
-+ keyword->sub, file);
- kw_level--;
- }
- break;
-@@ -656,6 +568,7 @@ int
- process_file(char *file)
- {
- int r;
-+ FILE *stream;
-
- if (!keywords) {
- condlog(0, "No keywords alocated");
-@@ -670,7 +583,7 @@ process_file(char *file)
-
- /* Stream handling */
- line_nr = 0;
-- r = process_stream(keywords, file);
-+ r = process_stream(stream, keywords, file);
- fclose(stream);
- //free_keywords(keywords);
-
-Index: multipath-tools-130222/libmultipath/parser.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/parser.h
-+++ multipath-tools-130222/libmultipath/parser.h
-@@ -47,9 +47,6 @@ struct keyword {
- int unique;
- };
-
--/* global var exported */
--FILE *stream;
--
- /* Reloading helpers */
- #define SET_RELOAD (reload = 1)
- #define UNSET_RELOAD (reload = 0)
-@@ -72,9 +69,6 @@ extern int _install_keyword(char *string
- extern void dump_keywords(vector keydump, int level);
- extern void free_keywords(vector keywords);
- extern vector alloc_strvec(char *string);
--extern int read_line(char *buf, int size);
--extern vector read_value_block(void);
--extern int alloc_value_block(vector strvec, void (*alloc_func) (vector));
- extern void *set_value(vector strvec);
- extern int alloc_keywords(void);
- extern int process_file(char *conf_file);
+++ /dev/null
----
- libmultipath/checkers.c | 3
- libmultipath/checkers.h | 9 +
- libmultipath/config.c | 4
- libmultipath/config.h | 6 +
- libmultipath/configure.c | 2
- libmultipath/defaults.h | 1
- libmultipath/dict.c | 204 ++++++++++++++++++++++++++++++++++++++++++++-
- libmultipath/print.c | 2
- libmultipath/propsel.c | 52 +++++++++++
- libmultipath/propsel.h | 2
- libmultipath/structs.h | 9 +
- multipath.conf.annotated | 40 ++++++++
- multipath.conf.defaults | 2
- multipath/multipath.conf.5 | 27 +++++
- multipathd/main.c | 34 ++++++-
- 15 files changed, 388 insertions(+), 9 deletions(-)
-
-Index: multipath-tools-130222/libmultipath/config.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.h
-+++ multipath-tools-130222/libmultipath/config.h
-@@ -62,6 +62,8 @@ struct hwentry {
- int retain_hwhandler;
- int detect_prio;
- int deferred_remove;
-+ int delay_watch_checks;
-+ int delay_wait_checks;
- char * bl_product;
- };
-
-@@ -86,6 +88,8 @@ struct mpentry {
- int attribute_flags;
- int user_friendly_names;
- int deferred_remove;
-+ int delay_watch_checks;
-+ int delay_wait_checks;
- uid_t uid;
- gid_t gid;
- mode_t mode;
-@@ -133,6 +137,8 @@ struct config {
- int deferred_remove;
- int ignore_new_boot_devs;
- int processed_main_config;
-+ int delay_watch_checks;
-+ int delay_wait_checks;
- unsigned int version[3];
-
- char * dev;
-Index: multipath-tools-130222/libmultipath/structs.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/structs.h
-+++ multipath-tools-130222/libmultipath/structs.h
-@@ -134,6 +134,11 @@ enum scsi_protocol {
- SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */
- };
-
-+enum delay_checks_states {
-+ DELAY_CHECKS_OFF = -1,
-+ DELAY_CHECKS_UNDEF = 0,
-+};
-+
- struct sg_id {
- int host_no;
- int channel;
-@@ -180,6 +185,8 @@ struct path {
- int priority;
- int pgindex;
- int detect_prio;
-+ int watch_checks;
-+ int wait_checks;
- char * uid_attribute;
- struct prio prio;
- char * prio_args;
-@@ -215,6 +222,8 @@ struct multipath {
- int fast_io_fail;
- int retain_hwhandler;
- int deferred_remove;
-+ int delay_watch_checks;
-+ int delay_wait_checks;
- unsigned int dev_loss;
- uid_t uid;
- gid_t gid;
-Index: multipath-tools-130222/libmultipath/checkers.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/checkers.h
-+++ multipath-tools-130222/libmultipath/checkers.h
-@@ -46,6 +46,14 @@
- * PATH_PENDING:
- * - Use: All async checkers
- * - Description: Indicates a check IO is in flight.
-+ *
-+ * PATH_DELAYED:
-+ * - Use: None of the checkers (returned if the path is being delayed before
-+ * reintegration.
-+ * - Description: If a path fails after being up for less than
-+ * delay_watch_checks checks, when it comes back up again, it will not
-+ * be marked as up until it has been up for delay_wait_checks checks.
-+ * During this time, it is marked as "delayed"
- */
- enum path_check_state {
- PATH_WILD,
-@@ -55,6 +63,7 @@ enum path_check_state {
- PATH_SHAKY,
- PATH_GHOST,
- PATH_PENDING,
-+ PATH_DELAYED,
- PATH_MAX_STATE
- };
-
-Index: multipath-tools-130222/libmultipath/configure.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/configure.c
-+++ multipath-tools-130222/libmultipath/configure.c
-@@ -291,6 +291,8 @@ setup_map (struct multipath * mpp, char
- select_reservation_key(mpp);
- select_retain_hwhandler(mpp);
- select_deferred_remove(mpp);
-+ select_delay_watch_checks(mpp);
-+ select_delay_wait_checks(mpp);
-
- sysfs_set_scsi_tmo(mpp);
- /*
-Index: multipath-tools-130222/libmultipath/defaults.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/defaults.h
-+++ multipath-tools-130222/libmultipath/defaults.h
-@@ -20,6 +20,7 @@
- #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
- #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
- #define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF
-+#define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF
-
- #define DEFAULT_CHECKINT 5
- #define MAX_CHECKINT(a) (a << 2)
-Index: multipath-tools-130222/libmultipath/dict.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/dict.c
-+++ multipath-tools-130222/libmultipath/dict.c
-@@ -801,6 +801,44 @@ def_ignore_new_boot_devs_handler(vector
- return 0;
- }
-
-+static int
-+def_delay_watch_checks_handler(vector strvec)
-+{
-+ char * buff;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ conf->delay_watch_checks = DELAY_CHECKS_OFF;
-+ else if ((conf->delay_watch_checks = atoi(buff)) < 1)
-+ conf->delay_watch_checks = DELAY_CHECKS_OFF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
-+static int
-+def_delay_wait_checks_handler(vector strvec)
-+{
-+ char * buff;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ conf->delay_wait_checks = DELAY_CHECKS_OFF;
-+ else if ((conf->delay_wait_checks = atoi(buff)) < 1)
-+ conf->delay_wait_checks = DELAY_CHECKS_OFF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * blacklist block handlers
- */
-@@ -1517,6 +1555,52 @@ hw_deferred_remove_handler(vector strvec
- return 0;
- }
-
-+static int
-+hw_delay_watch_checks_handler(vector strvec)
-+{
-+ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
-+ char * buff;
-+
-+ if (!hwe)
-+ return 1;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ hwe->delay_watch_checks = DELAY_CHECKS_OFF;
-+ else if ((hwe->delay_watch_checks = atoi(buff)) < 1)
-+ hwe->delay_watch_checks = DELAY_CHECKS_OFF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
-+static int
-+hw_delay_wait_checks_handler(vector strvec)
-+{
-+ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
-+ char * buff;
-+
-+ if (!hwe)
-+ return 1;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ hwe->delay_wait_checks = DELAY_CHECKS_OFF;
-+ else if ((hwe->delay_wait_checks = atoi(buff)) < 1)
-+ hwe->delay_wait_checks = DELAY_CHECKS_OFF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * multipaths block handlers
- */
-@@ -1996,6 +2080,52 @@ mp_deferred_remove_handler(vector strvec
- return 0;
- }
-
-+static int
-+mp_delay_watch_checks_handler(vector strvec)
-+{
-+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
-+ char * buff;
-+
-+ if (!mpe)
-+ return 1;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ mpe->delay_watch_checks = DELAY_CHECKS_OFF;
-+ else if ((mpe->delay_watch_checks = atoi(buff)) < 1)
-+ mpe->delay_watch_checks = DELAY_CHECKS_OFF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
-+static int
-+mp_delay_wait_checks_handler(vector strvec)
-+{
-+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
-+ char * buff;
-+
-+ if (!mpe)
-+ return 1;
-+
-+ buff = set_value(strvec);
-+ if (!buff)
-+ return 1;
-+
-+ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
-+ (strlen(buff) == 1 && !strcmp(buff, "0")))
-+ mpe->delay_wait_checks = DELAY_CHECKS_OFF;
-+ else if ((mpe->delay_wait_checks = atoi(buff)) < 1)
-+ mpe->delay_wait_checks = DELAY_CHECKS_OFF;
-+
-+ FREE(buff);
-+ return 0;
-+}
-+
- /*
- * config file keywords printing
- */
-@@ -2258,6 +2388,30 @@ snprint_mp_deferred_remove (char * buff,
- }
-
- static int
-+snprint_mp_delay_watch_checks(char * buff, int len, void * data)
-+{
-+ struct mpentry * mpe = (struct mpentry *)data;
-+
-+ if (mpe->delay_watch_checks == DELAY_CHECKS_UNDEF)
-+ return 0;
-+ if (mpe->delay_watch_checks == DELAY_CHECKS_OFF)
-+ return snprintf(buff, len, "no");
-+ return snprintf(buff, len, "%d", mpe->delay_watch_checks);
-+}
-+
-+static int
-+snprint_mp_delay_wait_checks(char * buff, int len, void * data)
-+{
-+ struct mpentry * mpe = (struct mpentry *)data;
-+
-+ if (mpe->delay_wait_checks == DELAY_CHECKS_UNDEF)
-+ return 0;
-+ if (mpe->delay_wait_checks == DELAY_CHECKS_OFF)
-+ return snprintf(buff, len, "no");
-+ return snprintf(buff, len, "%d", mpe->delay_wait_checks);
-+}
-+
-+static int
- snprint_hw_fast_io_fail(char * buff, int len, void * data)
- {
- struct hwentry * hwe = (struct hwentry *)data;
-@@ -2586,6 +2740,30 @@ snprint_hw_deferred_remove(char * buff,
- }
-
- static int
-+snprint_hw_delay_watch_checks(char * buff, int len, void * data)
-+{
-+ struct hwentry * hwe = (struct hwentry *)data;
-+
-+ if (hwe->delay_watch_checks == DELAY_CHECKS_UNDEF)
-+ return 0;
-+ if (hwe->delay_watch_checks == DELAY_CHECKS_OFF)
-+ return snprintf(buff, len, "no");
-+ return snprintf(buff, len, "%d", hwe->delay_watch_checks);
-+}
-+
-+static int
-+snprint_hw_delay_wait_checks(char * buff, int len, void * data)
-+{
-+ struct hwentry * hwe = (struct hwentry *)data;
-+
-+ if (hwe->delay_wait_checks == DELAY_CHECKS_UNDEF)
-+ return 0;
-+ if (hwe->delay_wait_checks == DELAY_CHECKS_OFF)
-+ return snprintf(buff, len, "no");
-+ return snprintf(buff, len, "%d", hwe->delay_wait_checks);
-+}
-+
-+static int
- snprint_detect_prio(char * buff, int len, void * data)
- {
- struct hwentry * hwe = (struct hwentry *)data;
-@@ -2883,7 +3061,6 @@ snprint_def_find_multipaths (char * buff
- return snprintf(buff, len, "yes");
- }
-
--
- static int
- snprint_def_user_friendly_names (char * buff, int len, void * data)
- {
-@@ -2989,7 +3166,6 @@ snprint_def_ignore_new_boot_devs(char *
- return snprintf(buff, len, "no");
- }
-
--
- static int
- snprint_def_config_dir (char * buff, int len, void * data)
- {
-@@ -3000,6 +3176,24 @@ snprint_def_config_dir (char * buff, int
- }
-
- static int
-+snprint_def_delay_watch_checks(char * buff, int len, void * data)
-+{
-+ if (conf->delay_watch_checks == DELAY_CHECKS_UNDEF ||
-+ conf->delay_watch_checks == DELAY_CHECKS_OFF)
-+ return snprintf(buff, len, "no");
-+ return snprintf(buff, len, "%d", conf->delay_watch_checks);
-+}
-+
-+static int
-+snprint_def_delay_wait_checks(char * buff, int len, void * data)
-+{
-+ if (conf->delay_wait_checks == DELAY_CHECKS_UNDEF ||
-+ conf->delay_wait_checks == DELAY_CHECKS_OFF)
-+ return snprintf(buff, len, "no");
-+ return snprintf(buff, len, "%d", conf->delay_wait_checks);
-+}
-+
-+static int
- snprint_ble_simple (char * buff, int len, void * data)
- {
- struct blentry * ble = (struct blentry *)data;
-@@ -3071,6 +3265,8 @@ init_keywords(void)
- install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
- install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
- install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
-+ install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks);
-+ install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks);
- __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);
-@@ -3136,6 +3332,8 @@ init_keywords(void)
- install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
- install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
- install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
-+ install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks);
-+ install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks);
- install_sublevel_end();
-
- install_keyword_root("multipaths", &multipaths_handler);
-@@ -3161,5 +3359,7 @@ init_keywords(void)
- install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
- install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names);
- install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove);
-+ install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks);
-+ install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks);
- install_sublevel_end();
- }
-Index: multipath-tools-130222/libmultipath/print.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/print.c
-+++ multipath-tools-130222/libmultipath/print.c
-@@ -336,6 +336,8 @@ snprint_chk_state (char * buff, size_t l
- return snprintf(buff, len, "shaky");
- case PATH_GHOST:
- return snprintf(buff, len, "ghost");
-+ case PATH_DELAYED:
-+ return snprintf(buff, len, "delayed");
- default:
- return snprintf(buff, len, "undef");
- }
-Index: multipath-tools-130222/libmultipath/propsel.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.c
-+++ multipath-tools-130222/libmultipath/propsel.c
-@@ -788,3 +788,55 @@ select_detect_prio (struct path * pp)
- condlog(3, "%s: detect_prio = %d (compiled in default)", pp->dev, pp->detect_prio);
- return 0;
- }
-+
-+extern int
-+select_delay_watch_checks (struct multipath * mp)
-+{
-+ if (mp->mpe && mp->mpe->delay_watch_checks != DELAY_CHECKS_UNDEF) {
-+ mp->delay_watch_checks = mp->mpe->delay_watch_checks;
-+ condlog(3, "delay_watch_checks = %i (multipath setting)",
-+ mp->delay_watch_checks);
-+ return 0;
-+ }
-+ if (mp->hwe && mp->hwe->delay_watch_checks != DELAY_CHECKS_UNDEF) {
-+ mp->delay_watch_checks = mp->hwe->delay_watch_checks;
-+ condlog(3, "delay_watch_checks = %i (controler setting)",
-+ mp->delay_watch_checks);
-+ return 0;
-+ }
-+ if (conf->delay_watch_checks != DELAY_CHECKS_UNDEF) {
-+ mp->delay_watch_checks = conf->delay_watch_checks;
-+ condlog(3, "delay_watch_checks = %i (config file default)",
-+ mp->delay_watch_checks);
-+ return 0;
-+ }
-+ mp->delay_watch_checks = DEFAULT_DELAY_CHECKS;
-+ condlog(3, "delay_watch_checks = DISABLED (internal default)");
-+ return 0;
-+}
-+
-+extern int
-+select_delay_wait_checks (struct multipath * mp)
-+{
-+ if (mp->mpe && mp->mpe->delay_wait_checks != DELAY_CHECKS_UNDEF) {
-+ mp->delay_wait_checks = mp->mpe->delay_wait_checks;
-+ condlog(3, "delay_wait_checks = %i (multipath setting)",
-+ mp->delay_wait_checks);
-+ return 0;
-+ }
-+ if (mp->hwe && mp->hwe->delay_wait_checks != DELAY_CHECKS_UNDEF) {
-+ mp->delay_wait_checks = mp->hwe->delay_wait_checks;
-+ condlog(3, "delay_wait_checks = %i (controler setting)",
-+ mp->delay_wait_checks);
-+ return 0;
-+ }
-+ if (conf->delay_wait_checks != DELAY_CHECKS_UNDEF) {
-+ mp->delay_wait_checks = conf->delay_wait_checks;
-+ condlog(3, "delay_wait_checks = %i (config file default)",
-+ mp->delay_wait_checks);
-+ return 0;
-+ }
-+ mp->delay_wait_checks = DEFAULT_DELAY_CHECKS;
-+ condlog(3, "delay_wait_checks = DISABLED (internal default)");
-+ return 0;
-+}
-Index: multipath-tools-130222/libmultipath/propsel.h
-===================================================================
---- multipath-tools-130222.orig/libmultipath/propsel.h
-+++ multipath-tools-130222/libmultipath/propsel.h
-@@ -21,3 +21,5 @@ int select_reservation_key(struct multip
- int select_retain_hwhandler (struct multipath * mp);
- int select_detect_prio(struct path * pp);
- int select_deferred_remove(struct multipath *mp);
-+int select_delay_watch_checks (struct multipath * mp);
-+int select_delay_wait_checks (struct multipath * mp);
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -188,7 +188,8 @@ sync_map_state(struct multipath *mpp)
- vector_foreach_slot (mpp->pg, pgp, i){
- vector_foreach_slot (pgp->paths, pp, j){
- if (pp->state == PATH_UNCHECKED ||
-- pp->state == PATH_WILD)
-+ pp->state == PATH_WILD ||
-+ pp->state == PATH_DELAYED)
- continue;
- if ((pp->dmstate == PSTATE_FAILED ||
- pp->dmstate == PSTATE_UNDEF) &&
-@@ -1165,6 +1166,16 @@ check_path (struct vectors * vecs, struc
- if (!pp->mpp)
- return;
-
-+ if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
-+ pp->wait_checks > 0) {
-+ if (pp->mpp && pp->mpp->nr_active > 0) {
-+ pp->state = PATH_DELAYED;
-+ pp->wait_checks--;
-+ return;
-+ } else
-+ pp->wait_checks = 0;
-+ }
-+
- pp->chkrstate = newstate;
- if (newstate != pp->state) {
- int oldstate = pp->state;
-@@ -1182,9 +1193,14 @@ check_path (struct vectors * vecs, struc
- * proactively fail path in the DM
- */
- if (oldstate == PATH_UP ||
-- oldstate == PATH_GHOST)
-+ oldstate == PATH_GHOST) {
- fail_path(pp, 1);
-- else
-+ if (pp->mpp->delay_wait_checks > 0 &&
-+ pp->watch_checks > 0) {
-+ pp->wait_checks = pp->mpp->delay_wait_checks;
-+ pp->watch_checks = 0;
-+ }
-+ }else
- fail_path(pp, 0);
-
- /*
-@@ -1211,11 +1227,15 @@ check_path (struct vectors * vecs, struc
- * reinstate this path
- */
- if (oldstate != PATH_UP &&
-- oldstate != PATH_GHOST)
-+ oldstate != PATH_GHOST) {
-+ if (pp->mpp->delay_watch_checks > 0)
-+ pp->watch_checks = pp->mpp->delay_watch_checks;
- reinstate_path(pp, 1);
-- else
-+ } else {
-+ if (pp->watch_checks > 0)
-+ pp->watch_checks--;
- reinstate_path(pp, 0);
--
-+ }
- new_path_up = 1;
-
- if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
-@@ -1245,6 +1265,8 @@ check_path (struct vectors * vecs, struc
- else
- pp->checkint = conf->max_checkint;
- }
-+ if (pp->watch_checks > 0)
-+ pp->watch_checks--;
- pp->tick = pp->checkint;
- condlog(4, "%s: delay next check %is",
- pp->dev_t, pp->tick);
-Index: multipath-tools-130222/multipath.conf.annotated
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.annotated
-+++ multipath-tools-130222/multipath.conf.annotated
-@@ -242,6 +242,30 @@
- # # files, just as if it was in /etc/multipath.conf
- # # values : "" or a fully qualified pathname
- # # default : "/etc/multipath/conf.d"
-+#
-+# #
-+# # name : delay_watch_checks
-+# # scope : multipathd
-+# # desc : If set to a value greater than 0, multipathd will watch
-+# # paths that have recently become valid for this many
-+# # checks. If they fail again while they are being watched,
-+# # when they next become valid, they will not be used until
-+# # they have stayed up for delay_wait_checks checks.
-+# # values : no|<n> > 0
-+# # default : no
-+# delay_watch_checks 12
-+#
-+# #
-+# # name : delay_wait_checks
-+# # scope : multipathd
-+# # desc : If set to a value greater than 0, when a device that has
-+# # recently come back online fails again within
-+# # delay_watch_checks checks, the next time it comes back
-+# # online, it will marked and delayed, and not used until
-+# # it has passed delay_wait_checks checks.
-+# # values : no|<n> > 0
-+# # default : no
-+# delay_wait_checks 12
- #}
- #
- ##
-@@ -383,6 +407,13 @@
- # #
- # flush_on_last_del yes
- #
-+# #
-+# # name : delay_watch_checks
-+# # See defualts section for information.
-+#
-+# #
-+# # name : delay_wait_checks
-+# # See defualts section for information.
- # }
- # multipath {
- # wwid 1DEC_____321816758474
-@@ -566,6 +597,15 @@
- # # before removing it from the system.
- # # values : n > 0
- # dev_loss_tmo 600
-+#
-+# #
-+# # name : delay_watch_checks
-+# # See defaults section for information.
-+#
-+# #
-+# # name : delay_wait_checks
-+# # See defaults section for information.
-+#
- # }
- # device {
- # vendor "COMPAQ "
-Index: multipath-tools-130222/multipath.conf.defaults
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.defaults
-+++ multipath-tools-130222/multipath.conf.defaults
-@@ -27,6 +27,8 @@
- # retain_attached_hw_handler no
- # detect_prio no
- # config_dir "/etc/multipath/conf.d"
-+# delay_watch_checks no
-+# delay_wait_checks no
- #}
- #blacklist {
- # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
-Index: multipath-tools-130222/multipath/multipath.conf.5
-===================================================================
---- multipath-tools-130222.orig/multipath/multipath.conf.5
-+++ multipath-tools-130222/multipath/multipath.conf.5
-@@ -437,6 +437,25 @@ alphabetically for file ending in ".conf
- information from them, just as if it was in /etc/multipath.conf. config_dir
- must either be "" or a fully qualified directory name. Default is
- .I "/etc/multipath/conf.d"
-+.TP
-+.B delay_watch_checks
-+If set to a value greater than 0, multipathd will watch paths that have
-+recently become valid for this many checks. If they fail again while they are
-+being watched, when they next become valid, they will not be used until they
-+have stayed up for
-+.I delay_wait_checks
-+checks. Default is
-+.I no
-+.TP
-+.B delay_wait_checks
-+If set to a value greater than 0, when a device that has recently come back
-+online fails again within
-+.I delay_watch_checks
-+checks, the next time it comes back online, it will marked and delayed, and not
-+used until it has passed
-+.I delay_wait_checks
-+checks. Default is
-+.I no
- .
- .SH "blacklist section"
- The
-@@ -540,6 +559,10 @@ section:
- .B reservation_key
- .TP
- .B deferred_remove
-+.TP
-+.B delay_watch_checks
-+.TP
-+.B delay_wait_checks
- .RE
- .PD
- .LP
-@@ -632,6 +655,10 @@ section:
- .B detect_prio
- .TP
- .B deferred_remove
-+.TP
-+.B delay_watch_checks
-+.TP
-+.B delay_wait_checks
- .RE
- .PD
- .LP
-Index: multipath-tools-130222/libmultipath/checkers.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/checkers.c
-+++ multipath-tools-130222/libmultipath/checkers.c
-@@ -16,7 +16,8 @@ char *checker_state_names[] = {
- "up",
- "shaky",
- "ghost",
-- "pending"
-+ "pending",
-+ "delayed"
- };
-
- static LIST_HEAD(checkers);
-Index: multipath-tools-130222/libmultipath/config.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/config.c
-+++ multipath-tools-130222/libmultipath/config.c
-@@ -341,6 +341,8 @@ merge_hwe (struct hwentry * dst, struct
- merge_num(retain_hwhandler);
- merge_num(detect_prio);
- merge_num(deferred_remove);
-+ merge_num(delay_watch_checks);
-+ merge_num(delay_wait_checks);
-
- /*
- * Make sure features is consistent with
-@@ -399,6 +401,8 @@ overwrite_hwe (struct hwentry * dst, str
- overwrite_num(retain_hwhandler);
- overwrite_num(detect_prio);
- overwrite_num(deferred_remove);
-+ overwrite_num(delay_watch_checks);
-+ overwrite_num(delay_wait_checks);
-
- /*
- * Make sure features is consistent with
+++ /dev/null
----
- multipathd/main.c | 13 +++++++++----
- 1 file changed, 9 insertions(+), 4 deletions(-)
-
-Index: multipath-tools-130222/multipathd/main.c
-===================================================================
---- multipath-tools-130222.orig/multipathd/main.c
-+++ multipath-tools-130222/multipathd/main.c
-@@ -310,10 +310,15 @@ ev_add_map (char * dev, char * alias, st
- /*
- * now we can register the map
- */
-- if (map_present && (mpp = add_map_without_path(vecs, alias))) {
-- sync_map_state(mpp);
-- condlog(2, "%s: devmap %s registered", alias, dev);
-- return 0;
-+ if (map_present) {
-+ if ((mpp = add_map_without_path(vecs, alias))) {
-+ sync_map_state(mpp);
-+ condlog(2, "%s: devmap %s registered", alias, dev);
-+ return 0;
-+ } else {
-+ condlog(2, "%s: uev_add_map failed", dev);
-+ return 1;
-+ }
- }
- r = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec, &refwwid);
-
+++ /dev/null
----
- libmultipath/hwtable.c | 30 ++++++++++++++++++++++++++++++
- multipath.conf.defaults | 26 ++++++++++++++++++++++++++
- 2 files changed, 56 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/hwtable.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/hwtable.c
-+++ multipath-tools-130222/libmultipath/hwtable.c
-@@ -772,6 +772,36 @@ static struct hwentry default_hw[] = {
- .prio_name = PRIO_RDAC,
- .prio_args = NULL,
- },
-+ {
-+ /* DELL MD36xxi */
-+ .vendor = "DELL",
-+ .product = "MD36xxi",
-+ .bl_product = "Universal Xport",
-+ .features = "2 pg_init_retries 50",
-+ .hwhandler = "1 rdac",
-+ .pgpolicy = GROUP_BY_PRIO,
-+ .pgfailback = -FAILBACK_IMMEDIATE,
-+ .rr_weight = RR_WEIGHT_NONE,
-+ .no_path_retry = 15,
-+ .checker_name = RDAC,
-+ .prio_name = PRIO_RDAC,
-+ .prio_args = NULL,
-+ },
-+ {
-+ /* DELL MD36xxf */
-+ .vendor = "DELL",
-+ .product = "MD36xxf",
-+ .bl_product = "Universal Xport",
-+ .features = "2 pg_init_retries 50",
-+ .hwhandler = "1 rdac",
-+ .pgpolicy = GROUP_BY_PRIO,
-+ .pgfailback = -FAILBACK_IMMEDIATE,
-+ .rr_weight = RR_WEIGHT_NONE,
-+ .no_path_retry = 15,
-+ .checker_name = RDAC,
-+ .prio_name = PRIO_RDAC,
-+ .prio_args = NULL,
-+ },
- /*
- * NETAPP controller family
- *
-Index: multipath-tools-130222/multipath.conf.defaults
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.defaults
-+++ multipath-tools-130222/multipath.conf.defaults
-@@ -655,6 +655,32 @@
- # no_path_retry 15
- # }
- # device {
-+# vendor "DELL"
-+# product "MD36xxi"
-+# product_blacklist "Universal Xport"
-+# path_grouping_policy "group_by_prio"
-+# path_checker "rdac"
-+# features "2 pg_init_retries 50"
-+# hardware_handler "1 rdac"
-+# prio "rdac"
-+# failback "immediate"
-+# rr_weight "uniform"
-+# no_path_retry 15
-+# }
-+# device {
-+# vendor "DELL"
-+# product "MD36xxf"
-+# product_blacklist "Universal Xport"
-+# path_grouping_policy "group_by_prio"
-+# path_checker "rdac"
-+# features "2 pg_init_retries 50"
-+# hardware_handler "1 rdac"
-+# prio "rdac"
-+# failback "immediate"
-+# rr_weight "uniform"
-+# no_path_retry 15
-+# }
-+# device {
- # vendor "NETAPP"
- # product "LUN.*"
- # path_grouping_policy "group_by_prio"
+++ /dev/null
----
- libmultipath/hwtable.c | 2 ++
- multipath.conf.defaults | 2 ++
- 2 files changed, 4 insertions(+)
-
-Index: multipath-tools-130222/libmultipath/hwtable.c
-===================================================================
---- multipath-tools-130222.orig/libmultipath/hwtable.c
-+++ multipath-tools-130222/libmultipath/hwtable.c
-@@ -272,6 +272,8 @@ static struct hwentry default_hw[] = {
- .checker_name = EMC_CLARIION,
- .prio_name = PRIO_EMC,
- .prio_args = NULL,
-+ .retain_hwhandler = RETAIN_HWHANDLER_ON,
-+ .detect_prio = DETECT_PRIO_ON,
- },
- {
- .vendor = "EMC",
-Index: multipath-tools-130222/multipath.conf.defaults
-===================================================================
---- multipath-tools-130222.orig/multipath.conf.defaults
-+++ multipath-tools-130222/multipath.conf.defaults
-@@ -261,6 +261,8 @@
- # failback immediate
- # rr_weight "uniform"
- # no_path_retry 60
-+# retain_attached_hw_handler yes
-+# detect_prio yes
- # }
- # device {
- # vendor "EMC"