diff options
Diffstat (limited to '0009-RH-add-find-multipaths.patch')
-rw-r--r-- | 0009-RH-add-find-multipaths.patch | 824 |
1 files changed, 824 insertions, 0 deletions
diff --git a/0009-RH-add-find-multipaths.patch b/0009-RH-add-find-multipaths.patch new file mode 100644 index 0000000..b706687 --- /dev/null +++ b/0009-RH-add-find-multipaths.patch @@ -0,0 +1,824 @@ +--- + libmultipath/Makefile | 2 + libmultipath/alias.c | 151 --------------------------------------- + libmultipath/alias.h | 1 + libmultipath/config.c | 1 + libmultipath/config.h | 1 + libmultipath/configure.c | 14 +++ + libmultipath/defaults.h | 2 + libmultipath/dict.c | 34 ++++++++ + libmultipath/file.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++ + libmultipath/file.h | 11 ++ + libmultipath/finder.c | 165 +++++++++++++++++++++++++++++++++++++++++++ + libmultipath/finder.h | 18 ++++ + multipath/main.c | 4 - + multipathd/main.c | 6 + + 14 files changed, 437 insertions(+), 151 deletions(-) + +Index: multipath-tools-111219/libmultipath/alias.c +=================================================================== +--- multipath-tools-111219.orig/libmultipath/alias.c ++++ multipath-tools-111219/libmultipath/alias.c +@@ -3,19 +3,16 @@ + * Copyright (c) 2005 Benjamin Marzinski, Redhat + */ + #include <stdlib.h> +-#include <sys/types.h> +-#include <sys/stat.h> +-#include <fcntl.h> + #include <errno.h> + #include <unistd.h> + #include <string.h> + #include <limits.h> + #include <stdio.h> +-#include <signal.h> + + #include "debug.h" + #include "uxsock.h" + #include "alias.h" ++#include "file.h" + + + /* +@@ -36,148 +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 */ +- ftruncate(fd, 0); +- 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) +@@ -366,7 +221,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; + +@@ -416,7 +271,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-111219/libmultipath/alias.h +=================================================================== +--- multipath-tools-111219.orig/libmultipath/alias.h ++++ multipath-tools-111219/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-111219/libmultipath/config.c +=================================================================== +--- multipath-tools-111219.orig/libmultipath/config.c ++++ multipath-tools-111219/libmultipath/config.c +@@ -504,6 +504,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-111219/libmultipath/configure.c +=================================================================== +--- multipath-tools-111219.orig/libmultipath/configure.c ++++ multipath-tools-111219/libmultipath/configure.c +@@ -36,6 +36,7 @@ + #include "prio.h" + #include "util.h" + #include "uxsock.h" ++#include "finder.h" + + extern int + setup_map (struct multipath * mpp, char * params, int params_size) +@@ -405,6 +406,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); +@@ -492,6 +495,10 @@ coalesce_paths (struct vectors * vecs, v + + memset(empty_buff, 0, WWID_SIZE); + ++ /* ignore refwwid if it's empty */ ++ if (refwwid && !strlen(refwwid)) ++ refwwid = NULL; ++ + if (force_reload) { + vector_foreach_slot (pathvec, pp1, k) { + pp1->mpp = NULL; +@@ -521,6 +528,13 @@ coalesce_paths (struct vectors * vecs, v + if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE)) + continue; + ++ /* If find_multipaths was selected check if the path is valid */ ++ if (conf->find_multipaths && !refwwid && ++ !should_multipath(pp1, pathvec)) { ++ orphan_path(pp1); ++ continue; ++ } ++ + /* + * at this point, we know we really got a new mp + */ +Index: multipath-tools-111219/libmultipath/defaults.h +=================================================================== +--- multipath-tools-111219.orig/libmultipath/defaults.h ++++ multipath-tools-111219/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) +@@ -24,5 +25,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-111219/libmultipath/dict.c +=================================================================== +--- multipath-tools-111219.orig/libmultipath/dict.c ++++ multipath-tools-111219/libmultipath/dict.c +@@ -544,6 +544,27 @@ def_log_checker_err_handler(vector strve + } + + static int ++def_find_multipaths_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ conf->find_multipaths = 0; ++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || ++ (strlen(buff) == 1 && !strcmp(buff, "1"))) ++ conf->find_multipaths = 1; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int + names_handler(vector strvec) + { + char * buff; +@@ -2365,6 +2386,18 @@ snprint_def_log_checker_err (char * buff + } + + static int ++snprint_def_find_multipaths (char * buff, int len, void * data) ++{ ++ if (conf->find_multipaths == DEFAULT_FIND_MULTIPATHS) ++ return 0; ++ if (!conf->find_multipaths) ++ return snprintf(buff, len, "no"); ++ ++ return snprintf(buff, len, "yes"); ++} ++ ++ ++static int + snprint_def_user_friendly_names (char * buff, int len, void * data) + { + if (!conf->user_friendly_names) +@@ -2456,6 +2489,7 @@ init_keywords(void) + install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); + install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file); + install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err); ++ install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL); +Index: multipath-tools-111219/libmultipath/file.c +=================================================================== +--- /dev/null ++++ multipath-tools-111219/libmultipath/file.c +@@ -0,0 +1,178 @@ ++/* ++ * Copyright (c) 2005 Christophe Varoqui ++ * Copyright (c) 2005 Benjamin Marzinski, Redhat ++ */ ++#include <stdlib.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <errno.h> ++#include <unistd.h> ++#include <string.h> ++#include <limits.h> ++#include <stdio.h> ++#include <signal.h> ++ ++#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 */ ++ ftruncate(fd, 0); ++ goto fail; ++ } ++ fsync(fd); ++ condlog(3, "Initialized new file [%s]", file); ++ } ++ ++ return fd; ++ ++fail: ++ close(fd); ++ return -1; ++} +Index: multipath-tools-111219/libmultipath/file.h +=================================================================== +--- /dev/null ++++ multipath-tools-111219/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-111219/libmultipath/finder.c +=================================================================== +--- /dev/null ++++ multipath-tools-111219/libmultipath/finder.c +@@ -0,0 +1,165 @@ ++#include <stdlib.h> ++#include <errno.h> ++#include <unistd.h> ++#include <string.h> ++#include <limits.h> ++#include <stdio.h> ++ ++#include "checkers.h" ++#include "vector.h" ++#include "structs.h" ++#include "debug.h" ++#include "uxsock.h" ++#include "file.h" ++#include "finder.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)); ++ ftruncate(fd, offset); ++ return -1; ++ } ++ return 1; ++} ++ ++static int ++check_wwids_file(char *wwid, int write_wwid) ++{ ++ int scan_fd, fd, can_write, found, ret; ++ FILE *f; ++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER); ++ if (fd < 0) ++ return -1; ++ ++ scan_fd = dup(fd); ++ if (scan_fd < 0) { ++ condlog(0, "can't dup wwids file descriptor : %s", ++ strerror(errno)); ++ close(fd); ++ return -1; ++ } ++ f = fdopen(scan_fd, "r"); ++ if (!f) { ++ condlog(0,"can't fdopen wwids file : %s", strerror(errno)); ++ close(fd); ++ close(scan_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; ++ } ++ ret = write_out_wwid(fd, wwid); ++out: ++ fclose(f); ++ close(scan_fd); ++ close(fd); ++ return ret; ++} ++ ++int ++should_multipath(struct path *pp1, vector pathvec) ++{ ++ int i; ++ struct path *pp2; ++ ++ condlog(4, "checking if %s should be multipathed", pp1->dev); ++ vector_foreach_slot(pathvec, pp2, i) { ++ if (pp1->dev == pp2->dev) ++ continue; ++ if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) { ++ condlog(3, "found multiple paths with wwid %s, " ++ "multipathing %s", pp1->wwid, pp1->dev); ++ return 1; ++ } ++ } ++ if (check_wwids_file(pp1->wwid, 0) < 0) { ++ condlog(3, "wwid %s not in wwids file, skipping %s", ++ pp1->wwid, pp1->dev); ++ return 0; ++ } ++ condlog(3, "found wwid %s in wwids file, multipathing %s", pp1->wwid, ++ pp1->dev); ++ return 1; ++} ++ ++int ++remember_wwid(char *wwid) ++{ ++ int ret = check_wwids_file(wwid, 1); ++ 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-111219/libmultipath/finder.h +=================================================================== +--- /dev/null ++++ multipath-tools-111219/libmultipath/finder.h +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (c) 2010 Benjamin Marzinski, Redhat ++ */ ++ ++#ifndef _FINDER_H ++#define _FINDER_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 should_multipath(struct path *pp, vector pathvec); ++int remember_wwid(char *wwid); ++ ++#endif /* _FINDER_H */ +Index: multipath-tools-111219/multipath/main.c +=================================================================== +--- multipath-tools-111219.orig/multipath/main.c ++++ multipath-tools-111219/multipath/main.c +@@ -53,6 +53,7 @@ + #include <errno.h> + #include <sys/time.h> + #include <sys/resource.h> ++#include <finder.h> + #include "dev_t.h" + + int logsink; +@@ -209,6 +210,7 @@ get_dm_mpvec (vector curmp, vector pathv + + if (!conf->dry_run) + reinstate_paths(mpp); ++ remember_wwid(mpp->wwid); + } + return 0; + } +@@ -316,7 +318,7 @@ configure (void) + /* + * core logic entry point + */ +- r = coalesce_paths(&vecs, NULL, NULL, conf->force_reload); ++ r = coalesce_paths(&vecs, NULL, refwwid, conf->force_reload); + + out: + if (refwwid) +Index: multipath-tools-111219/multipathd/main.c +=================================================================== +--- multipath-tools-111219.orig/multipathd/main.c ++++ multipath-tools-111219/multipathd/main.c +@@ -48,6 +48,7 @@ + #include <print.h> + #include <configure.h> + #include <prio.h> ++#include <finder.h> + #include <pgpolicies.h> + #include <uevent.h> + +@@ -471,6 +472,11 @@ rescan: + return 1; + } + ++ if (conf->find_multipaths && ++ !should_multipath(pp, vecs->pathvec)) { ++ orphan_path(pp); ++ return 0; ++ } + condlog(4,"%s: creating new map", pp->dev); + if ((mpp = add_map_with_path(vecs, pp, 1))) { + mpp->action = ACT_CREATE; +Index: multipath-tools-111219/libmultipath/Makefile +=================================================================== +--- multipath-tools-111219.orig/libmultipath/Makefile ++++ multipath-tools-111219/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 finder.o + + LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h) + +Index: multipath-tools-111219/libmultipath/config.h +=================================================================== +--- multipath-tools-111219.orig/libmultipath/config.h ++++ multipath-tools-111219/libmultipath/config.h +@@ -95,6 +95,7 @@ struct config { + unsigned int dev_loss; + int log_checker_err; + int allow_queueing; ++ int find_multipaths; + uid_t uid; + gid_t gid; + mode_t mode; |