Blame SOURCES/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch

68b27c
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
68b27c
From: Benjamin Marzinski <bmarzins@redhat.com>
68b27c
Date: Fri, 17 Oct 2014 11:20:34 -0500
68b27c
Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A
68b27c
68b27c
This patch adds another option to multipath, "-A", which reads
68b27c
/proc/cmdline for mpath.wwid=<WWID> options, and adds any wwids it finds
68b27c
to /etc/multipath/wwids.  While this isn't usually important during
68b27c
normal operation, since these wwids should already be added, it can be
68b27c
helpful during installation, to make sure that multipath can claim
68b27c
devices as its own, before LVM or something else makes use of them.  The
68b27c
patch also execs "/sbin/multipath -A" before running multipathd in
68b27c
multipathd.service
68b27c
68b27c
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
68b27c
---
68b27c
 multipath/main.c              | 54 +++++++++++++++++++++++++++++++++--
68b27c
 multipath/multipath.8         |  7 ++++-
68b27c
 multipathd/multipathd.service |  1 +
68b27c
 3 files changed, 59 insertions(+), 3 deletions(-)
68b27c
68b27c
diff --git a/multipath/main.c b/multipath/main.c
68b27c
index ef89c7cf..f618550d 100644
68b27c
--- a/multipath/main.c
68b27c
+++ b/multipath/main.c
68b27c
@@ -122,7 +122,7 @@ usage (char * progname)
68b27c
 	fprintf (stderr, "  %s [-v level] [-R retries] -F\n", progname);
68b27c
 	fprintf (stderr, "  %s [-v level] [-l|-ll] [device]\n", progname);
68b27c
 	fprintf (stderr, "  %s [-v level] [-a|-w] device\n", progname);
68b27c
-	fprintf (stderr, "  %s [-v level] -W\n", progname);
68b27c
+	fprintf (stderr, "  %s [-v level] [-A|-W]\n", progname);
68b27c
 	fprintf (stderr, "  %s [-v level] [-i] [-c|-C] device\n", progname);
68b27c
 	fprintf (stderr, "  %s [-v level] [-i] [-u|-U]\n", progname);
68b27c
 	fprintf (stderr, "  %s [-h|-t|-T]\n", progname);
68b27c
@@ -136,6 +136,8 @@ usage (char * progname)
68b27c
 		"  -f      flush a multipath device map\n"
68b27c
 		"  -F      flush all multipath device maps\n"
68b27c
 		"  -a      add a device wwid to the wwids file\n"
68b27c
+		"  -A      add devices from kernel command line mpath.wwids\n"
68b27c
+		"          parameters to wwids file\n"
68b27c
 		"  -c      check if a device should be a path in a multipath device\n"
68b27c
 		"  -C      check if a multipath device has usable paths\n"
68b27c
 		"  -q      allow queue_if_no_path when multipathd is not running\n"
68b27c
@@ -450,6 +452,50 @@ static void cleanup_vecs(void)
68b27c
 	free_pathvec(vecs.pathvec, FREE_PATHS);
68b27c
 }
68b27c
 
68b27c
+static int remember_cmdline_wwid(void)
68b27c
+{
68b27c
+	FILE *f = NULL;
68b27c
+	char buf[LINE_MAX], *next, *ptr;
68b27c
+	int ret = 0;
68b27c
+
68b27c
+	f = fopen("/proc/cmdline", "re");
68b27c
+	if (!f) {
68b27c
+		condlog(0, "can't open /proc/cmdline : %s", strerror(errno));
68b27c
+		return -1;
68b27c
+	}
68b27c
+
68b27c
+	if (!fgets(buf, sizeof(buf), f)) {
68b27c
+		if (ferror(f))
68b27c
+			condlog(0, "read of /proc/cmdline failed : %s",
68b27c
+				strerror(errno));
68b27c
+		else
68b27c
+			condlog(0, "couldn't read /proc/cmdline");
68b27c
+		fclose(f);
68b27c
+		return -1;
68b27c
+	}
68b27c
+	fclose(f);
68b27c
+	next = buf;
68b27c
+	while((ptr = strstr(next, "mpath.wwid="))) {
68b27c
+		ptr += 11;
68b27c
+		next = strpbrk(ptr, " \t\n");
68b27c
+		if (next) {
68b27c
+			*next = '\0';
68b27c
+			next++;
68b27c
+		}
68b27c
+		if (strlen(ptr)) {
68b27c
+			if (remember_wwid(ptr) != 0)
68b27c
+				ret = -1;
68b27c
+		}
68b27c
+		else {
68b27c
+			condlog(0, "empty mpath.wwid kernel command line option");
68b27c
+			ret = -1;
68b27c
+		}
68b27c
+		if (!next)
68b27c
+			break;
68b27c
+	}
68b27c
+	return ret;
68b27c
+}
68b27c
+
68b27c
 static int
68b27c
 configure (struct config *conf, enum mpath_cmds cmd,
68b27c
 	   enum devtypes dev_type, char *devpath)
68b27c
@@ -823,7 +869,7 @@ main (int argc, char *argv[])
68b27c
 	conf = get_multipath_config();
68b27c
 	conf->retrigger_tries = 0;
68b27c
 	conf->force_sync = 1;
68b27c
-	while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
68b27c
+	while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
68b27c
 		switch(arg) {
68b27c
 		case 1: printf("optarg : %s\n",optarg);
68b27c
 			break;
68b27c
@@ -900,6 +946,10 @@ main (int argc, char *argv[])
68b27c
 		case 'T':
68b27c
 			cmd = CMD_DUMP_CONFIG;
68b27c
 			break;
68b27c
+		case 'A':
68b27c
+			if (remember_cmdline_wwid() != 0)
68b27c
+				exit(RTVL_FAIL);
68b27c
+			exit(RTVL_OK);
68b27c
 		case 'h':
68b27c
 			usage(argv[0]);
68b27c
 			exit(RTVL_OK);
68b27c
diff --git a/multipath/multipath.8 b/multipath/multipath.8
68b27c
index 5b29a5d9..0478f4e7 100644
68b27c
--- a/multipath/multipath.8
68b27c
+++ b/multipath/multipath.8
68b27c
@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig.
68b27c
 .B multipath
68b27c
 .RB [\| \-v\ \c
68b27c
 .IR level \|]
68b27c
-.B -W
68b27c
+.RB [\| \-A | \-W \|]
68b27c
 .
68b27c
 .LP
68b27c
 .B multipath
68b27c
@@ -145,6 +145,11 @@ device mapper, path checkers ...).
68b27c
 Add the WWID for the specified device to the WWIDs file.
68b27c
 .
68b27c
 .TP
68b27c
+.B \-A
68b27c
+Add the WWIDs from any kernel command line \fImpath.wwid\fR parameters to the
68b27c
+WWIDs file.
68b27c
+.
68b27c
+.TP
68b27c
 .B \-w
68b27c
 Remove the WWID for the specified device from the WWIDs file.
68b27c
 .
68b27c
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
68b27c
index af592057..bc8fa07a 100644
68b27c
--- a/multipathd/multipathd.service
68b27c
+++ b/multipathd/multipathd.service
68b27c
@@ -15,6 +15,7 @@ Type=notify
68b27c
 NotifyAccess=main
68b27c
 LimitCORE=infinity
68b27c
 ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath
68b27c
+ExecStartPre=-/sbin/multipath -A
68b27c
 ExecStart=/sbin/multipathd -d -s
68b27c
 ExecReload=/sbin/multipathd reconfigure
68b27c
 TasksMax=infinity