ecd2a9
---
ecd2a9
 libmultipath/config.c    |    4 ++++
ecd2a9
 libmultipath/config.h    |    1 +
ecd2a9
 libmultipath/configure.c |    5 ++---
ecd2a9
 libmultipath/dict.c      |   33 +++++++++++++++++++++++++++++++++
ecd2a9
 libmultipath/util.c      |   30 ++++++++++++++++++++++++++++++
ecd2a9
 libmultipath/util.h      |    1 +
ecd2a9
 libmultipath/wwids.c     |   21 ++++++++++++++-------
ecd2a9
 multipathd/main.c        |    3 +--
ecd2a9
 8 files changed, 86 insertions(+), 12 deletions(-)
ecd2a9
ecd2a9
Index: multipath-tools-130222/libmultipath/config.h
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/libmultipath/config.h
ecd2a9
+++ multipath-tools-130222/libmultipath/config.h
ecd2a9
@@ -131,6 +131,7 @@ struct config {
ecd2a9
 	int detect_prio;
ecd2a9
 	int force_sync;
ecd2a9
 	int deferred_remove;
ecd2a9
+	int ignore_new_boot_devs;
ecd2a9
 	unsigned int version[3];
ecd2a9
 
ecd2a9
 	char * dev;
ecd2a9
Index: multipath-tools-130222/libmultipath/configure.c
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/libmultipath/configure.c
ecd2a9
+++ multipath-tools-130222/libmultipath/configure.c
ecd2a9
@@ -775,9 +775,8 @@ coalesce_paths (struct vectors * vecs, v
ecd2a9
 		if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
ecd2a9
 			continue;
ecd2a9
 
ecd2a9
-		/* If find_multipaths was selected check if the path is valid */
ecd2a9
-		if (conf->find_multipaths && !refwwid &&
ecd2a9
-		    !should_multipath(pp1, pathvec)) {
ecd2a9
+		/* check if the path is valid */
ecd2a9
+		if (!refwwid && !should_multipath(pp1, pathvec)) {
ecd2a9
 			orphan_path(pp1);
ecd2a9
 			continue;
ecd2a9
 		}
ecd2a9
Index: multipath-tools-130222/libmultipath/wwids.c
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/libmultipath/wwids.c
ecd2a9
+++ multipath-tools-130222/libmultipath/wwids.c
ecd2a9
@@ -15,6 +15,7 @@
ecd2a9
 #include "wwids.h"
ecd2a9
 #include "defaults.h"
ecd2a9
 #include "config.h"
ecd2a9
+#include "util.h"
ecd2a9
 
ecd2a9
 /*
ecd2a9
  * Copyright (c) 2010 Benjamin Marzinski, Redhat
ecd2a9
@@ -268,15 +269,21 @@ should_multipath(struct path *pp1, vecto
ecd2a9
 {
ecd2a9
 	int i;
ecd2a9
 	struct path *pp2;
ecd2a9
+	int ignore_new_devs = (conf->ignore_new_boot_devs && in_initrd());
ecd2a9
+
ecd2a9
+	if (!conf->find_multipaths && !ignore_new_devs)
ecd2a9
+		return 1;
ecd2a9
 
ecd2a9
 	condlog(4, "checking if %s should be multipathed", pp1->dev);
ecd2a9
-	vector_foreach_slot(pathvec, pp2, i) {
ecd2a9
-		if (pp1->dev == pp2->dev)
ecd2a9
-			continue;
ecd2a9
-		if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
ecd2a9
-			condlog(3, "found multiple paths with wwid %s, "
ecd2a9
-				"multipathing %s", pp1->wwid, pp1->dev);
ecd2a9
-			return 1;
ecd2a9
+	if (!ignore_new_devs) {
ecd2a9
+		vector_foreach_slot(pathvec, pp2, i) {
ecd2a9
+			if (pp1->dev == pp2->dev)
ecd2a9
+				continue;
ecd2a9
+			if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
ecd2a9
+				condlog(3, "found multiple paths with wwid %s, "
ecd2a9
+					"multipathing %s", pp1->wwid, pp1->dev);
ecd2a9
+				return 1;
ecd2a9
+			}
ecd2a9
 		}
ecd2a9
 	}
ecd2a9
 	if (check_wwids_file(pp1->wwid, 0) < 0) {
ecd2a9
Index: multipath-tools-130222/multipathd/main.c
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/multipathd/main.c
ecd2a9
+++ multipath-tools-130222/multipathd/main.c
ecd2a9
@@ -503,8 +503,7 @@ rescan:
ecd2a9
 			return 1;
ecd2a9
 		}
ecd2a9
 
ecd2a9
-		if (conf->find_multipaths &&
ecd2a9
-		    !should_multipath(pp, vecs->pathvec)) {
ecd2a9
+		if (!should_multipath(pp, vecs->pathvec)) {
ecd2a9
 			orphan_path(pp);
ecd2a9
 			return 0;
ecd2a9
 		}
ecd2a9
Index: multipath-tools-130222/libmultipath/config.c
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/libmultipath/config.c
ecd2a9
+++ multipath-tools-130222/libmultipath/config.c
ecd2a9
@@ -622,6 +622,7 @@ load_config (char * file, struct udev *u
ecd2a9
 	conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
ecd2a9
 	conf->hw_strmatch = 0;
ecd2a9
 	conf->force_sync = 0;
ecd2a9
+	conf->ignore_new_boot_devs = 0;
ecd2a9
 
ecd2a9
 	/*
ecd2a9
 	 * preload default hwtable
ecd2a9
@@ -732,6 +733,9 @@ load_config (char * file, struct udev *u
ecd2a9
 	    !conf->wwids_file)
ecd2a9
 		goto out;
ecd2a9
 
ecd2a9
+	if (conf->ignore_new_boot_devs)
ecd2a9
+		in_initrd();
ecd2a9
+
ecd2a9
 	return 0;
ecd2a9
 out:
ecd2a9
 	free_config(conf);
ecd2a9
Index: multipath-tools-130222/libmultipath/dict.c
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/libmultipath/dict.c
ecd2a9
+++ multipath-tools-130222/libmultipath/dict.c
ecd2a9
@@ -761,6 +761,29 @@ def_deferred_remove_handler(vector strve
ecd2a9
 	return 0;
ecd2a9
 }
ecd2a9
 
ecd2a9
+static int
ecd2a9
+def_ignore_new_boot_devs_handler(vector strvec)
ecd2a9
+{
ecd2a9
+	char * buff;
ecd2a9
+
ecd2a9
+	buff = set_value(strvec);
ecd2a9
+
ecd2a9
+	if (!buff)
ecd2a9
+		return 1;
ecd2a9
+
ecd2a9
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
ecd2a9
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
ecd2a9
+		conf->ignore_new_boot_devs = 0;
ecd2a9
+	else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
ecd2a9
+		 (strlen(buff) == 1 && !strcmp(buff, "1")))
ecd2a9
+		conf->ignore_new_boot_devs = 1;
ecd2a9
+	else
ecd2a9
+		conf->ignore_new_boot_devs = 0;
ecd2a9
+
ecd2a9
+	FREE(buff);
ecd2a9
+	return 0;
ecd2a9
+}
ecd2a9
+
ecd2a9
 /*
ecd2a9
  * blacklist block handlers
ecd2a9
  */
ecd2a9
@@ -3011,6 +3034,15 @@ snprint_def_deferred_remove(char * buff,
ecd2a9
 }
ecd2a9
 
ecd2a9
 static int
ecd2a9
+snprint_def_ignore_new_boot_devs(char * buff, int len, void * data)
ecd2a9
+{
ecd2a9
+	if (conf->ignore_new_boot_devs == 1)
ecd2a9
+		return snprintf(buff, len, "yes");
ecd2a9
+	else
ecd2a9
+		return snprintf(buff, len, "no");
ecd2a9
+}
ecd2a9
+
ecd2a9
+static int
ecd2a9
 snprint_ble_simple (char * buff, int len, void * data)
ecd2a9
 {
ecd2a9
 	struct blentry * ble = (struct blentry *)data;
ecd2a9
@@ -3080,6 +3112,7 @@ init_keywords(void)
ecd2a9
 	install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
ecd2a9
 	install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
ecd2a9
 	install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
ecd2a9
+	install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
ecd2a9
 	__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
ecd2a9
 	__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
ecd2a9
 	__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
ecd2a9
Index: multipath-tools-130222/libmultipath/util.c
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/libmultipath/util.c
ecd2a9
+++ multipath-tools-130222/libmultipath/util.c
ecd2a9
@@ -3,6 +3,8 @@
ecd2a9
 #include <sys/types.h>
ecd2a9
 #include <sys/stat.h>
ecd2a9
 #include <unistd.h>
ecd2a9
+#include <sys/vfs.h>
ecd2a9
+#include <linux/magic.h>
ecd2a9
 
ecd2a9
 #include "debug.h"
ecd2a9
 #include "memory.h"
ecd2a9
@@ -267,3 +269,31 @@ dev_t parse_devt(const char *dev_t)
ecd2a9
 
ecd2a9
 	return makedev(maj, min);
ecd2a9
 }
ecd2a9
+
ecd2a9
+/* This define was taken from systemd. src/shared/macro.h */
ecd2a9
+#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
ecd2a9
+
ecd2a9
+/* This function was taken from systemd. src/shared/util.c */
ecd2a9
+int in_initrd(void) {
ecd2a9
+	static int saved = -1;
ecd2a9
+	struct statfs s;
ecd2a9
+
ecd2a9
+	if (saved >= 0)
ecd2a9
+		return saved;
ecd2a9
+
ecd2a9
+	/* We make two checks here:
ecd2a9
+	 *
ecd2a9
+	 * 1. the flag file /etc/initrd-release must exist
ecd2a9
+	 * 2. the root file system must be a memory file system
ecd2a9
+	 * The second check is extra paranoia, since misdetecting an
ecd2a9
+	 * initrd can have bad bad consequences due the initrd
ecd2a9
+	 * emptying when transititioning to the main systemd.
ecd2a9
+	 */
ecd2a9
+
ecd2a9
+	saved = access("/etc/initrd-release", F_OK) >= 0 &&
ecd2a9
+		statfs("/", &s) >= 0 &&
ecd2a9
+		(F_TYPE_EQUAL(s.f_type, TMPFS_MAGIC) ||
ecd2a9
+		 F_TYPE_EQUAL(s.f_type, RAMFS_MAGIC));
ecd2a9
+
ecd2a9
+	return saved;
ecd2a9
+}
ecd2a9
Index: multipath-tools-130222/libmultipath/util.h
ecd2a9
===================================================================
ecd2a9
--- multipath-tools-130222.orig/libmultipath/util.h
ecd2a9
+++ multipath-tools-130222/libmultipath/util.h
ecd2a9
@@ -11,6 +11,7 @@ void remove_trailing_chars(char *path, c
ecd2a9
 int devt2devname (char *, int, char *);
ecd2a9
 dev_t parse_devt(const char *dev_t);
ecd2a9
 char *convert_dev(char *dev, int is_path_device);
ecd2a9
+int in_initrd(void);
ecd2a9
 
ecd2a9
 #define safe_sprintf(var, format, args...)	\
ecd2a9
 	snprintf(var, sizeof(var), format, ##args) >= sizeof(var)