Blob Blame History Raw
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Fri, 17 Oct 2014 11:20:34 -0500
Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A

This patch adds another option to multipath, "-A", which reads
/proc/cmdline for mpath.wwid=<WWID> options, and adds any wwids it finds
to /etc/multipath/wwids.  While this isn't usually important during
normal operation, since these wwids should already be added, it can be
helpful during installation, to make sure that multipath can claim
devices as its own, before LVM or something else makes use of them.  The
patch also execs "/sbin/multipath -A" before running multipathd in
multipathd.service

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
 multipath/main.c                 | 54 ++++++++++++++++++++++++++++++--
 multipath/multipath.8.in         |  7 ++++-
 multipathd/multipathd.service.in |  1 +
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/multipath/main.c b/multipath/main.c
index 46944589..47f89a0a 100644
--- a/multipath/main.c
+++ b/multipath/main.c
@@ -120,7 +120,7 @@ usage (char * progname)
 	fprintf (stderr, "  %s [-v level] [-R retries] -F\n", progname);
 	fprintf (stderr, "  %s [-v level] [-l|-ll] [device]\n", progname);
 	fprintf (stderr, "  %s [-v level] [-a|-w] device\n", progname);
-	fprintf (stderr, "  %s [-v level] -W\n", progname);
+	fprintf (stderr, "  %s [-v level] [-A|-W]\n", progname);
 	fprintf (stderr, "  %s [-v level] [-i] [-c|-C] device\n", progname);
 	fprintf (stderr, "  %s [-v level] [-i] [-u|-U]\n", progname);
 	fprintf (stderr, "  %s [-h|-t|-T]\n", progname);
@@ -134,6 +134,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"
 		"  -C      check if a multipath device has usable paths\n"
 		"  -q      allow queue_if_no_path when multipathd is not running\n"
@@ -448,6 +450,50 @@ static void cleanup_vecs(void)
 	free_pathvec(vecs.pathvec, FREE_PATHS);
 }
 
+static 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;
+}
+
 static int
 configure (struct config *conf, enum mpath_cmds cmd,
 	   enum devtypes dev_type, char *devpath)
@@ -848,7 +894,7 @@ main (int argc, char *argv[])
 		condlog(1, "failed to register cleanup handler for vecs: %m");
 	if (atexit(cleanup_bindings))
 		condlog(1, "failed to register cleanup handler for bindings: %m");
-	while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
+	while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
 		switch(arg) {
 		case 'v':
 			if (!isdigit(optarg[0])) {
@@ -919,6 +965,10 @@ main (int argc, char *argv[])
 		case 'T':
 			cmd = CMD_DUMP_CONFIG;
 			break;
+		case 'A':
+			if (remember_cmdline_wwid() != 0)
+				exit(RTVL_FAIL);
+			exit(RTVL_OK);
 		case 'h':
 			usage(argv[0]);
 			exit(RTVL_OK);
diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in
index 348eb220..82a7e68e 100644
--- a/multipath/multipath.8.in
+++ b/multipath/multipath.8.in
@@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig.
 .B multipath
 .RB [\| \-v\ \c
 .IR level \|]
-.B -W
+.RB [\| \-A | \-W \|]
 .
 .LP
 .B multipath
@@ -146,6 +146,11 @@ device mapper, path checkers ...).
 Add the WWID for the specified device to the WWIDs file.
 .
 .TP
+.B \-A
+Add the WWIDs from any kernel command line \fImpath.wwid\fR parameters to the
+WWIDs file.
+.
+.TP
 .B \-w
 Remove the WWID for the specified device from the WWIDs file.
 .
diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in
index 0965d6f9..c964eb1b 100644
--- a/multipathd/multipathd.service.in
+++ b/multipathd/multipathd.service.in
@@ -17,6 +17,7 @@ ConditionVirtualization=!container
 [Service]
 Type=notify
 NotifyAccess=main
+ExecStartPre=-/sbin/multipath -A
 ExecStart=/sbin/multipathd -d -s
 ExecReload=/sbin/multipathd reconfigure
 TasksMax=infinity