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

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