From: Michael Tremer Date: Mon, 6 Apr 2015 19:49:27 +0000 (-0400) Subject: multipath-tools: Update to snapshot from 2013-02-22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=289c5516e3248154e1a9f9cf330f8917e4103bbf;p=ipfire-3.x.git multipath-tools: Update to snapshot from 2013-02-22 --- diff --git a/multipath-tools/multipath-tools.nm b/multipath-tools/multipath-tools.nm index 63b035a4e..a2c82705d 100644 --- a/multipath-tools/multipath-tools.nm +++ b/multipath-tools/multipath-tools.nm @@ -7,8 +7,9 @@ name = multipath-tools version = %{rel_ver}.%{rel_date} release = 1 +thisapp = %{name}-%{rel_date} rel_ver = 0.4.9 -rel_date = 120613 +rel_date = 130222 groups = System/Base url = http://christophe.varoqui.free.fr/ @@ -20,8 +21,6 @@ description instructing the device-mapper multipath kernel module what to do. end -thisapp = %{name}-%{rel_date} - sources = %{thisapp}.tgz build @@ -34,13 +33,10 @@ build readline-devel end - prepare_cmds - # Fix hardcoded install location for udev rules. - sed -e "s@lib/udev@usr/lib/udev@g" -i multipath/Makefile - end + make_build_targets += LIB=%{lib} # Install everything to the correct locations. - make_install_targets +=\ + make_install_targets += \ bindir=%{sbindir} \ syslibdir=%{libdir} \ libdir=%{libdir}/multipath \ diff --git a/multipath-tools/patches/0001-RH-dont_start_with_no_config.patch b/multipath-tools/patches/0001-RH-dont_start_with_no_config.patch new file mode 100644 index 000000000..e894632ef --- /dev/null +++ b/multipath-tools/patches/0001-RH-dont_start_with_no_config.patch @@ -0,0 +1,16 @@ +--- + 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 + diff --git a/multipath-tools/patches/0001-RH-remove_callout.patch b/multipath-tools/patches/0001-RH-remove_callout.patch deleted file mode 100644 index 0c03cc473..000000000 --- a/multipath-tools/patches/0001-RH-remove_callout.patch +++ /dev/null @@ -1,279 +0,0 @@ ---- - libmultipath/Makefile | 2 - libmultipath/callout.c | 217 ----------------------------------------------- - libmultipath/callout.h | 7 - - libmultipath/discovery.c | 1 - multipathd/main.c | 1 - 5 files changed, 1 insertion(+), 227 deletions(-) - -Index: multipath-tools-120518/libmultipath/Makefile -=================================================================== ---- multipath-tools-120518.orig/libmultipath/Makefile -+++ multipath-tools-120518/libmultipath/Makefile -@@ -9,7 +9,7 @@ DEVLIB = libmultipath.so - LIBS = $(DEVLIB).$(SONAME) - LIBDEPS = -lpthread -ldl -ldevmapper -ludev - --OBJS = memory.o parser.o vector.o devmapper.o callout.o \ -+OBJS = memory.o parser.o vector.o devmapper.o \ - hwtable.o blacklist.o util.o dmparser.o config.o \ - structs.o discovery.o propsel.o dict.o \ - pgpolicies.o debug.o regex.o defaults.o uevent.o \ -Index: multipath-tools-120518/libmultipath/callout.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/callout.c -+++ /dev/null -@@ -1,217 +0,0 @@ --/* -- * Source: copy of the udev package source file -- * -- * Copyrights of the source file apply -- * Copyright (c) 2004 Christophe Varoqui -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "checkers.h" --#include "vector.h" --#include "structs.h" --#include "util.h" --#include "debug.h" -- --int execute_program(char *path, char *value, int len) --{ -- int retval; -- int count; -- int status; -- int fds[2], null_fd; -- pid_t pid; -- char *pos; -- char arg[CALLOUT_MAX_SIZE]; -- int argc = sizeof(arg) / 2; -- char *argv[argc + 1]; -- int i; -- -- i = 0; -- -- if (strchr(path, ' ')) { -- strlcpy(arg, path, sizeof(arg)); -- pos = arg; -- while (pos != NULL && i < argc) { -- if (pos[0] == '\'') { -- /* don't separate if in apostrophes */ -- pos++; -- argv[i] = strsep(&pos, "\'"); -- while (pos[0] == ' ') -- pos++; -- } else { -- argv[i] = strsep(&pos, " "); -- } -- i++; -- } -- } else { -- argv[i++] = path; -- } -- argv[i] = NULL; -- -- retval = pipe(fds); -- -- if (retval != 0) { -- condlog(0, "error creating pipe for callout: %s", strerror(errno)); -- return -1; -- } -- -- pid = fork(); -- -- switch(pid) { -- case 0: -- /* child */ -- close(STDOUT_FILENO); -- -- /* dup write side of pipe to STDOUT */ -- if (dup(fds[1]) < 0) -- return -1; -- -- /* Ignore writes to stderr */ -- null_fd = open("/dev/null", O_WRONLY); -- if (null_fd > 0) { -- close(STDERR_FILENO); -- dup(null_fd); -- close(null_fd); -- } -- -- retval = execv(argv[0], argv); -- condlog(0, "error execing %s : %s", argv[0], strerror(errno)); -- exit(-1); -- case -1: -- condlog(0, "fork failed: %s", strerror(errno)); -- close(fds[0]); -- close(fds[1]); -- return -1; -- default: -- /* parent reads from fds[0] */ -- close(fds[1]); -- retval = 0; -- i = 0; -- while (1) { -- count = read(fds[0], value + i, len - i-1); -- if (count <= 0) -- break; -- -- i += count; -- if (i >= len-1) { -- condlog(0, "not enough space for response from %s", argv[0]); -- retval = -1; -- break; -- } -- } -- -- if (count < 0) { -- condlog(0, "no response from %s", argv[0]); -- retval = -1; -- } -- -- if (i > 0 && value[i-1] == '\n') -- i--; -- value[i] = '\0'; -- -- wait(&status); -- close(fds[0]); -- -- retval = -1; -- if (WIFEXITED(status)) { -- status = WEXITSTATUS(status); -- if (status == 0) -- retval = 0; -- else -- condlog(0, "%s exitted with %d", argv[0], status); -- } -- else if (WIFSIGNALED(status)) -- condlog(0, "%s was terminated by signal %d", argv[0], WTERMSIG(status)); -- else -- condlog(0, "%s terminated abnormally", argv[0]); -- } -- return retval; --} -- --extern int --apply_format (char * string, char * cmd, struct path * pp) --{ -- char * pos; -- char * dst; -- char * p; -- char * q; -- int len; -- int myfree; -- -- if (!string) -- return 1; -- -- if (!cmd) -- return 1; -- -- dst = cmd; -- p = dst; -- pos = strchr(string, '%'); -- myfree = CALLOUT_MAX_SIZE; -- -- if (!pos) { -- strcpy(dst, string); -- return 0; -- } -- -- len = (int) (pos - string) + 1; -- myfree -= len; -- -- if (myfree < 2) -- return 1; -- -- snprintf(p, len, "%s", string); -- p += len - 1; -- pos++; -- -- switch (*pos) { -- case 'n': -- len = strlen(pp->dev) + 1; -- myfree -= len; -- -- if (myfree < 2) -- return 1; -- -- snprintf(p, len, "%s", pp->dev); -- for (q = p; q < p + len; q++) { -- if (q && *q == '!') -- *q = '/'; -- } -- p += len - 1; -- break; -- case 'd': -- len = strlen(pp->dev_t) + 1; -- myfree -= len; -- -- if (myfree < 2) -- return 1; -- -- snprintf(p, len, "%s", pp->dev_t); -- p += len - 1; -- break; -- default: -- break; -- } -- pos++; -- -- if (!*pos) -- return 0; -- -- len = strlen(pos) + 1; -- myfree -= len; -- -- if (myfree < 2) -- return 1; -- -- snprintf(p, len, "%s", pos); -- condlog(3, "reformated callout = %s", dst); -- return 0; --} -- -Index: multipath-tools-120518/libmultipath/callout.h -=================================================================== ---- multipath-tools-120518.orig/libmultipath/callout.h -+++ /dev/null -@@ -1,7 +0,0 @@ --#ifndef _CALLOUT_H --#define _CALLOUT_H -- --int execute_program(char *, char *, int); --int apply_format (char *, char *, struct path *); -- --#endif /* _CALLOUT_H */ -Index: multipath-tools-120518/libmultipath/discovery.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/discovery.c -+++ multipath-tools-120518/libmultipath/discovery.c -@@ -20,7 +20,6 @@ - #include "structs.h" - #include "config.h" - #include "blacklist.h" --#include "callout.h" - #include "debug.h" - #include "propsel.h" - #include "sg_include.h" -Index: multipath-tools-120518/multipathd/main.c -=================================================================== ---- multipath-tools-120518.orig/multipathd/main.c -+++ multipath-tools-120518/multipathd/main.c -@@ -35,7 +35,6 @@ - #include - #include - #include --#include - #include - #include - #include diff --git a/multipath-tools/patches/0002-RH-add-wwids-file.patch b/multipath-tools/patches/0002-RH-add-wwids-file.patch deleted file mode 100644 index f3014ba5b..000000000 --- a/multipath-tools/patches/0002-RH-add-wwids-file.patch +++ /dev/null @@ -1,748 +0,0 @@ ---- - libmultipath/Makefile | 2 - libmultipath/alias.c | 153 --------------------------------------- - libmultipath/alias.h | 1 - libmultipath/configure.c | 3 - libmultipath/defaults.h | 1 - libmultipath/discovery.c | 2 - libmultipath/file.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++ - libmultipath/file.h | 11 ++ - libmultipath/wwids.c | 139 ++++++++++++++++++++++++++++++++++++ - libmultipath/wwids.h | 18 ++++ - multipath/main.c | 37 ++++++++- - 11 files changed, 389 insertions(+), 158 deletions(-) - -Index: multipath-tools-120518/libmultipath/alias.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/alias.c -+++ multipath-tools-120518/libmultipath/alias.c -@@ -3,19 +3,16 @@ - * Copyright (c) 2005 Benjamin Marzinski, Redhat - */ - #include --#include --#include --#include - #include - #include - #include - #include - #include --#include - - #include "debug.h" - #include "uxsock.h" - #include "alias.h" -+#include "file.h" - - - /* -@@ -36,150 +33,6 @@ - * See the file COPYING included with this distribution for more details. - */ - --static int --ensure_directories_exist(char *str, mode_t dir_mode) --{ -- char *pathname; -- char *end; -- int err; -- -- pathname = strdup(str); -- if (!pathname){ -- condlog(0, "Cannot copy bindings file pathname : %s", -- strerror(errno)); -- return -1; -- } -- end = pathname; -- /* skip leading slashes */ -- while (end && *end && (*end == '/')) -- end++; -- -- while ((end = strchr(end, '/'))) { -- /* if there is another slash, make the dir. */ -- *end = '\0'; -- err = mkdir(pathname, dir_mode); -- if (err && errno != EEXIST) { -- condlog(0, "Cannot make directory [%s] : %s", -- pathname, strerror(errno)); -- free(pathname); -- return -1; -- } -- if (!err) -- condlog(3, "Created dir [%s]", pathname); -- *end = '/'; -- end++; -- } -- free(pathname); -- return 0; --} -- --static void --sigalrm(int sig) --{ -- /* do nothing */ --} -- --static int --lock_bindings_file(int fd) --{ -- struct sigaction act, oldact; -- sigset_t set, oldset; -- struct flock lock; -- int err; -- -- memset(&lock, 0, sizeof(lock)); -- lock.l_type = F_WRLCK; -- lock.l_whence = SEEK_SET; -- -- act.sa_handler = sigalrm; -- sigemptyset(&act.sa_mask); -- act.sa_flags = 0; -- sigemptyset(&set); -- sigaddset(&set, SIGALRM); -- -- sigaction(SIGALRM, &act, &oldact); -- sigprocmask(SIG_UNBLOCK, &set, &oldset); -- -- alarm(BINDINGS_FILE_TIMEOUT); -- err = fcntl(fd, F_SETLKW, &lock); -- alarm(0); -- -- if (err) { -- if (errno != EINTR) -- condlog(0, "Cannot lock bindings file : %s", -- strerror(errno)); -- else -- condlog(0, "Bindings file is locked. Giving up."); -- } -- -- sigprocmask(SIG_SETMASK, &oldset, NULL); -- sigaction(SIGALRM, &oldact, NULL); -- return err; -- --} -- -- --static int --open_bindings_file(char *file, int *can_write) --{ -- int fd; -- struct stat s; -- -- if (ensure_directories_exist(file, 0700)) -- return -1; -- *can_write = 1; -- fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); -- if (fd < 0) { -- if (errno == EROFS) { -- *can_write = 0; -- condlog(3, "Cannot open bindings file [%s] read/write. " -- " trying readonly", file); -- fd = open(file, O_RDONLY); -- if (fd < 0) { -- condlog(0, "Cannot open bindings file [%s] " -- "readonly : %s", file, strerror(errno)); -- return -1; -- } -- } -- else { -- condlog(0, "Cannot open bindings file [%s] : %s", file, -- strerror(errno)); -- return -1; -- } -- } -- if (*can_write && lock_bindings_file(fd) < 0) -- goto fail; -- -- memset(&s, 0, sizeof(s)); -- if (fstat(fd, &s) < 0){ -- condlog(0, "Cannot stat bindings file : %s", strerror(errno)); -- goto fail; -- } -- if (s.st_size == 0) { -- if (*can_write == 0) -- goto fail; -- /* If bindings file is empty, write the header */ -- size_t len = strlen(BINDINGS_FILE_HEADER); -- if (write_all(fd, BINDINGS_FILE_HEADER, len) != len) { -- condlog(0, -- "Cannot write header to bindings file : %s", -- strerror(errno)); -- /* cleanup partially written header */ -- if (ftruncate(fd, 0)) -- condlog(0, "Cannot truncate the header : %s", -- strerror(errno)); -- goto fail; -- } -- fsync(fd); -- condlog(3, "Initialized new bindings file [%s]", file); -- } -- -- return fd; -- --fail: -- close(fd); -- return -1; --} - - static int - format_devname(char *name, int id, int len, char *prefix) -@@ -370,7 +223,7 @@ get_user_friendly_alias(char *wwid, char - return NULL; - } - -- fd = open_bindings_file(file, &can_write); -+ fd = open_file(file, &can_write, BINDINGS_FILE_HEADER); - if (fd < 0) - return NULL; - -@@ -414,7 +267,7 @@ get_user_friendly_wwid(char *alias, char - return NULL; - } - -- fd = open_bindings_file(file, &unused); -+ fd = open_file(file, &unused, BINDINGS_FILE_HEADER); - if (fd < 0) - return NULL; - -Index: multipath-tools-120518/libmultipath/alias.h -=================================================================== ---- multipath-tools-120518.orig/libmultipath/alias.h -+++ multipath-tools-120518/libmultipath/alias.h -@@ -1,4 +1,3 @@ --#define BINDINGS_FILE_TIMEOUT 30 - #define BINDINGS_FILE_HEADER \ - "# Multipath bindings, Version : 1.0\n" \ - "# NOTE: this file is automatically maintained by the multipath program.\n" \ -Index: multipath-tools-120518/libmultipath/configure.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/configure.c -+++ multipath-tools-120518/libmultipath/configure.c -@@ -37,6 +37,7 @@ - #include "prio.h" - #include "util.h" - #include "uxsock.h" -+#include "wwids.h" - - extern int - setup_map (struct multipath * mpp, char * params, int params_size) -@@ -407,6 +408,8 @@ domap (struct multipath * mpp, char * pa - * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD - * succeeded - */ -+ if (mpp->action == ACT_CREATE) -+ remember_wwid(mpp->wwid); - if (!conf->daemon) { - /* multipath client mode */ - dm_switchgroup(mpp->alias, mpp->bestpg); -Index: multipath-tools-120518/libmultipath/defaults.h -=================================================================== ---- multipath-tools-120518.orig/libmultipath/defaults.h -+++ multipath-tools-120518/libmultipath/defaults.h -@@ -24,5 +24,6 @@ - #define DEFAULT_SOCKET "/var/run/multipathd.sock" - #define DEFAULT_CONFIGFILE "/etc/multipath.conf" - #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" -+#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" - - char * set_default (char * str); -Index: multipath-tools-120518/libmultipath/file.c -=================================================================== ---- /dev/null -+++ multipath-tools-120518/libmultipath/file.c -@@ -0,0 +1,180 @@ -+/* -+ * Copyright (c) 2005 Christophe Varoqui -+ * Copyright (c) 2005 Benjamin Marzinski, Redhat -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "file.h" -+#include "debug.h" -+#include "uxsock.h" -+ -+ -+/* -+ * significant parts of this file were taken from iscsi-bindings.c of the -+ * linux-iscsi project. -+ * Copyright (C) 2002 Cisco Systems, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published -+ * by the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * See the file COPYING included with this distribution for more details. -+ */ -+ -+static int -+ensure_directories_exist(char *str, mode_t dir_mode) -+{ -+ char *pathname; -+ char *end; -+ int err; -+ -+ pathname = strdup(str); -+ if (!pathname){ -+ condlog(0, "Cannot copy file pathname %s : %s", -+ str, strerror(errno)); -+ return -1; -+ } -+ end = pathname; -+ /* skip leading slashes */ -+ while (end && *end && (*end == '/')) -+ end++; -+ -+ while ((end = strchr(end, '/'))) { -+ /* if there is another slash, make the dir. */ -+ *end = '\0'; -+ err = mkdir(pathname, dir_mode); -+ if (err && errno != EEXIST) { -+ condlog(0, "Cannot make directory [%s] : %s", -+ pathname, strerror(errno)); -+ free(pathname); -+ return -1; -+ } -+ if (!err) -+ condlog(3, "Created dir [%s]", pathname); -+ *end = '/'; -+ end++; -+ } -+ free(pathname); -+ return 0; -+} -+ -+static void -+sigalrm(int sig) -+{ -+ /* do nothing */ -+} -+ -+static int -+lock_file(int fd, char *file_name) -+{ -+ struct sigaction act, oldact; -+ sigset_t set, oldset; -+ struct flock lock; -+ int err; -+ -+ memset(&lock, 0, sizeof(lock)); -+ lock.l_type = F_WRLCK; -+ lock.l_whence = SEEK_SET; -+ -+ act.sa_handler = sigalrm; -+ sigemptyset(&act.sa_mask); -+ act.sa_flags = 0; -+ sigemptyset(&set); -+ sigaddset(&set, SIGALRM); -+ -+ sigaction(SIGALRM, &act, &oldact); -+ sigprocmask(SIG_UNBLOCK, &set, &oldset); -+ -+ alarm(FILE_TIMEOUT); -+ err = fcntl(fd, F_SETLKW, &lock); -+ alarm(0); -+ -+ if (err) { -+ if (errno != EINTR) -+ condlog(0, "Cannot lock %s : %s", file_name, -+ strerror(errno)); -+ else -+ condlog(0, "%s is locked. Giving up.", file_name); -+ } -+ -+ sigprocmask(SIG_SETMASK, &oldset, NULL); -+ sigaction(SIGALRM, &oldact, NULL); -+ return err; -+} -+ -+int -+open_file(char *file, int *can_write, char *header) -+{ -+ int fd; -+ struct stat s; -+ -+ if (ensure_directories_exist(file, 0700)) -+ return -1; -+ *can_write = 1; -+ fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); -+ if (fd < 0) { -+ if (errno == EROFS) { -+ *can_write = 0; -+ condlog(3, "Cannot open file [%s] read/write. " -+ " trying readonly", file); -+ fd = open(file, O_RDONLY); -+ if (fd < 0) { -+ condlog(0, "Cannot open file [%s] " -+ "readonly : %s", file, strerror(errno)); -+ return -1; -+ } -+ } -+ else { -+ condlog(0, "Cannot open file [%s] : %s", file, -+ strerror(errno)); -+ return -1; -+ } -+ } -+ if (*can_write && lock_file(fd, file) < 0) -+ goto fail; -+ -+ memset(&s, 0, sizeof(s)); -+ if (fstat(fd, &s) < 0){ -+ condlog(0, "Cannot stat file %s : %s", file, strerror(errno)); -+ goto fail; -+ } -+ if (s.st_size == 0) { -+ if (*can_write == 0) -+ goto fail; -+ /* If file is empty, write the header */ -+ size_t len = strlen(header); -+ if (write_all(fd, header, len) != len) { -+ condlog(0, -+ "Cannot write header to file %s : %s", file, -+ strerror(errno)); -+ /* cleanup partially written header */ -+ if (ftruncate(fd, 0)) -+ condlog(0, "Cannot truncate header : %s", -+ strerror(errno)); -+ goto fail; -+ } -+ fsync(fd); -+ condlog(3, "Initialized new file [%s]", file); -+ } -+ -+ return fd; -+ -+fail: -+ close(fd); -+ return -1; -+} -Index: multipath-tools-120518/libmultipath/file.h -=================================================================== ---- /dev/null -+++ multipath-tools-120518/libmultipath/file.h -@@ -0,0 +1,11 @@ -+/* -+ * Copyright (c) 2010 Benjamin Marzinski, Redhat -+ */ -+ -+#ifndef _FILE_H -+#define _FILE_H -+ -+#define FILE_TIMEOUT 30 -+int open_file(char *file, int *can_write, char *header); -+ -+#endif /* _FILE_H */ -Index: multipath-tools-120518/multipath/main.c -=================================================================== ---- multipath-tools-120518.orig/multipath/main.c -+++ multipath-tools-120518/multipath/main.c -@@ -53,6 +53,7 @@ - #include - #include - #include -+#include - #include "dev_t.h" - - int logsink; -@@ -82,7 +83,7 @@ usage (char * progname) - { - fprintf (stderr, VERSION_STRING); - fprintf (stderr, "Usage:\n"); -- fprintf (stderr, " %s [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); -+ fprintf (stderr, " %s [-c] [-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); -@@ -95,6 +96,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" \ -+ " -c check if a device should be 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" \ -@@ -209,6 +211,7 @@ get_dm_mpvec (vector curmp, vector pathv - - if (!conf->dry_run) - reinstate_paths(mpp); -+ remember_wwid(mpp->wwid); - } - return 0; - } -@@ -259,9 +262,13 @@ configure (void) - * if we have a blacklisted device parameter, exit early - */ - if (dev && -- (filter_devnode(conf->blist_devnode, conf->elist_devnode, dev) > 0)) -- goto out; -- -+ (filter_devnode(conf->blist_devnode, -+ conf->elist_devnode, dev) > 0)) { -+ if (conf->dry_run == 2) -+ printf("%s is not a valid multipath device path\n", -+ conf->dev); -+ goto out; -+ } - /* - * scope limiting must be translated into a wwid - * failing the translation is fatal (by policy) -@@ -277,6 +284,15 @@ configure (void) - if (filter_wwid(conf->blist_wwid, conf->elist_wwid, - refwwid) > 0) - goto out; -+ if (conf->dry_run == 2) { -+ if (check_wwids_file(refwwid, 0) == 0){ -+ printf("%s is a valid multipath device path\n", conf->dev); -+ r = 0; -+ } -+ else -+ printf("%s is not a valid multipath device path\n", conf->dev); -+ goto out; -+ } - } - - /* -@@ -412,7 +428,7 @@ main (int argc, char *argv[]) - if (load_config(DEFAULT_CONFIGFILE)) - exit(1); - -- while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:Brtq")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -434,8 +450,12 @@ main (int argc, char *argv[]) - case 'q': - conf->allow_queueing = 1; - break; -+ case 'c': -+ conf->dry_run = 2; -+ break; - case 'd': -- conf->dry_run = 1; -+ if (!conf->dry_run) -+ conf->dry_run = 1; - break; - case 'f': - conf->remove = FLUSH_ONE; -@@ -517,6 +537,11 @@ main (int argc, char *argv[]) - } - dm_init(); - -+ if (conf->dry_run == 2 && -+ (!conf->dev || conf->dev_type == DEV_DEVMAP)) { -+ condlog(0, "the -c option requires a path to check"); -+ goto out; -+ } - if (conf->remove == FLUSH_ONE) { - if (conf->dev_type == DEV_DEVMAP) - r = dm_flush_map(conf->dev); -Index: multipath-tools-120518/libmultipath/Makefile -=================================================================== ---- multipath-tools-120518.orig/libmultipath/Makefile -+++ multipath-tools-120518/libmultipath/Makefile -@@ -15,7 +15,7 @@ OBJS = memory.o parser.o vector.o devmap - pgpolicies.o debug.o regex.o defaults.o uevent.o \ - switchgroup.o uxsock.o print.o alias.o log_pthread.o \ - log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ -- lock.o waiter.o -+ lock.o waiter.o file.o wwids.o - - LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h) - -Index: multipath-tools-120518/libmultipath/wwids.c -=================================================================== ---- /dev/null -+++ multipath-tools-120518/libmultipath/wwids.c -@@ -0,0 +1,139 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "checkers.h" -+#include "vector.h" -+#include "structs.h" -+#include "debug.h" -+#include "uxsock.h" -+#include "file.h" -+#include "wwids.h" -+#include "defaults.h" -+ -+/* -+ * Copyright (c) 2010 Benjamin Marzinski, Redhat -+ */ -+ -+static int -+lookup_wwid(FILE *f, char *wwid) { -+ int c; -+ char buf[LINE_MAX]; -+ int count; -+ -+ while ((c = fgetc(f)) != EOF){ -+ if (c != '/') { -+ if (fgets(buf, LINE_MAX, f) == NULL) -+ return 0; -+ else -+ continue; -+ } -+ count = 0; -+ while ((c = fgetc(f)) != '/') { -+ if (c == EOF) -+ return 0; -+ if (count >= WWID_SIZE - 1) -+ goto next; -+ if (wwid[count] == '\0') -+ goto next; -+ if (c != wwid[count++]) -+ goto next; -+ } -+ if (wwid[count] == '\0') -+ return 1; -+next: -+ if (fgets(buf, LINE_MAX, f) == NULL) -+ return 0; -+ } -+ return 0; -+} -+ -+static int -+write_out_wwid(int fd, char *wwid) { -+ int ret; -+ off_t offset; -+ char buf[WWID_SIZE + 3]; -+ -+ ret = snprintf(buf, WWID_SIZE + 3, "/%s/\n", wwid); -+ if (ret >= (WWID_SIZE + 3) || ret < 0){ -+ condlog(0, "can't format wwid for writing (%d) : %s", -+ ret, strerror(errno)); -+ return -1; -+ } -+ offset = lseek(fd, 0, SEEK_END); -+ if (offset < 0) { -+ condlog(0, "can't seek to the end of wwids file : %s", -+ strerror(errno)); -+ return -1; -+ } -+ if (write_all(fd, buf, strlen(buf)) != strlen(buf)) { -+ condlog(0, "cannot write wwid to wwids file : %s", -+ strerror(errno)); -+ if (ftruncate(fd, offset)) -+ condlog(0, "cannot truncate failed wwid write : %s", -+ strerror(errno)); -+ return -1; -+ } -+ return 1; -+} -+ -+int -+check_wwids_file(char *wwid, int write_wwid) -+{ -+ int fd, can_write, found, ret; -+ FILE *f; -+ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); -+ if (fd < 0) -+ return -1; -+ -+ f = fdopen(fd, "r"); -+ if (!f) { -+ condlog(0,"can't fdopen wwids file : %s", strerror(errno)); -+ close(fd); -+ return -1; -+ } -+ found = lookup_wwid(f, wwid); -+ if (found) { -+ ret = 0; -+ goto out; -+ } -+ if (!write_wwid) { -+ ret = -1; -+ goto out; -+ } -+ if (!can_write) { -+ condlog(0, "wwids file is read-only. Can't write wwid"); -+ ret = -1; -+ goto out; -+ } -+ -+ if (fflush(f) != 0) { -+ condlog(0, "cannot fflush wwids file stream : %s", -+ strerror(errno)); -+ ret = -1; -+ goto out; -+ } -+ -+ ret = write_out_wwid(fd, wwid); -+out: -+ fclose(f); -+ return ret; -+} -+ -+int -+remember_wwid(char *wwid) -+{ -+ int ret = check_wwids_file(wwid, 1); -+ if (ret < 0){ -+ condlog(3, "failed writing wwid %s to wwids file", wwid); -+ return -1; -+ } -+ if (ret == 1) -+ condlog(3, "wrote wwid %s to wwids file", wwid); -+ else -+ condlog(4, "wwid %s already in wwids file", wwid); -+ return 0; -+} -Index: multipath-tools-120518/libmultipath/wwids.h -=================================================================== ---- /dev/null -+++ multipath-tools-120518/libmultipath/wwids.h -@@ -0,0 +1,18 @@ -+/* -+ * Copyright (c) 2010 Benjamin Marzinski, Redhat -+ */ -+ -+#ifndef _WWIDS_H -+#define _WWIDS_H -+ -+#define WWIDS_FILE_HEADER \ -+"# Multipath wwids, Version : 1.0\n" \ -+"# NOTE: This file is automatically maintained by multipath and multipathd.\n" \ -+"# You should not need to edit this file in normal circumstances.\n" \ -+"#\n" \ -+"# Valid WWIDs:\n" -+ -+int remember_wwid(char *wwid); -+int check_wwids_file(char *wwid, int write_wwid); -+ -+#endif /* _WWIDS_H */ -Index: multipath-tools-120518/libmultipath/discovery.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/discovery.c -+++ multipath-tools-120518/libmultipath/discovery.c -@@ -810,6 +810,8 @@ 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) -+ value = getenv(pp->uid_attribute); - if (value && strlen(value)) { - size_t len = WWID_SIZE; - diff --git a/multipath-tools/patches/0006-RH-multipath.rules.patch b/multipath-tools/patches/0002-RH-multipath.rules.patch similarity index 62% rename from multipath-tools/patches/0006-RH-multipath.rules.patch rename to multipath-tools/patches/0002-RH-multipath.rules.patch index bfcfc98b8..a910dc1cd 100644 --- a/multipath-tools/patches/0006-RH-multipath.rules.patch +++ b/multipath-tools/patches/0002-RH-multipath.rules.patch @@ -1,23 +1,17 @@ --- - multipath/Makefile | 6 +++--- - multipath/multipath.rules | 30 ++++++++++++++++++++++++------ - 2 files changed, 27 insertions(+), 9 deletions(-) + multipath/Makefile | 3 +++ + multipath/multipath.rules | 24 ++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) -Index: multipath-tools-120613/multipath/multipath.rules +Index: multipath-tools-130222/multipath/multipath.rules =================================================================== ---- multipath-tools-120613.orig/multipath/multipath.rules -+++ multipath-tools-120613/multipath/multipath.rules -@@ -1,7 +1,25 @@ --# --# udev rules for multipathing. --# The persistent symlinks are created with the kpartx 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" - --# socket for uevents --SUBSYSTEM=="block", RUN+="socket:/org/kernel/dm/multipath_event" ++ +ENV{MPATH_SBIN_PATH}="/sbin" +TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin" + @@ -30,25 +24,22 @@ Index: multipath-tools-120613/multipath/multipath.rules +ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \ + RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}" + -+RUN+="socket:/org/kernel/dm/multipath_event" +KERNEL!="dm-*", GOTO="end_mpath" -+ACTION!="change", 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 -p p $tempnode" ++RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode" +LABEL="end_mpath" -Index: multipath-tools-120613/multipath/Makefile +Index: multipath-tools-130222/multipath/Makefile =================================================================== ---- multipath-tools-120613.orig/multipath/Makefile -+++ multipath-tools-120613/multipath/Makefile -@@ -21,15 +21,15 @@ $(EXEC): $(OBJS) +--- 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)/etc/udev/rules.d -- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/etc/udev/rules.d/ + $(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) @@ -57,7 +48,6 @@ Index: multipath-tools-120613/multipath/Makefile $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir) uninstall: -- rm $(DESTDIR)/etc/udev/rules.d/multipath.rules + rm $(DESTDIR)/lib/udev/rules.d/62-multipath.rules rm $(DESTDIR)$(bindir)/$(EXEC) rm $(DESTDIR)$(mandir)/$(EXEC).8.gz diff --git a/multipath-tools/patches/0007-RH-Make-build-system-RH-Fedora-friendly.patch b/multipath-tools/patches/0003-RH-Make-build-system-RH-Fedora-friendly.patch similarity index 77% rename from multipath-tools/patches/0007-RH-Make-build-system-RH-Fedora-friendly.patch rename to multipath-tools/patches/0003-RH-Make-build-system-RH-Fedora-friendly.patch index bc5d17da5..f293c800c 100644 --- a/multipath-tools/patches/0007-RH-Make-build-system-RH-Fedora-friendly.patch +++ b/multipath-tools/patches/0003-RH-Make-build-system-RH-Fedora-friendly.patch @@ -9,16 +9,16 @@ Signed-off-by: Fabio M. Di Nitto :100644 100644 21e4ad4... 06d79c0... M kpartx/Makefile :100644 100644 32d9ef5... 25e1483... M multipathd/Makefile Makefile.inc | 2 +- - kpartx/Makefile | 8 ++++---- + kpartx/Makefile | 10 +++++----- libmpathpersist/Makefile | 7 ++----- libmultipath/Makefile | 2 ++ multipathd/Makefile | 1 + - 5 files changed, 10 insertions(+), 10 deletions(-) + 5 files changed, 11 insertions(+), 11 deletions(-) -Index: multipath-tools-120613/Makefile.inc +Index: multipath-tools-130222/Makefile.inc =================================================================== ---- multipath-tools-120613.orig/Makefile.inc -+++ multipath-tools-120613/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 @@ -28,11 +28,11 @@ Index: multipath-tools-120613/Makefile.inc syslibdir = $(prefix)/$(LIB) libdir = $(prefix)/$(LIB)/multipath unitdir = $(prefix)/lib/systemd/system -Index: multipath-tools-120613/kpartx/Makefile +Index: multipath-tools-130222/kpartx/Makefile =================================================================== ---- multipath-tools-120613.orig/kpartx/Makefile -+++ multipath-tools-120613/kpartx/Makefile -@@ -26,10 +26,10 @@ $(EXEC): $(OBJS) +--- 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) @@ -47,10 +47,18 @@ Index: multipath-tools-120613/kpartx/Makefile $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) -Index: multipath-tools-120613/multipathd/Makefile + 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-120613.orig/multipathd/Makefile -+++ multipath-tools-120613/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) @@ -59,10 +67,10 @@ Index: multipath-tools-120613/multipathd/Makefile $(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir) $(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) -Index: multipath-tools-120613/libmultipath/Makefile +Index: multipath-tools-130222/libmultipath/Makefile =================================================================== ---- multipath-tools-120613.orig/libmultipath/Makefile -+++ multipath-tools-120613/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) @@ -75,10 +83,10 @@ Index: multipath-tools-120613/libmultipath/Makefile clean: rm -f core *.a *.o *.gz *.so *.so.* -Index: multipath-tools-120613/libmpathpersist/Makefile +Index: multipath-tools-130222/libmpathpersist/Makefile =================================================================== ---- multipath-tools-120613.orig/libmpathpersist/Makefile -+++ multipath-tools-120613/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) diff --git a/multipath-tools/patches/0003-RH-add-followover.patch b/multipath-tools/patches/0003-RH-add-followover.patch deleted file mode 100644 index 9aeecf464..000000000 --- a/multipath-tools/patches/0003-RH-add-followover.patch +++ /dev/null @@ -1,235 +0,0 @@ ---- - libmultipath/dict.c | 12 ++++++++++++ - libmultipath/discovery.c | 6 +++--- - libmultipath/print.c | 2 ++ - libmultipath/structs.h | 4 +++- - multipath/main.c | 2 +- - multipath/multipath.conf.5 | 5 +++++ - multipathd/main.c | 35 ++++++++++++++++++++++++++++++++++- - 7 files changed, 60 insertions(+), 6 deletions(-) - -Index: multipath-tools-120518/libmultipath/dict.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/dict.c -+++ multipath-tools-120518/libmultipath/dict.c -@@ -398,6 +398,8 @@ default_failback_handler(vector strvec) - conf->pgfailback = -FAILBACK_MANUAL; - else if (strlen(buff) == 9 && !strcmp(buff, "immediate")) - conf->pgfailback = -FAILBACK_IMMEDIATE; -+ else if (strlen(buff) == 10 && !strcmp(buff, "followover")) -+ conf->pgfailback = -FAILBACK_FOLLOWOVER; - else - conf->pgfailback = atoi(buff); - -@@ -1053,6 +1055,8 @@ hw_failback_handler(vector strvec) - hwe->pgfailback = -FAILBACK_MANUAL; - else if (strlen(buff) == 9 && !strcmp(buff, "immediate")) - hwe->pgfailback = -FAILBACK_IMMEDIATE; -+ else if (strlen(buff) == 10 && !strcmp(buff, "followover")) -+ hwe->pgfailback = -FAILBACK_FOLLOWOVER; - else - hwe->pgfailback = atoi(buff); - -@@ -1351,6 +1355,8 @@ mp_failback_handler(vector strvec) - mpe->pgfailback = -FAILBACK_MANUAL; - else if (strlen(buff) == 9 && !strcmp(buff, "immediate")) - mpe->pgfailback = -FAILBACK_IMMEDIATE; -+ else if (strlen(buff) == 10 && !strcmp(buff, "followover")) -+ mpe->pgfailback = -FAILBACK_FOLLOWOVER; - else - mpe->pgfailback = atoi(buff); - -@@ -1769,6 +1775,8 @@ snprint_mp_failback (char * buff, int le - return snprintf(buff, len, "manual"); - case -FAILBACK_IMMEDIATE: - return snprintf(buff, len, "immediate"); -+ case -FAILBACK_FOLLOWOVER: -+ return snprintf(buff, len, "followover"); - default: - return snprintf(buff, len, "%i", mpe->pgfailback); - } -@@ -2130,6 +2138,8 @@ snprint_hw_failback (char * buff, int le - return snprintf(buff, len, "manual"); - case -FAILBACK_IMMEDIATE: - return snprintf(buff, len, "immediate"); -+ case -FAILBACK_FOLLOWOVER: -+ return snprintf(buff, len, "followover"); - default: - return snprintf(buff, len, "%i", hwe->pgfailback); - } -@@ -2394,6 +2404,8 @@ snprint_def_failback (char * buff, int l - return snprintf(buff, len, "manual"); - case -FAILBACK_IMMEDIATE: - return snprintf(buff, len, "immediate"); -+ case -FAILBACK_FOLLOWOVER: -+ return snprintf(buff, len, "followover"); - default: - return snprintf(buff, len, "%i", conf->pgfailback); - } -Index: multipath-tools-120518/libmultipath/print.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/print.c -+++ multipath-tools-120518/libmultipath/print.c -@@ -143,6 +143,8 @@ snprint_failback (char * buff, size_t le - { - if (mpp->pgfailback == -FAILBACK_IMMEDIATE) - return snprintf(buff, len, "immediate"); -+ if (mpp->pgfailback == -FAILBACK_FOLLOWOVER) -+ return snprintf(buff, len, "followover"); - - if (!mpp->failback_tick) - return snprintf(buff, len, "-"); -Index: multipath-tools-120518/libmultipath/structs.h -=================================================================== ---- multipath-tools-120518.orig/libmultipath/structs.h -+++ multipath-tools-120518/libmultipath/structs.h -@@ -39,7 +39,8 @@ enum rr_weight_mode { - enum failback_mode { - FAILBACK_UNDEF, - FAILBACK_MANUAL, -- FAILBACK_IMMEDIATE -+ FAILBACK_IMMEDIATE, -+ FAILBACK_FOLLOWOVER - }; - - enum sysfs_buses { -@@ -151,6 +152,7 @@ struct path { - int offline; - int state; - int dmstate; -+ int chkrstate; - int failcount; - int priority; - int pgindex; -Index: multipath-tools-120518/multipathd/main.c -=================================================================== ---- multipath-tools-120518.orig/multipathd/main.c -+++ multipath-tools-120518/multipathd/main.c -@@ -995,6 +995,32 @@ mpvec_garbage_collector (struct vectors - } - } - -+/* This is called after a path has started working again. It the multipath -+ * device for this path uses the followover failback type, and this is the -+ * best pathgroup, and this is the first path in the pathgroup to come back -+ * up, then switch to this pathgroup */ -+static int -+followover_should_failback(struct path * pp) -+{ -+ struct pathgroup * pgp; -+ struct path *pp1; -+ int i; -+ -+ if (pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER || -+ !pp->mpp->pg || !pp->pgindex || -+ pp->pgindex != pp->mpp->bestpg) -+ return 0; -+ -+ pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1); -+ vector_foreach_slot(pgp->paths, pp1, i) { -+ if (pp1 == pp) -+ continue; -+ if (pp1->chkrstate != PATH_DOWN && pp1->chkrstate != PATH_SHAKY) -+ return 0; -+ } -+ return 1; -+} -+ - static void - defered_failback_tick (vector mpvec) - { -@@ -1092,6 +1118,8 @@ check_path (struct vectors * vecs, struc - { - int newstate; - int new_path_up = 0; -+ int chkr_new_path_up = 0; -+ int oldchkrstate = pp->chkrstate; - - if (!pp->mpp) - return; -@@ -1130,6 +1158,7 @@ check_path (struct vectors * vecs, struc - pp->dev); - pp->dmstate = PSTATE_UNDEF; - } -+ pp->chkrstate = newstate; - if (newstate != pp->state) { - int oldstate = pp->state; - pp->state = newstate; -@@ -1182,6 +1211,9 @@ check_path (struct vectors * vecs, struc - - new_path_up = 1; - -+ if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) -+ chkr_new_path_up = 1; -+ - /* - * if at least one path is up in a group, and - * the group is disabled, re-enable it -@@ -1233,7 +1265,8 @@ check_path (struct vectors * vecs, struc - (new_path_up || pp->mpp->failback_tick <= 0)) - pp->mpp->failback_tick = - pp->mpp->pgfailback + 1; -- else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) -+ else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE || -+ (chkr_new_path_up && followover_should_failback(pp))) - switch_pathgroup(pp->mpp); - } - } -Index: multipath-tools-120518/multipath/multipath.conf.5 -=================================================================== ---- multipath-tools-120518.orig/multipath/multipath.conf.5 -+++ multipath-tools-120518/multipath/multipath.conf.5 -@@ -254,6 +254,11 @@ active paths. - .B manual - Do not perform automatic failback. - .TP -+.B followover -+Only perform automatic failback when the first path of a pathgroup -+becomes active. This keeps a node from automatically failing back when -+another node requested the failover. -+.TP - .B values > 0 - deferred failback (time to defer in seconds) - .TP -Index: multipath-tools-120518/libmultipath/discovery.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/discovery.c -+++ multipath-tools-120518/libmultipath/discovery.c -@@ -878,13 +878,13 @@ pathinfo (struct path *pp, vector hwtabl - - if (mask & DI_CHECKER) { - if (path_state == PATH_UP) { -- pp->state = get_state(pp, 0); -+ pp->chkrstate = pp->state = get_state(pp, 0); - if (pp->state == PATH_UNCHECKED || - pp->state == PATH_WILD) - goto blank; - } else { - condlog(3, "%s: path inaccessible", pp->dev); -- pp->state = path_state; -+ pp->chkrstate = pp->state = path_state; - } - } - -@@ -912,7 +912,7 @@ blank: - * Recoverable error, for example faulty or offline path - */ - memset(pp->wwid, 0, WWID_SIZE); -- pp->state = PATH_DOWN; -+ pp->chkrstate = pp->state = PATH_DOWN; - - return 0; - } -Index: multipath-tools-120518/multipath/main.c -=================================================================== ---- multipath-tools-120518.orig/multipath/main.c -+++ multipath-tools-120518/multipath/main.c -@@ -144,7 +144,7 @@ update_paths (struct multipath * mpp) - /* - * path is not in sysfs anymore - */ -- pp->state = PATH_DOWN; -+ pp->chkrstate = pp->state = PATH_DOWN; - continue; - } - pp->mpp = mpp; diff --git a/multipath-tools/patches/0004-RH-fix-cciss-names.patch b/multipath-tools/patches/0004-RH-fix-cciss-names.patch deleted file mode 100644 index 890a48399..000000000 --- a/multipath-tools/patches/0004-RH-fix-cciss-names.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- - multipath/main.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -Index: multipath-tools-120518/multipath/main.c -=================================================================== ---- multipath-tools-120518.orig/multipath/main.c -+++ multipath-tools-120518/multipath/main.c -@@ -409,6 +409,16 @@ 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[]) - { -@@ -514,6 +524,8 @@ 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; - diff --git a/multipath-tools/patches/0008-RH-multipathd-blacklist-all-by-default.patch b/multipath-tools/patches/0004-RH-multipathd-blacklist-all-by-default.patch similarity index 83% rename from multipath-tools/patches/0008-RH-multipathd-blacklist-all-by-default.patch rename to multipath-tools/patches/0004-RH-multipathd-blacklist-all-by-default.patch index 5bbf3ca82..2dda63c73 100644 --- a/multipath-tools/patches/0008-RH-multipathd-blacklist-all-by-default.patch +++ b/multipath-tools/patches/0004-RH-multipathd-blacklist-all-by-default.patch @@ -16,10 +16,10 @@ Signed-off-by: Fabio M. Di Nitto libmultipath/config.h | 1 + 2 files changed, 17 insertions(+) -Index: multipath-tools-120518/libmultipath/config.c +Index: multipath-tools-130222/libmultipath/config.c =================================================================== ---- multipath-tools-120518.orig/libmultipath/config.c -+++ multipath-tools-120518/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" @@ -28,7 +28,7 @@ Index: multipath-tools-120518/libmultipath/config.c static int hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2) -@@ -549,6 +550,21 @@ load_config (char * file) +@@ -585,6 +586,21 @@ load_config (char * file) } else { init_keywords(); @@ -50,10 +50,10 @@ Index: multipath-tools-120518/libmultipath/config.c } /* -Index: multipath-tools-120518/libmultipath/config.h +Index: multipath-tools-130222/libmultipath/config.h =================================================================== ---- multipath-tools-120518.orig/libmultipath/config.h -+++ multipath-tools-120518/libmultipath/config.h +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h @@ -6,6 +6,7 @@ #define ORIGIN_DEFAULT 0 diff --git a/multipath-tools/patches/0009-RH-add-mpathconf.patch b/multipath-tools/patches/0005-RH-add-mpathconf.patch similarity index 94% rename from multipath-tools/patches/0009-RH-add-mpathconf.patch rename to multipath-tools/patches/0005-RH-add-mpathconf.patch index 2a5bec8ec..ce1b2c76e 100644 --- a/multipath-tools/patches/0009-RH-add-mpathconf.patch +++ b/multipath-tools/patches/0005-RH-add-mpathconf.patch @@ -6,11 +6,11 @@ multipath/mpathconf.8 | 103 ++++++++++++++++ 5 files changed, 423 insertions(+), 2 deletions(-) -Index: multipath-tools-120613/libmultipath/config.c +Index: multipath-tools-130222/libmultipath/config.c =================================================================== ---- multipath-tools-120613.orig/libmultipath/config.c -+++ multipath-tools-120613/libmultipath/config.c -@@ -553,6 +553,7 @@ load_config (char * file) +--- 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)); @@ -18,10 +18,10 @@ Index: multipath-tools-120613/libmultipath/config.c if (conf->blist_devnode == NULL) { conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { -Index: multipath-tools-120613/multipath/Makefile +Index: multipath-tools-130222/multipath/Makefile =================================================================== ---- multipath-tools-120613.orig/multipath/Makefile -+++ multipath-tools-120613/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 @@ -50,11 +50,11 @@ Index: multipath-tools-120613/multipath/Makefile clean: rm -f core *.o $(EXEC) *.gz -Index: multipath-tools-120613/multipath/main.c +Index: multipath-tools-130222/multipath/main.c =================================================================== ---- multipath-tools-120613.orig/multipath/main.c -+++ multipath-tools-120613/multipath/main.c -@@ -432,10 +432,10 @@ main (int argc, char *argv[]) +--- multipath-tools-130222.orig/multipath/main.c ++++ multipath-tools-130222/multipath/main.c +@@ -433,10 +433,10 @@ main (int argc, char *argv[]) exit(1); } @@ -67,10 +67,10 @@ Index: multipath-tools-120613/multipath/main.c exit(1); while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) { -Index: multipath-tools-120613/multipath/mpathconf +Index: multipath-tools-130222/multipath/mpathconf =================================================================== --- /dev/null -+++ multipath-tools-120613/multipath/mpathconf ++++ multipath-tools-130222/multipath/mpathconf @@ -0,0 +1,312 @@ +#!/bin/sh +# @@ -384,10 +384,10 @@ Index: multipath-tools-120613/multipath/mpathconf +elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then + service multipathd reload +fi -Index: multipath-tools-120613/multipath/mpathconf.8 +Index: multipath-tools-130222/multipath/mpathconf.8 =================================================================== --- /dev/null -+++ multipath-tools-120613/multipath/mpathconf.8 ++++ multipath-tools-130222/multipath/mpathconf.8 @@ -0,0 +1,103 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME diff --git a/multipath-tools/patches/0005-RH-dont_start_with_no_config.patch b/multipath-tools/patches/0005-RH-dont_start_with_no_config.patch deleted file mode 100644 index 7efd925a2..000000000 --- a/multipath-tools/patches/0005-RH-dont_start_with_no_config.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- - multipathd/multipathd.service | 1 + - 1 file changed, 1 insertion(+) - -Index: multipath-tools-110916/multipathd/multipathd.service -=================================================================== ---- multipath-tools-110916.orig/multipathd/multipathd.service -+++ multipath-tools-110916/multipathd/multipathd.service -@@ -2,6 +2,7 @@ - Description=Device-Mapper Multipath Device Controller - Before=iscsi.service iscsid.service - After=syslog.target -+ConditionPathExists=/etc/multipath.conf - - [Service] - Type=forking diff --git a/multipath-tools/patches/0010-RH-add-find-multipaths.patch b/multipath-tools/patches/0006-RH-add-find-multipaths.patch similarity index 67% rename from multipath-tools/patches/0010-RH-add-find-multipaths.patch rename to multipath-tools/patches/0006-RH-add-find-multipaths.patch index 57eb0a8ed..4a0c36476 100644 --- a/multipath-tools/patches/0010-RH-add-find-multipaths.patch +++ b/multipath-tools/patches/0006-RH-add-find-multipaths.patch @@ -10,23 +10,23 @@ multipathd/main.c | 6 ++++++ 9 files changed, 82 insertions(+), 1 deletion(-) -Index: multipath-tools-120518/libmultipath/config.c +Index: multipath-tools-130222/libmultipath/config.c =================================================================== ---- multipath-tools-120518.orig/libmultipath/config.c -+++ multipath-tools-120518/libmultipath/config.c -@@ -514,6 +514,7 @@ load_config (char * file) +--- 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; - - /* - * preload default hwtable -Index: multipath-tools-120518/libmultipath/configure.c + 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-120518.orig/libmultipath/configure.c -+++ multipath-tools-120518/libmultipath/configure.c -@@ -497,6 +497,10 @@ coalesce_paths (struct vectors * vecs, v +--- 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); @@ -37,7 +37,7 @@ Index: multipath-tools-120518/libmultipath/configure.c if (force_reload) { vector_foreach_slot (pathvec, pp1, k) { pp1->mpp = NULL; -@@ -526,6 +530,13 @@ coalesce_paths (struct vectors * vecs, v +@@ -537,6 +541,13 @@ coalesce_paths (struct vectors * vecs, v if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE)) continue; @@ -51,22 +51,22 @@ Index: multipath-tools-120518/libmultipath/configure.c /* * at this point, we know we really got a new mp */ -Index: multipath-tools-120518/libmultipath/defaults.h +Index: multipath-tools-130222/libmultipath/defaults.h =================================================================== ---- multipath-tools-120518.orig/libmultipath/defaults.h -+++ multipath-tools-120518/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_CHECKINT 5 - #define MAX_CHECKINT(a) (a << 2) -Index: multipath-tools-120518/libmultipath/dict.c ++#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-120518.orig/libmultipath/dict.c -+++ multipath-tools-120518/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 } @@ -95,7 +95,7 @@ Index: multipath-tools-120518/libmultipath/dict.c def_names_handler(vector strvec) { char * buff; -@@ -2549,6 +2570,18 @@ snprint_def_log_checker_err (char * buff +@@ -2700,6 +2721,18 @@ snprint_def_log_checker_err (char * buff } static int @@ -114,19 +114,19 @@ Index: multipath-tools-120518/libmultipath/dict.c snprint_def_user_friendly_names (char * buff, int len, void * data) { if (conf->user_friendly_names == USER_FRIENDLY_NAMES_ON) -@@ -2646,6 +2679,7 @@ init_keywords(void) - install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file); +@@ -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); - __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-120518/libmultipath/wwids.c +Index: multipath-tools-130222/libmultipath/wwids.c =================================================================== ---- multipath-tools-120518.orig/libmultipath/wwids.c -+++ multipath-tools-120518/libmultipath/wwids.c -@@ -124,6 +124,32 @@ out: +--- multipath-tools-130222.orig/libmultipath/wwids.c ++++ multipath-tools-130222/libmultipath/wwids.c +@@ -125,6 +125,32 @@ out: } int @@ -159,10 +159,10 @@ Index: multipath-tools-120518/libmultipath/wwids.c remember_wwid(char *wwid) { int ret = check_wwids_file(wwid, 1); -Index: multipath-tools-120518/libmultipath/wwids.h +Index: multipath-tools-130222/libmultipath/wwids.h =================================================================== ---- multipath-tools-120518.orig/libmultipath/wwids.h -+++ multipath-tools-120518/libmultipath/wwids.h +--- multipath-tools-130222.orig/libmultipath/wwids.h ++++ multipath-tools-130222/libmultipath/wwids.h @@ -12,6 +12,7 @@ "#\n" \ "# Valid WWIDs:\n" @@ -171,11 +171,11 @@ Index: multipath-tools-120518/libmultipath/wwids.h int remember_wwid(char *wwid); int check_wwids_file(char *wwid, int write_wwid); -Index: multipath-tools-120518/multipath/main.c +Index: multipath-tools-130222/multipath/main.c =================================================================== ---- multipath-tools-120518.orig/multipath/main.c -+++ multipath-tools-120518/multipath/main.c -@@ -332,7 +332,7 @@ configure (void) +--- multipath-tools-130222.orig/multipath/main.c ++++ multipath-tools-130222/multipath/main.c +@@ -333,7 +333,7 @@ configure (void) /* * core logic entry point */ @@ -184,10 +184,10 @@ Index: multipath-tools-120518/multipath/main.c out: if (refwwid) -Index: multipath-tools-120518/multipathd/main.c +Index: multipath-tools-130222/multipathd/main.c =================================================================== ---- multipath-tools-120518.orig/multipathd/main.c -+++ multipath-tools-120518/multipathd/main.c +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c @@ -49,6 +49,7 @@ #include #include @@ -196,7 +196,7 @@ Index: multipath-tools-120518/multipathd/main.c #include #include -@@ -473,6 +474,11 @@ rescan: +@@ -471,6 +472,11 @@ rescan: return 1; } @@ -208,11 +208,11 @@ Index: multipath-tools-120518/multipathd/main.c condlog(4,"%s: creating new map", pp->dev); if ((mpp = add_map_with_path(vecs, pp, 1))) { mpp->action = ACT_CREATE; -Index: multipath-tools-120518/libmultipath/config.h +Index: multipath-tools-130222/libmultipath/config.h =================================================================== ---- multipath-tools-120518.orig/libmultipath/config.h -+++ multipath-tools-120518/libmultipath/config.h -@@ -104,6 +104,7 @@ struct config { +--- 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; diff --git a/multipath-tools/patches/0011-RH-add-hp_tur-checker.patch b/multipath-tools/patches/0007-RH-add-hp_tur-checker.patch similarity index 100% rename from multipath-tools/patches/0011-RH-add-hp_tur-checker.patch rename to multipath-tools/patches/0007-RH-add-hp_tur-checker.patch diff --git a/multipath-tools/patches/0008-RH-revert-partition-changes.patch b/multipath-tools/patches/0008-RH-revert-partition-changes.patch new file mode 100644 index 000000000..c563b0e26 --- /dev/null +++ b/multipath-tools/patches/0008-RH-revert-partition-changes.patch @@ -0,0 +1,45 @@ +--- + 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); + } diff --git a/multipath-tools/patches/0012-RH-RHEL5-style-partitions.patch b/multipath-tools/patches/0009-RH-RHEL5-style-partitions.patch similarity index 90% rename from multipath-tools/patches/0012-RH-RHEL5-style-partitions.patch rename to multipath-tools/patches/0009-RH-RHEL5-style-partitions.patch index 47fa725ee..a2691bb0b 100644 --- a/multipath-tools/patches/0012-RH-RHEL5-style-partitions.patch +++ b/multipath-tools/patches/0009-RH-RHEL5-style-partitions.patch @@ -6,10 +6,10 @@ kpartx/sun.c | 35 --------------- 5 files changed, 24 insertions(+), 177 deletions(-) -Index: multipath-tools-120123/kpartx/bsd.c +Index: multipath-tools-130222/kpartx/bsd.c =================================================================== ---- multipath-tools-120123.orig/kpartx/bsd.c -+++ multipath-tools-120123/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; @@ -60,10 +60,10 @@ Index: multipath-tools-120123/kpartx/bsd.c - } return n; } -Index: multipath-tools-120123/kpartx/dos.c +Index: multipath-tools-130222/kpartx/dos.c =================================================================== ---- multipath-tools-120123.orig/kpartx/dos.c -+++ multipath-tools-120123/kpartx/dos.c +--- multipath-tools-130222.orig/kpartx/dos.c ++++ multipath-tools-130222/kpartx/dos.c @@ -16,7 +16,7 @@ is_extended(int type) { } @@ -92,11 +92,11 @@ Index: multipath-tools-120123/kpartx/dos.c } } return n; -Index: multipath-tools-120123/kpartx/kpartx.c +Index: multipath-tools-130222/kpartx/kpartx.c =================================================================== ---- multipath-tools-120123.orig/kpartx/kpartx.c -+++ multipath-tools-120123/kpartx/kpartx.c -@@ -190,7 +190,7 @@ get_hotplug_device(void) +--- 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){ @@ -105,7 +105,7 @@ Index: multipath-tools-120123/kpartx/kpartx.c int fd = -1; struct slice all; struct pt *ptp; -@@ -380,49 +380,30 @@ main(int argc, char **argv){ +@@ -381,49 +381,30 @@ main(int argc, char **argv){ else continue; @@ -169,7 +169,7 @@ Index: multipath-tools-120123/kpartx/kpartx.c break; -@@ -461,16 +442,10 @@ main(int argc, char **argv){ +@@ -462,16 +443,10 @@ main(int argc, char **argv){ case ADD: case UPDATE: /* ADD and UPDATE share the same code that adds new partitions. */ @@ -187,7 +187,7 @@ Index: multipath-tools-120123/kpartx/kpartx.c if (safe_sprintf(partname, "%s%s%d", mapname, delim, j+1)) { fprintf(stderr, "partname too small\n"); -@@ -511,72 +486,6 @@ main(int argc, char **argv){ +@@ -512,72 +487,6 @@ main(int argc, char **argv){ slices[j].minor, slices[j].size, DM_TARGET, params); } @@ -260,10 +260,10 @@ Index: multipath-tools-120123/kpartx/kpartx.c if (what == ADD) { /* Skip code that removes devmappings for deleted partitions */ -Index: multipath-tools-120123/kpartx/kpartx.h +Index: multipath-tools-130222/kpartx/kpartx.h =================================================================== ---- multipath-tools-120123.orig/kpartx/kpartx.h -+++ multipath-tools-120123/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; @@ -272,10 +272,10 @@ Index: multipath-tools-120123/kpartx/kpartx.h int major; int minor; }; -Index: multipath-tools-120123/kpartx/sun.c +Index: multipath-tools-130222/kpartx/sun.c =================================================================== ---- multipath-tools-120123.orig/kpartx/sun.c -+++ multipath-tools-120123/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; diff --git a/multipath-tools/patches/0013-RH-dont-remove-map-on-enomem.patch b/multipath-tools/patches/0010-RH-dont-remove-map-on-enomem.patch similarity index 69% rename from multipath-tools/patches/0013-RH-dont-remove-map-on-enomem.patch rename to multipath-tools/patches/0010-RH-dont-remove-map-on-enomem.patch index b7ee42c43..1740c1076 100644 --- a/multipath-tools/patches/0013-RH-dont-remove-map-on-enomem.patch +++ b/multipath-tools/patches/0010-RH-dont-remove-map-on-enomem.patch @@ -2,11 +2,11 @@ multipathd/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -Index: multipath-tools-120518/multipathd/main.c +Index: multipath-tools-130222/multipathd/main.c =================================================================== ---- multipath-tools-120518.orig/multipathd/main.c -+++ multipath-tools-120518/multipathd/main.c -@@ -993,7 +993,8 @@ mpvec_garbage_collector (struct vectors +--- 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) { diff --git a/multipath-tools/patches/0014-RH-deprecate-uid-gid-mode.patch b/multipath-tools/patches/0011-RH-deprecate-uid-gid-mode.patch similarity index 100% rename from multipath-tools/patches/0014-RH-deprecate-uid-gid-mode.patch rename to multipath-tools/patches/0011-RH-deprecate-uid-gid-mode.patch diff --git a/multipath-tools/patches/0012-RH-kpartx-msg.patch b/multipath-tools/patches/0012-RH-kpartx-msg.patch new file mode 100644 index 000000000..7584c840f --- /dev/null +++ b/multipath-tools/patches/0012-RH-kpartx-msg.patch @@ -0,0 +1,24 @@ +--- + 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 diff --git a/multipath-tools/patches/0013-RHBZ-883981-cleanup-rpmdiff-issues.patch b/multipath-tools/patches/0013-RHBZ-883981-cleanup-rpmdiff-issues.patch new file mode 100644 index 000000000..03bce1742 --- /dev/null +++ b/multipath-tools/patches/0013-RHBZ-883981-cleanup-rpmdiff-issues.patch @@ -0,0 +1,148 @@ +--- + 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 diff --git a/multipath-tools/patches/0014-RH-handle-other-sector-sizes.patch b/multipath-tools/patches/0014-RH-handle-other-sector-sizes.patch new file mode 100644 index 000000000..d07e0d844 --- /dev/null +++ b/multipath-tools/patches/0014-RH-handle-other-sector-sizes.patch @@ -0,0 +1,31 @@ +--- + 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++; + } diff --git a/multipath-tools/patches/0015-RH-fix-output-buffer.patch b/multipath-tools/patches/0015-RH-fix-output-buffer.patch new file mode 100644 index 000000000..ffbbaadd8 --- /dev/null +++ b/multipath-tools/patches/0015-RH-fix-output-buffer.patch @@ -0,0 +1,62 @@ +--- + 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 + #include + #include ++#include ++#include + + #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 diff --git a/multipath-tools/patches/0015-RH-use-sync-support.patch b/multipath-tools/patches/0015-RH-use-sync-support.patch deleted file mode 100644 index c5dee9d0b..000000000 --- a/multipath-tools/patches/0015-RH-use-sync-support.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- - libmultipath/devmapper.c | 2 ++ - 1 file changed, 2 insertions(+) - -Index: multipath-tools-120518/libmultipath/devmapper.c -=================================================================== ---- multipath-tools-120518.orig/libmultipath/devmapper.c -+++ multipath-tools-120518/libmultipath/devmapper.c -@@ -1272,6 +1272,8 @@ dm_rename (char * old, char * new) - goto out; - if (!dm_task_run(dmt)) - goto out; -+ if (conf->daemon) -+ dm_task_update_nodes(); - - r = 1; - out: diff --git a/multipath-tools/patches/0016-RH-change-configs.patch b/multipath-tools/patches/0016-RH-change-configs.patch deleted file mode 100644 index 7942ea835..000000000 --- a/multipath-tools/patches/0016-RH-change-configs.patch +++ /dev/null @@ -1,541 +0,0 @@ ---- - libmultipath/config.c | 1 - libmultipath/hwtable.c | 65 ------------------------------------------------- - 2 files changed, 1 insertion(+), 65 deletions(-) - -Index: multipath-tools-120613/libmultipath/config.c -=================================================================== ---- multipath-tools-120613.orig/libmultipath/config.c -+++ multipath-tools-120613/libmultipath/config.c -@@ -515,6 +515,7 @@ load_config (char * file) - conf->checkint = DEFAULT_CHECKINT; - conf->max_checkint = MAX_CHECKINT(conf->checkint); - conf->find_multipaths = DEFAULT_FIND_MULTIPATHS; -+ conf->fast_io_fail = 5; - - /* - * preload default hwtable -Index: multipath-tools-120613/libmultipath/hwtable.c -=================================================================== ---- multipath-tools-120613.orig/libmultipath/hwtable.c -+++ multipath-tools-120613/libmultipath/hwtable.c -@@ -28,7 +28,6 @@ static struct hwentry default_hw[] = { - .product = "Compellent Vol", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -50,7 +49,6 @@ static struct hwentry default_hw[] = { - .product = "Xserve RAID ", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -72,7 +70,6 @@ static struct hwentry default_hw[] = { - .product = "VV", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -88,7 +85,6 @@ static struct hwentry default_hw[] = { - .product = "HSG80", - .features = "1 queue_if_no_path", - .hwhandler = "1 hp_sw", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -104,7 +100,6 @@ static struct hwentry default_hw[] = { - .product = "A6189A", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -121,7 +116,6 @@ static struct hwentry default_hw[] = { - .product = "(MSA|HSV)1.0.*", - .features = "1 queue_if_no_path", - .hwhandler = "1 hp_sw", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -137,7 +131,6 @@ static struct hwentry default_hw[] = { - .product = "MSA VOLUME", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -153,7 +146,6 @@ static struct hwentry default_hw[] = { - .product = "HSV1[01]1|HSV2[01]0|HSV300|HSV4[05]0", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -169,7 +161,6 @@ static struct hwentry default_hw[] = { - .product = "MSA2[02]12fc|MSA2012i", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -185,7 +176,6 @@ static struct hwentry default_hw[] = { - .product = "MSA2012sa|MSA23(12|24)(fc|i|sa)|MSA2000s VOLUME", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -202,7 +192,6 @@ static struct hwentry default_hw[] = { - .product = "HSVX700", - .features = DEFAULT_FEATURES, - .hwhandler = "1 alua", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -219,7 +208,6 @@ static struct hwentry default_hw[] = { - .product = "LOGICAL VOLUME.*", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -236,7 +224,6 @@ static struct hwentry default_hw[] = { - .product = "P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCSI", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -258,7 +245,6 @@ static struct hwentry default_hw[] = { - .product = "SAN DataDirector", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -280,7 +266,6 @@ static struct hwentry default_hw[] = { - .product = "SYMMETRIX", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -297,7 +282,6 @@ static struct hwentry default_hw[] = { - .bl_product = "LUNZ", - .features = "1 queue_if_no_path", - .hwhandler = "1 emc", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -314,7 +298,6 @@ static struct hwentry default_hw[] = { - .bl_product = "LUNZ", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -336,7 +319,6 @@ static struct hwentry default_hw[] = { - .product = "CentricStor", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_SERIAL, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -352,7 +334,6 @@ static struct hwentry default_hw[] = { - .product = "ETERNUS_DX(L|400|8000)", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -373,7 +354,6 @@ static struct hwentry default_hw[] = { - .product = "OPEN-.*", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -389,7 +369,6 @@ static struct hwentry default_hw[] = { - .product = "DF.*", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -411,7 +390,6 @@ static struct hwentry default_hw[] = { - .product = "ProFibre 4000R", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -429,7 +407,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "1 queue_if_no_path", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -447,7 +424,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "1 queue_if_no_path", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -465,7 +441,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "1 queue_if_no_path", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -483,7 +458,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -500,7 +474,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "2 pg_init_retries 50", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -518,7 +491,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -536,7 +508,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -554,7 +525,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -572,7 +542,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -589,7 +558,6 @@ static struct hwentry default_hw[] = { - .product = "^3542", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_SERIAL, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -606,7 +574,6 @@ static struct hwentry default_hw[] = { - .product = "^2105800", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_SERIAL, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -623,7 +590,6 @@ static struct hwentry default_hw[] = { - .product = "^2105F20", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_SERIAL, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -640,7 +606,6 @@ static struct hwentry default_hw[] = { - .product = "^1750500", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -657,7 +622,6 @@ static struct hwentry default_hw[] = { - .product = "^2107900", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -674,7 +638,6 @@ static struct hwentry default_hw[] = { - .product = "^2145", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -693,7 +656,6 @@ static struct hwentry default_hw[] = { - .uid_attribute = "ID_UID", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -712,7 +674,6 @@ static struct hwentry default_hw[] = { - .uid_attribute = "ID_UID", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -729,7 +690,6 @@ static struct hwentry default_hw[] = { - .product = "^IPR.*", - .features = "1 queue_if_no_path", - .hwhandler = "1 alua", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -746,7 +706,6 @@ static struct hwentry default_hw[] = { - .product = "1820N00", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -763,7 +722,6 @@ static struct hwentry default_hw[] = { - .product = "2810XIV", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = 15, - .rr_weight = RR_WEIGHT_NONE, -@@ -786,7 +744,6 @@ static struct hwentry default_hw[] = { - .product = "VDASD", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -803,7 +760,6 @@ static struct hwentry default_hw[] = { - .product = "3303 NVDISK", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = FAILOVER, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -820,7 +776,6 @@ static struct hwentry default_hw[] = { - .product = "NVDISK", - .features = DEFAULT_FEATURES, - .hwhandler = "1 alua", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -838,7 +793,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "2 pg_init_retries 50", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -856,7 +810,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "2 pg_init_retries 50", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -874,7 +827,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "2 pg_init_retries 50", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -892,7 +844,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "2 pg_init_retries 50", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -914,7 +865,6 @@ static struct hwentry default_hw[] = { - .product = "LUN.*", - .features = "3 queue_if_no_path pg_init_retries 50", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .flush_on_last_del = FLUSH_ENABLED, -@@ -936,7 +886,6 @@ static struct hwentry default_hw[] = { - .product = "COMSTAR", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_SERIAL, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -957,7 +906,6 @@ static struct hwentry default_hw[] = { - .product = "Nseries.*", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -978,7 +926,6 @@ static struct hwentry default_hw[] = { - .product = "Axiom.*", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -1001,7 +948,6 @@ static struct hwentry default_hw[] = { - .product = "TP9[13]00", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -1018,7 +964,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -1035,7 +980,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "2 pg_init_retries 50", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -1052,7 +996,6 @@ static struct hwentry default_hw[] = { - .product = "DISK ARRAY", - .features = DEFAULT_FEATURES, - .hwhandler = "1 alua", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -1075,7 +1018,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -1097,7 +1039,6 @@ static struct hwentry default_hw[] = { - .product = "(StorEdge 3510|T4)", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -1113,7 +1054,6 @@ static struct hwentry default_hw[] = { - .product = "FC2502", - .features = DEFAULT_FEATURES, - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -1135,7 +1075,6 @@ static struct hwentry default_hw[] = { - .product = "RAIGE VOLUME", - .features = "1 queue_if_no_path", - .hwhandler = DEFAULT_HWHANDLER, -- .selector = DEFAULT_SELECTOR, - .pgpolicy = MULTIBUS, - .pgfailback = FAILBACK_UNDEF, - .rr_weight = RR_WEIGHT_NONE, -@@ -1151,7 +1090,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -1169,7 +1107,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -1187,7 +1124,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = "2 pg_init_retries 50", - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, -@@ -1204,7 +1140,6 @@ static struct hwentry default_hw[] = { - .bl_product = "Universal Xport", - .features = DEFAULT_FEATURES, - .hwhandler = "1 rdac", -- .selector = DEFAULT_SELECTOR, - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .rr_weight = RR_WEIGHT_NONE, diff --git a/multipath-tools/patches/0016-RH-dont-print-ghost-messages.patch b/multipath-tools/patches/0016-RH-dont-print-ghost-messages.patch new file mode 100644 index 000000000..3387424d4 --- /dev/null +++ b/multipath-tools/patches/0016-RH-dont-print-ghost-messages.patch @@ -0,0 +1,18 @@ +--- + 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; diff --git a/multipath-tools/patches/0018-RH-fix-factorize.patch b/multipath-tools/patches/0018-RH-fix-factorize.patch new file mode 100644 index 000000000..1dfcab547 --- /dev/null +++ b/multipath-tools/patches/0018-RH-fix-factorize.patch @@ -0,0 +1,17 @@ +--- + 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 diff --git a/multipath-tools/patches/0019-RH-fix-sockets.patch b/multipath-tools/patches/0019-RH-fix-sockets.patch new file mode 100644 index 000000000..8639e2042 --- /dev/null +++ b/multipath-tools/patches/0019-RH-fix-sockets.patch @@ -0,0 +1,48 @@ +--- + 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 + #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) { diff --git a/multipath-tools/patches/0020-RHBZ-907360-static-pthread-init.patch b/multipath-tools/patches/0020-RHBZ-907360-static-pthread-init.patch new file mode 100644 index 000000000..bafa5ce4b --- /dev/null +++ b/multipath-tools/patches/0020-RHBZ-907360-static-pthread-init.patch @@ -0,0 +1,41 @@ +--- + 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; + } + diff --git a/multipath-tools/patches/0021-RHBZ-919119-respect-kernel-cmdline.patch b/multipath-tools/patches/0021-RHBZ-919119-respect-kernel-cmdline.patch new file mode 100644 index 000000000..cea1e4845 --- /dev/null +++ b/multipath-tools/patches/0021-RHBZ-919119-respect-kernel-cmdline.patch @@ -0,0 +1,30 @@ +--- + 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 + diff --git a/multipath-tools/patches/0022-RH-multipathd-check-wwids.patch b/multipath-tools/patches/0022-RH-multipathd-check-wwids.patch new file mode 100644 index 000000000..b6e8f42c0 --- /dev/null +++ b/multipath-tools/patches/0022-RH-multipathd-check-wwids.patch @@ -0,0 +1,16 @@ +--- + 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); + } + diff --git a/multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch b/multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch new file mode 100644 index 000000000..6de04bf4f --- /dev/null +++ b/multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch @@ -0,0 +1,239 @@ +--- + 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 diff --git a/multipath-tools/patches/0024-RH-multipath-wipe-wwids.patch b/multipath-tools/patches/0024-RH-multipath-wipe-wwids.patch new file mode 100644 index 000000000..b91836c6d --- /dev/null +++ b/multipath-tools/patches/0024-RH-multipath-wipe-wwids.patch @@ -0,0 +1,164 @@ +--- + 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 diff --git a/multipath-tools/patches/0025-UPBZ-916668_add_maj_min.patch b/multipath-tools/patches/0025-UPBZ-916668_add_maj_min.patch new file mode 100644 index 000000000..615533de8 --- /dev/null +++ b/multipath-tools/patches/0025-UPBZ-916668_add_maj_min.patch @@ -0,0 +1,29 @@ +--- + 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); + } + } + diff --git a/multipath-tools/patches/0026-fix-checker-time.patch b/multipath-tools/patches/0026-fix-checker-time.patch new file mode 100644 index 000000000..e05ef5813 --- /dev/null +++ b/multipath-tools/patches/0026-fix-checker-time.patch @@ -0,0 +1,23 @@ +--- + 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) { diff --git a/multipath-tools/patches/0027-RH-get-wwid.patch b/multipath-tools/patches/0027-RH-get-wwid.patch new file mode 100644 index 000000000..04217b46f --- /dev/null +++ b/multipath-tools/patches/0027-RH-get-wwid.patch @@ -0,0 +1,17 @@ +--- + 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); diff --git a/multipath-tools/patches/0028-RHBZ-929078-refresh-udev-dev.patch b/multipath-tools/patches/0028-RHBZ-929078-refresh-udev-dev.patch new file mode 100644 index 000000000..c14ddb55c --- /dev/null +++ b/multipath-tools/patches/0028-RHBZ-929078-refresh-udev-dev.patch @@ -0,0 +1,55 @@ +--- + 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 diff --git a/multipath-tools/patches/0029-RH-no-prio-put-msg.patch b/multipath-tools/patches/0029-RH-no-prio-put-msg.patch new file mode 100644 index 000000000..6ebdae0a4 --- /dev/null +++ b/multipath-tools/patches/0029-RH-no-prio-put-msg.patch @@ -0,0 +1,20 @@ +--- + 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); + } diff --git a/multipath-tools/patches/0030-RHBZ-916528-override-queue-no-daemon.patch b/multipath-tools/patches/0030-RHBZ-916528-override-queue-no-daemon.patch new file mode 100644 index 000000000..e663dedc9 --- /dev/null +++ b/multipath-tools/patches/0030-RHBZ-916528-override-queue-no-daemon.patch @@ -0,0 +1,200 @@ +--- + 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 diff --git a/multipath-tools/patches/0031-RHBZ-957188-kpartx-use-dm-name.patch b/multipath-tools/patches/0031-RHBZ-957188-kpartx-use-dm-name.patch new file mode 100644 index 000000000..282c517c0 --- /dev/null +++ b/multipath-tools/patches/0031-RHBZ-957188-kpartx-use-dm-name.patch @@ -0,0 +1,17 @@ +--- + 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); diff --git a/multipath-tools/patches/0032-RHBZ-956464-mpathconf-defaults.patch b/multipath-tools/patches/0032-RHBZ-956464-mpathconf-defaults.patch new file mode 100644 index 000000000..d63c32e2a --- /dev/null +++ b/multipath-tools/patches/0032-RHBZ-956464-mpathconf-defaults.patch @@ -0,0 +1,19 @@ +--- + 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 " +- echo "Set find_multipaths (Default n): --find_multipaths " ++ echo "Set user_friendly_names (Default y): --user_friendly_names " ++ echo "Set find_multipaths (Default y): --find_multipaths " + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " + echo "" diff --git a/multipath-tools/patches/0033-RHBZ-829963-e-series-conf.patch b/multipath-tools/patches/0033-RHBZ-829963-e-series-conf.patch new file mode 100644 index 000000000..d8fc1192b --- /dev/null +++ b/multipath-tools/patches/0033-RHBZ-829963-e-series-conf.patch @@ -0,0 +1,44 @@ +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 + +--- +--- + 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", diff --git a/multipath-tools/patches/0034-RHBZ-851416-mpathconf-display.patch b/multipath-tools/patches/0034-RHBZ-851416-mpathconf-display.patch new file mode 100644 index 000000000..e9e00ceb4 --- /dev/null +++ b/multipath-tools/patches/0034-RHBZ-851416-mpathconf-display.patch @@ -0,0 +1,53 @@ +--- + 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 diff --git a/multipath-tools/patches/0035-RHBZ-891921-list-mpp.patch b/multipath-tools/patches/0035-RHBZ-891921-list-mpp.patch new file mode 100644 index 000000000..b0bb7a25a --- /dev/null +++ b/multipath-tools/patches/0035-RHBZ-891921-list-mpp.patch @@ -0,0 +1,33 @@ +--- + 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} + }; + diff --git a/multipath-tools/patches/0036-RHBZ-949239-load-multipath-module.patch b/multipath-tools/patches/0036-RHBZ-949239-load-multipath-module.patch new file mode 100644 index 000000000..04a6f684c --- /dev/null +++ b/multipath-tools/patches/0036-RHBZ-949239-load-multipath-module.patch @@ -0,0 +1,16 @@ +--- + 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 diff --git a/multipath-tools/patches/0037-RHBZ-768873-fix-rename.patch b/multipath-tools/patches/0037-RHBZ-768873-fix-rename.patch new file mode 100644 index 000000000..7e05bd07c --- /dev/null +++ b/multipath-tools/patches/0037-RHBZ-768873-fix-rename.patch @@ -0,0 +1,87 @@ +--- + 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); + } + diff --git a/multipath-tools/patches/0038-RHBZ-799860-netapp-config.patch b/multipath-tools/patches/0038-RHBZ-799860-netapp-config.patch new file mode 100644 index 000000000..3b91f9ba9 --- /dev/null +++ b/multipath-tools/patches/0038-RHBZ-799860-netapp-config.patch @@ -0,0 +1,16 @@ +--- + 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, + }, + /* diff --git a/multipath-tools/patches/0039-RH-detect-prio-fix.patch b/multipath-tools/patches/0039-RH-detect-prio-fix.patch new file mode 100644 index 000000000..941a57087 --- /dev/null +++ b/multipath-tools/patches/0039-RH-detect-prio-fix.patch @@ -0,0 +1,28 @@ +--- + 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 diff --git a/multipath-tools/patches/0040-RH-bindings-fix.patch b/multipath-tools/patches/0040-RH-bindings-fix.patch new file mode 100644 index 000000000..c56f352ad --- /dev/null +++ b/multipath-tools/patches/0040-RH-bindings-fix.patch @@ -0,0 +1,101 @@ +--- + 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); diff --git a/multipath-tools/patches/0041-RH-check-for-erofs.patch b/multipath-tools/patches/0041-RH-check-for-erofs.patch new file mode 100644 index 000000000..d29d78d60 --- /dev/null +++ b/multipath-tools/patches/0041-RH-check-for-erofs.patch @@ -0,0 +1,121 @@ +--- + 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 *); diff --git a/multipath-tools/patches/0042-UP-fix-signal-handling.patch b/multipath-tools/patches/0042-UP-fix-signal-handling.patch new file mode 100644 index 000000000..4b4b40bf3 --- /dev/null +++ b/multipath-tools/patches/0042-UP-fix-signal-handling.patch @@ -0,0 +1,493 @@ +--- + 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 +-#include + #include "lock.h" + #include + +-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 + #include + #include ++#include + #include + + /* +@@ -52,6 +53,7 @@ + #include + #include + #include ++#include + + #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 + #include + #include +@@ -19,20 +20,21 @@ + #include + #include + #include +- ++#include + #include +- + #include + #include + #include + #include ++#include + #include + #include + ++#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 + diff --git a/multipath-tools/patches/0043-RH-signal-waiter.patch b/multipath-tools/patches/0043-RH-signal-waiter.patch new file mode 100644 index 000000000..a1a63ea03 --- /dev/null +++ b/multipath-tools/patches/0043-RH-signal-waiter.patch @@ -0,0 +1,71 @@ +--- + 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); diff --git a/multipath-tools/patches/0044-RHBZ-976688-fix-wipe-wwids.patch b/multipath-tools/patches/0044-RHBZ-976688-fix-wipe-wwids.patch new file mode 100644 index 000000000..6f7057465 --- /dev/null +++ b/multipath-tools/patches/0044-RHBZ-976688-fix-wipe-wwids.patch @@ -0,0 +1,28 @@ +--- + 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 + #include + #include ++#include + + #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", diff --git a/multipath-tools/patches/0045-RHBZ-977297-man-page-fix.patch b/multipath-tools/patches/0045-RHBZ-977297-man-page-fix.patch new file mode 100644 index 000000000..3ede0ce04 --- /dev/null +++ b/multipath-tools/patches/0045-RHBZ-977297-man-page-fix.patch @@ -0,0 +1,35 @@ +--- + 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 diff --git a/multipath-tools/patches/0046-RHBZ-883981-move-udev-rules.patch b/multipath-tools/patches/0046-RHBZ-883981-move-udev-rules.patch new file mode 100644 index 000000000..4e5bc8535 --- /dev/null +++ b/multipath-tools/patches/0046-RHBZ-883981-move-udev-rules.patch @@ -0,0 +1,28 @@ +--- + 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 diff --git a/multipath-tools/patches/0047-RHBZ-980777-kpartx-read-only-loop-devs.patch b/multipath-tools/patches/0047-RHBZ-980777-kpartx-read-only-loop-devs.patch new file mode 100644 index 000000000..ed79e2297 --- /dev/null +++ b/multipath-tools/patches/0047-RHBZ-980777-kpartx-read-only-loop-devs.patch @@ -0,0 +1,39 @@ +--- + 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) { diff --git a/multipath-tools/patches/0048-RH-print-defaults.patch b/multipath-tools/patches/0048-RH-print-defaults.patch new file mode 100644 index 000000000..be1ce572e --- /dev/null +++ b/multipath-tools/patches/0048-RH-print-defaults.patch @@ -0,0 +1,25 @@ +--- + 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"); + } diff --git a/multipath-tools/patches/0049-RH-remove-ID_FS_TYPE.patch b/multipath-tools/patches/0049-RH-remove-ID_FS_TYPE.patch new file mode 100644 index 000000000..732f50f77 --- /dev/null +++ b/multipath-tools/patches/0049-RH-remove-ID_FS_TYPE.patch @@ -0,0 +1,17 @@ +--- + 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}" diff --git a/multipath-tools/patches/0050-RH-listing-speedup.patch b/multipath-tools/patches/0050-RH-listing-speedup.patch new file mode 100644 index 000000000..4742634e6 --- /dev/null +++ b/multipath-tools/patches/0050-RH-listing-speedup.patch @@ -0,0 +1,17 @@ +--- + 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) diff --git a/multipath-tools/patches/0051-UP-fix-cli-resize.patch b/multipath-tools/patches/0051-UP-fix-cli-resize.patch new file mode 100644 index 000000000..f278607c8 --- /dev/null +++ b/multipath-tools/patches/0051-UP-fix-cli-resize.patch @@ -0,0 +1,23 @@ +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); diff --git a/multipath-tools/patches/0052-RH-fix-bad-derefs.patch b/multipath-tools/patches/0052-RH-fix-bad-derefs.patch new file mode 100644 index 000000000..db5f1dbef --- /dev/null +++ b/multipath-tools/patches/0052-RH-fix-bad-derefs.patch @@ -0,0 +1,54 @@ +--- + 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(); diff --git a/multipath-tools/patches/0053-UP-fix-failback.patch b/multipath-tools/patches/0053-UP-fix-failback.patch new file mode 100644 index 000000000..936655d54 --- /dev/null +++ b/multipath-tools/patches/0053-UP-fix-failback.patch @@ -0,0 +1,23 @@ +--- + 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); diff --git a/multipath-tools/patches/0054-UP-keep-udev-ref.patch b/multipath-tools/patches/0054-UP-keep-udev-ref.patch new file mode 100644 index 000000000..e42d716f0 --- /dev/null +++ b/multipath-tools/patches/0054-UP-keep-udev-ref.patch @@ -0,0 +1,308 @@ +--- + 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 + #include + #include +@@ -8,6 +7,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -20,6 +20,7 @@ + #include + #include + ++#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 + #include + #include +-#include "mpath_pr_ioctl.h" +-#include ++#include ++#include "mpath_pr_ioctl.h" ++#include + + #include + +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 + #include + #include ++#include + #include + #include "main.h" + #include +@@ -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 + #include + #include ++#include + + #include + #include +@@ -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 + diff --git a/multipath-tools/patches/0055-UP-handle-quiesced-paths.patch b/multipath-tools/patches/0055-UP-handle-quiesced-paths.patch new file mode 100644 index 000000000..0556a6129 --- /dev/null +++ b/multipath-tools/patches/0055-UP-handle-quiesced-paths.patch @@ -0,0 +1,16 @@ +--- + 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; diff --git a/multipath-tools/patches/0056-UP-alua-prio-fix.patch b/multipath-tools/patches/0056-UP-alua-prio-fix.patch new file mode 100644 index 000000000..0ac41aba0 --- /dev/null +++ b/multipath-tools/patches/0056-UP-alua-prio-fix.patch @@ -0,0 +1,17 @@ +--- + 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) { diff --git a/multipath-tools/patches/0057-UP-fix-tmo.patch b/multipath-tools/patches/0057-UP-fix-tmo.patch new file mode 100644 index 000000000..0bfc46bc2 --- /dev/null +++ b/multipath-tools/patches/0057-UP-fix-tmo.patch @@ -0,0 +1,329 @@ +--- + 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 diff --git a/multipath-tools/patches/0058-UP-fix-failback.patch b/multipath-tools/patches/0058-UP-fix-failback.patch new file mode 100644 index 000000000..d1fbaebe9 --- /dev/null +++ b/multipath-tools/patches/0058-UP-fix-failback.patch @@ -0,0 +1,17 @@ +--- + 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: diff --git a/multipath-tools/patches/0059-UP-flush-failure-queueing.patch b/multipath-tools/patches/0059-UP-flush-failure-queueing.patch new file mode 100644 index 000000000..f72f31418 --- /dev/null +++ b/multipath-tools/patches/0059-UP-flush-failure-queueing.patch @@ -0,0 +1,71 @@ +--- + 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); diff --git a/multipath-tools/patches/0060-UP-uevent-loop-udev.patch b/multipath-tools/patches/0060-UP-uevent-loop-udev.patch new file mode 100644 index 000000000..88fc00595 --- /dev/null +++ b/multipath-tools/patches/0060-UP-uevent-loop-udev.patch @@ -0,0 +1,127 @@ +--- + 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); diff --git a/multipath-tools/patches/0061-RH-display-find-mpaths.patch b/multipath-tools/patches/0061-RH-display-find-mpaths.patch new file mode 100644 index 000000000..05c63f081 --- /dev/null +++ b/multipath-tools/patches/0061-RH-display-find-mpaths.patch @@ -0,0 +1,17 @@ +--- + 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"); + diff --git a/multipath-tools/patches/0062-RH-dont-free-vecs.patch b/multipath-tools/patches/0062-RH-dont-free-vecs.patch new file mode 100644 index 000000000..f1c321747 --- /dev/null +++ b/multipath-tools/patches/0062-RH-dont-free-vecs.patch @@ -0,0 +1,28 @@ +--- + 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(); + diff --git a/multipath-tools/patches/0063-RH-fix-warning.patch b/multipath-tools/patches/0063-RH-fix-warning.patch new file mode 100644 index 000000000..7db805646 --- /dev/null +++ b/multipath-tools/patches/0063-RH-fix-warning.patch @@ -0,0 +1,26 @@ +--- + 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) { diff --git a/multipath-tools/patches/0064-fix-ID_FS-attrs.patch b/multipath-tools/patches/0064-fix-ID_FS-attrs.patch new file mode 100644 index 000000000..cb59a8544 --- /dev/null +++ b/multipath-tools/patches/0064-fix-ID_FS-attrs.patch @@ -0,0 +1,383 @@ +--- + 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 + #include + #include ++#include + + #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 /* for fcntl() */ + + #include ++#include + + #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 + #include + #include ++#include + + #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 + #include + #include ++#include + #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); diff --git a/multipath-tools/patches/0065-UPBZ-995538-fail-rdac-on-unavailable.patch b/multipath-tools/patches/0065-UPBZ-995538-fail-rdac-on-unavailable.patch new file mode 100644 index 000000000..ca72b6139 --- /dev/null +++ b/multipath-tools/patches/0065-UPBZ-995538-fail-rdac-on-unavailable.patch @@ -0,0 +1,21 @@ +--- + 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; + } diff --git a/multipath-tools/patches/0066-UP-dos-4k-partition-fix.patch b/multipath-tools/patches/0066-UP-dos-4k-partition-fix.patch new file mode 100644 index 000000000..a2d1b4418 --- /dev/null +++ b/multipath-tools/patches/0066-UP-dos-4k-partition-fix.patch @@ -0,0 +1,159 @@ +--- + 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 + #include + #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 + #include + #include ++#include + #include + #include + #include +@@ -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 ++#include + + /* + * 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 + */ diff --git a/multipath-tools/patches/0067-RHBZ-1022899-fix-udev-partition-handling.patch b/multipath-tools/patches/0067-RHBZ-1022899-fix-udev-partition-handling.patch new file mode 100644 index 000000000..6f0a3d8ba --- /dev/null +++ b/multipath-tools/patches/0067-RHBZ-1022899-fix-udev-partition-handling.patch @@ -0,0 +1,37 @@ +--- + 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" diff --git a/multipath-tools/patches/0068-RHBZ-1034578-label-partition-devices.patch b/multipath-tools/patches/0068-RHBZ-1034578-label-partition-devices.patch new file mode 100644 index 000000000..e8008f7dd --- /dev/null +++ b/multipath-tools/patches/0068-RHBZ-1034578-label-partition-devices.patch @@ -0,0 +1,18 @@ +--- + 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" diff --git a/multipath-tools/patches/0069-UPBZ-1033791-improve-rdac-checker.patch b/multipath-tools/patches/0069-UPBZ-1033791-improve-rdac-checker.patch new file mode 100644 index 000000000..c838f29ff --- /dev/null +++ b/multipath-tools/patches/0069-UPBZ-1033791-improve-rdac-checker.patch @@ -0,0 +1,153 @@ +--- + 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; + } + } + diff --git a/multipath-tools/patches/0070-RHBZ-1036503-blacklist-td-devs.patch b/multipath-tools/patches/0070-RHBZ-1036503-blacklist-td-devs.patch new file mode 100644 index 000000000..ffcae46c9 --- /dev/null +++ b/multipath-tools/patches/0070-RHBZ-1036503-blacklist-td-devs.patch @@ -0,0 +1,17 @@ +--- + 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)) diff --git a/multipath-tools/patches/0071-RHBZ-1031546-strip-dev.patch b/multipath-tools/patches/0071-RHBZ-1031546-strip-dev.patch new file mode 100644 index 000000000..64118c24b --- /dev/null +++ b/multipath-tools/patches/0071-RHBZ-1031546-strip-dev.patch @@ -0,0 +1,248 @@ +--- + 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); + diff --git a/multipath-tools/patches/0072-RHBZ-1039199-check-loop-control.patch b/multipath-tools/patches/0072-RHBZ-1039199-check-loop-control.patch new file mode 100644 index 000000000..21bd0c379 --- /dev/null +++ b/multipath-tools/patches/0072-RHBZ-1039199-check-loop-control.patch @@ -0,0 +1,46 @@ +--- + 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)) { diff --git a/multipath-tools/patches/0073-RH-update-build-flags.patch b/multipath-tools/patches/0073-RH-update-build-flags.patch new file mode 100644 index 000000000..3ab72d004 --- /dev/null +++ b/multipath-tools/patches/0073-RH-update-build-flags.patch @@ -0,0 +1,33 @@ +--- + 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); diff --git a/multipath-tools/patches/0074-RHBZ-1056976-dm-mpath-rules.patch b/multipath-tools/patches/0074-RHBZ-1056976-dm-mpath-rules.patch new file mode 100644 index 000000000..9f6c880c0 --- /dev/null +++ b/multipath-tools/patches/0074-RHBZ-1056976-dm-mpath-rules.patch @@ -0,0 +1,64 @@ +--- + 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 diff --git a/multipath-tools/patches/0075-RHBZ-1056976-reload-flag.patch b/multipath-tools/patches/0075-RHBZ-1056976-reload-flag.patch new file mode 100644 index 000000000..ee2cdee9a --- /dev/null +++ b/multipath-tools/patches/0075-RHBZ-1056976-reload-flag.patch @@ -0,0 +1,246 @@ +--- + 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); diff --git a/multipath-tools/patches/0076-RHBZ-1056686-add-hw_str_match.patch b/multipath-tools/patches/0076-RHBZ-1056686-add-hw_str_match.patch new file mode 100644 index 000000000..dc9aca61a --- /dev/null +++ b/multipath-tools/patches/0076-RHBZ-1056686-add-hw_str_match.patch @@ -0,0 +1,125 @@ +--- + 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 diff --git a/multipath-tools/patches/0078-RHBZ-1054044-fix-mpathconf-manpage.patch b/multipath-tools/patches/0078-RHBZ-1054044-fix-mpathconf-manpage.patch new file mode 100644 index 000000000..b06b4101f --- /dev/null +++ b/multipath-tools/patches/0078-RHBZ-1054044-fix-mpathconf-manpage.patch @@ -0,0 +1,17 @@ +--- + 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. diff --git a/multipath-tools/patches/0079-RHBZ-1070581-add-wwid-option.patch b/multipath-tools/patches/0079-RHBZ-1070581-add-wwid-option.patch new file mode 100644 index 000000000..e967a512c --- /dev/null +++ b/multipath-tools/patches/0079-RHBZ-1070581-add-wwid-option.patch @@ -0,0 +1,93 @@ +--- + 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 diff --git a/multipath-tools/patches/0080-RHBZ-1075796-cmdline-wwid.patch b/multipath-tools/patches/0080-RHBZ-1075796-cmdline-wwid.patch new file mode 100644 index 000000000..f943aa322 --- /dev/null +++ b/multipath-tools/patches/0080-RHBZ-1075796-cmdline-wwid.patch @@ -0,0 +1,157 @@ +--- + 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 diff --git a/multipath-tools/patches/0081-RHBZ-1066264-check-prefix-on-rename.patch b/multipath-tools/patches/0081-RHBZ-1066264-check-prefix-on-rename.patch new file mode 100644 index 000000000..791f32e29 --- /dev/null +++ b/multipath-tools/patches/0081-RHBZ-1066264-check-prefix-on-rename.patch @@ -0,0 +1,41 @@ +--- + 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); diff --git a/multipath-tools/patches/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch b/multipath-tools/patches/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch new file mode 100644 index 000000000..9a1bd344a --- /dev/null +++ b/multipath-tools/patches/0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch @@ -0,0 +1,32 @@ +--- + 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; diff --git a/multipath-tools/patches/0083-RHBZ-1080055-orphan-paths-on-reload.patch b/multipath-tools/patches/0083-RHBZ-1080055-orphan-paths-on-reload.patch new file mode 100644 index 000000000..8eaee7425 --- /dev/null +++ b/multipath-tools/patches/0083-RHBZ-1080055-orphan-paths-on-reload.patch @@ -0,0 +1,85 @@ +--- + 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; diff --git a/multipath-tools/patches/0084-RHBZ-1110000-multipath-man.patch b/multipath-tools/patches/0084-RHBZ-1110000-multipath-man.patch new file mode 100644 index 000000000..4ea422a39 --- /dev/null +++ b/multipath-tools/patches/0084-RHBZ-1110000-multipath-man.patch @@ -0,0 +1,101 @@ +--- + 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; + } + } diff --git a/multipath-tools/patches/0085-UPBZ-1110006-datacore-config.patch b/multipath-tools/patches/0085-UPBZ-1110006-datacore-config.patch new file mode 100644 index 000000000..cedb5e3ee --- /dev/null +++ b/multipath-tools/patches/0085-UPBZ-1110006-datacore-config.patch @@ -0,0 +1,28 @@ +--- + 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 + */ diff --git a/multipath-tools/patches/0086-RHBZ-1110007-orphan-path-on-failed-add.patch b/multipath-tools/patches/0086-RHBZ-1110007-orphan-path-on-failed-add.patch new file mode 100644 index 000000000..0d6aa589e --- /dev/null +++ b/multipath-tools/patches/0086-RHBZ-1110007-orphan-path-on-failed-add.patch @@ -0,0 +1,17 @@ +--- + 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); diff --git a/multipath-tools/patches/0087-RHBZ-1110013-config-error-checking.patch b/multipath-tools/patches/0087-RHBZ-1110013-config-error-checking.patch new file mode 100644 index 000000000..c774bc5f0 --- /dev/null +++ b/multipath-tools/patches/0087-RHBZ-1110013-config-error-checking.patch @@ -0,0 +1,190 @@ +--- + 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++) { diff --git a/multipath-tools/patches/0088-RHBZ-1069811-configurable-prio-timeout.patch b/multipath-tools/patches/0088-RHBZ-1069811-configurable-prio-timeout.patch new file mode 100644 index 000000000..60f374be1 --- /dev/null +++ b/multipath-tools/patches/0088-RHBZ-1069811-configurable-prio-timeout.patch @@ -0,0 +1,178 @@ +--- + 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 + ++#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/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/device/timeout + .TP + .B fast_io_fail_tmo diff --git a/multipath-tools/patches/0089-RHBZ-1110016-add-noasync-option.patch b/multipath-tools/patches/0089-RHBZ-1110016-add-noasync-option.patch new file mode 100644 index 000000000..2651c0e92 --- /dev/null +++ b/multipath-tools/patches/0089-RHBZ-1110016-add-noasync-option.patch @@ -0,0 +1,158 @@ +--- + 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 diff --git a/multipath-tools/patches/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch b/multipath-tools/patches/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch new file mode 100644 index 000000000..44f840731 --- /dev/null +++ b/multipath-tools/patches/0090-UPBZ-1080038-reorder-paths-for-round-robin.patch @@ -0,0 +1,529 @@ +--- + 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); + diff --git a/multipath-tools/patches/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch b/multipath-tools/patches/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch new file mode 100644 index 000000000..d164de132 --- /dev/null +++ b/multipath-tools/patches/0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch @@ -0,0 +1,38 @@ +--- + 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) diff --git a/multipath-tools/patches/0092-UPBZ-1104605-reload-on-rename.patch b/multipath-tools/patches/0092-UPBZ-1104605-reload-on-rename.patch new file mode 100644 index 000000000..465257c0c --- /dev/null +++ b/multipath-tools/patches/0092-UPBZ-1104605-reload-on-rename.patch @@ -0,0 +1,63 @@ +--- + 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; + diff --git a/multipath-tools/patches/0093-UPBZ-1086825-user-friendly-name-remap.patch b/multipath-tools/patches/0093-UPBZ-1086825-user-friendly-name-remap.patch new file mode 100644 index 000000000..ab5abbd1c --- /dev/null +++ b/multipath-tools/patches/0093-UPBZ-1086825-user-friendly-name-remap.patch @@ -0,0 +1,199 @@ +--- + 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; diff --git a/multipath-tools/patches/0094-RHBZ-1086825-cleanup-remap.patch b/multipath-tools/patches/0094-RHBZ-1086825-cleanup-remap.patch new file mode 100644 index 000000000..7d85c2d2e --- /dev/null +++ b/multipath-tools/patches/0094-RHBZ-1086825-cleanup-remap.patch @@ -0,0 +1,107 @@ +--- + 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, diff --git a/multipath-tools/patches/0095-RHBZ-1127944-xtremIO-config.patch b/multipath-tools/patches/0095-RHBZ-1127944-xtremIO-config.patch new file mode 100644 index 000000000..6807cbc3f --- /dev/null +++ b/multipath-tools/patches/0095-RHBZ-1127944-xtremIO-config.patch @@ -0,0 +1,28 @@ +--- + 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 + */ diff --git a/multipath-tools/patches/0096-RHBZ-979474-new-wildcards.patch b/multipath-tools/patches/0096-RHBZ-979474-new-wildcards.patch new file mode 100644 index 000000000..9025efe40 --- /dev/null +++ b/multipath-tools/patches/0096-RHBZ-979474-new-wildcards.patch @@ -0,0 +1,120 @@ +--- + 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 + #include + #include ++#include + + #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} + }; + diff --git a/multipath-tools/patches/0097-RH-fix-coverity-errors.patch b/multipath-tools/patches/0097-RH-fix-coverity-errors.patch new file mode 100644 index 000000000..8ce0e87de --- /dev/null +++ b/multipath-tools/patches/0097-RH-fix-coverity-errors.patch @@ -0,0 +1,158 @@ +--- + 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) { diff --git a/multipath-tools/patches/0098-UPBZ-1067171-mutipath-i.patch b/multipath-tools/patches/0098-UPBZ-1067171-mutipath-i.patch new file mode 100644 index 000000000..cf41863ed --- /dev/null +++ b/multipath-tools/patches/0098-UPBZ-1067171-mutipath-i.patch @@ -0,0 +1,332 @@ +--- + 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; diff --git a/multipath-tools/patches/0099-RH-add-all-devs.patch b/multipath-tools/patches/0099-RH-add-all-devs.patch new file mode 100644 index 000000000..aca6d4c38 --- /dev/null +++ b/multipath-tools/patches/0099-RH-add-all-devs.patch @@ -0,0 +1,170 @@ +--- + 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); diff --git a/multipath-tools/patches/0100-RHBZ-1067171-multipath-i-update.patch b/multipath-tools/patches/0100-RHBZ-1067171-multipath-i-update.patch new file mode 100644 index 000000000..9a67e7aa9 --- /dev/null +++ b/multipath-tools/patches/0100-RHBZ-1067171-multipath-i-update.patch @@ -0,0 +1,54 @@ +--- + 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; diff --git a/multipath-tools/patches/0101-RH-adapter-name-wildcard.patch b/multipath-tools/patches/0101-RH-adapter-name-wildcard.patch new file mode 100644 index 000000000..3c67de5b8 --- /dev/null +++ b/multipath-tools/patches/0101-RH-adapter-name-wildcard.patch @@ -0,0 +1,33 @@ +--- + 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} + }; + diff --git a/multipath-tools/patches/0102-RHBZ-1160478-mpathconf-template.patch b/multipath-tools/patches/0102-RHBZ-1160478-mpathconf-template.patch new file mode 100644 index 000000000..3c0e44346 --- /dev/null +++ b/multipath-tools/patches/0102-RHBZ-1160478-mpathconf-template.patch @@ -0,0 +1,52 @@ +--- + 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 diff --git a/multipath-tools/patches/0103-RH-cleanup-partmaps-code.patch b/multipath-tools/patches/0103-RH-cleanup-partmaps-code.patch new file mode 100644 index 000000000..57fb402c7 --- /dev/null +++ b/multipath-tools/patches/0103-RH-cleanup-partmaps-code.patch @@ -0,0 +1,199 @@ +--- + 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 diff --git a/multipath-tools/patches/0104-RHBZ-631009-deferred-remove.patch b/multipath-tools/patches/0104-RHBZ-631009-deferred-remove.patch new file mode 100644 index 000000000..1e1367a23 --- /dev/null +++ b/multipath-tools/patches/0104-RHBZ-631009-deferred-remove.patch @@ -0,0 +1,751 @@ +--- + 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) + diff --git a/multipath-tools/patches/0105-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch b/multipath-tools/patches/0105-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch new file mode 100644 index 000000000..8c793bbf0 --- /dev/null +++ b/multipath-tools/patches/0105-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch @@ -0,0 +1,10 @@ +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" diff --git a/multipath-tools/patches/0106-RHBZ-1159337-fix-double-free.patch b/multipath-tools/patches/0106-RHBZ-1159337-fix-double-free.patch new file mode 100644 index 000000000..cbe4d1e7e --- /dev/null +++ b/multipath-tools/patches/0106-RHBZ-1159337-fix-double-free.patch @@ -0,0 +1,20 @@ +--- + 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", diff --git a/multipath-tools/patches/0107-RHBZ-1169935-no-new-devs.patch b/multipath-tools/patches/0107-RHBZ-1169935-no-new-devs.patch new file mode 100644 index 000000000..99ae35a73 --- /dev/null +++ b/multipath-tools/patches/0107-RHBZ-1169935-no-new-devs.patch @@ -0,0 +1,231 @@ +--- + 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 + #include + #include ++#include ++#include + + #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) diff --git a/multipath-tools/patches/0108-RHBZ-1153832-kpartx-remove-devs.patch b/multipath-tools/patches/0108-RHBZ-1153832-kpartx-remove-devs.patch new file mode 100644 index 000000000..f02551a5b --- /dev/null +++ b/multipath-tools/patches/0108-RHBZ-1153832-kpartx-remove-devs.patch @@ -0,0 +1,15 @@ +--- + 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" diff --git a/multipath-tools/patches/0109-RH-read-only-bindings.patch b/multipath-tools/patches/0109-RH-read-only-bindings.patch new file mode 100644 index 000000000..c08120fb8 --- /dev/null +++ b/multipath-tools/patches/0109-RH-read-only-bindings.patch @@ -0,0 +1,27 @@ +--- + 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: + ; + } diff --git a/multipath-tools/patches/0110-RHBZ-blacklist-vd-devs.patch b/multipath-tools/patches/0110-RHBZ-blacklist-vd-devs.patch new file mode 100644 index 000000000..af52d0de5 --- /dev/null +++ b/multipath-tools/patches/0110-RHBZ-blacklist-vd-devs.patch @@ -0,0 +1,17 @@ +--- + 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)) diff --git a/multipath-tools/patches/0111-RH-dont-show-pg-timeout.patch b/multipath-tools/patches/0111-RH-dont-show-pg-timeout.patch new file mode 100644 index 000000000..f545cc5a9 --- /dev/null +++ b/multipath-tools/patches/0111-RH-dont-show-pg-timeout.patch @@ -0,0 +1,147 @@ +--- + 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; + } + diff --git a/multipath-tools/patches/0112-RHBZ-1194917-add-config_dir-option.patch b/multipath-tools/patches/0112-RHBZ-1194917-add-config_dir-option.patch new file mode 100644 index 000000000..e3226149d --- /dev/null +++ b/multipath-tools/patches/0112-RHBZ-1194917-add-config_dir-option.patch @@ -0,0 +1,616 @@ +--- + 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 ++#include + + #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 + #include + #include ++#include ++#include ++#include + + #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 diff --git a/multipath-tools/patches/0113-RHBZ-1194917-cleanup.patch b/multipath-tools/patches/0113-RHBZ-1194917-cleanup.patch new file mode 100644 index 000000000..cf95c9843 --- /dev/null +++ b/multipath-tools/patches/0113-RHBZ-1194917-cleanup.patch @@ -0,0 +1,185 @@ +--- + 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); diff --git a/multipath-tools/patches/0114-RHBZ-1196394-delayed-reintegration.patch b/multipath-tools/patches/0114-RHBZ-1196394-delayed-reintegration.patch new file mode 100644 index 000000000..78e43ee4b --- /dev/null +++ b/multipath-tools/patches/0114-RHBZ-1196394-delayed-reintegration.patch @@ -0,0 +1,744 @@ +--- + 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| > 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| > 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 diff --git a/multipath-tools/patches/0115-RHBZ-1198418-fix-double-free.patch b/multipath-tools/patches/0115-RHBZ-1198418-fix-double-free.patch new file mode 100644 index 000000000..a40376059 --- /dev/null +++ b/multipath-tools/patches/0115-RHBZ-1198418-fix-double-free.patch @@ -0,0 +1,28 @@ +--- + 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); + diff --git a/multipath-tools/patches/0116-UPBZ-1188179-dell-36xxi.patch b/multipath-tools/patches/0116-UPBZ-1188179-dell-36xxi.patch new file mode 100644 index 000000000..e32118b46 --- /dev/null +++ b/multipath-tools/patches/0116-UPBZ-1188179-dell-36xxi.patch @@ -0,0 +1,83 @@ +--- + 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" diff --git a/multipath-tools/patches/0117-RHBZ-1198424-autodetect-clariion-alua.patch b/multipath-tools/patches/0117-RHBZ-1198424-autodetect-clariion-alua.patch new file mode 100644 index 000000000..64a302d50 --- /dev/null +++ b/multipath-tools/patches/0117-RHBZ-1198424-autodetect-clariion-alua.patch @@ -0,0 +1,31 @@ +--- + 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"