blob: ddf022f7627c37613e7650f63fd21e8ac54a8f7e [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Benjamin Marzinski <bmarzins@redhat.com>
3Date: Fri, 17 Oct 2014 11:20:34 -0500
4Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A
5
6This patch adds another option to multipath, "-A", which reads
7/proc/cmdline for mpath.wwid=<WWID> options, and adds any wwids it finds
8to /etc/multipath/wwids. While this isn't usually important during
9normal operation, since these wwids should already be added, it can be
10helpful during installation, to make sure that multipath can claim
11devices as its own, before LVM or something else makes use of them. The
12patch also execs "/sbin/multipath -A" before running multipathd in
13multipathd.service
14
15Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
16---
17 libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++++++++++
18 libmultipath/wwids.h | 1 +
19 multipath/main.c | 10 ++++++++--
20 multipath/multipath.8 | 5 ++++-
21 multipathd/multipathd.service | 1 +
22 5 files changed, 58 insertions(+), 3 deletions(-)
23
24diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
25index 53e7951..39e08cd 100644
26--- a/libmultipath/wwids.c
27+++ b/libmultipath/wwids.c
28@@ -443,3 +443,47 @@ int op ## _wwid(const char *wwid) \
29 declare_failed_wwid_op(is_failed, false)
30 declare_failed_wwid_op(mark_failed, true)
31 declare_failed_wwid_op(unmark_failed, true)
32+
33+int remember_cmdline_wwid(void)
34+{
35+ FILE *f = NULL;
36+ char buf[LINE_MAX], *next, *ptr;
37+ int ret = 0;
38+
39+ f = fopen("/proc/cmdline", "re");
40+ if (!f) {
41+ condlog(0, "can't open /proc/cmdline : %s", strerror(errno));
42+ return -1;
43+ }
44+
45+ if (!fgets(buf, sizeof(buf), f)) {
46+ if (ferror(f))
47+ condlog(0, "read of /proc/cmdline failed : %s",
48+ strerror(errno));
49+ else
50+ condlog(0, "couldn't read /proc/cmdline");
51+ fclose(f);
52+ return -1;
53+ }
54+ fclose(f);
55+ next = buf;
56+ while((ptr = strstr(next, "mpath.wwid="))) {
57+ ptr += 11;
58+ next = strpbrk(ptr, " \t\n");
59+ if (next) {
60+ *next = '\0';
61+ next++;
62+ }
63+ if (strlen(ptr)) {
64+ if (remember_wwid(ptr) != 0)
65+ ret = -1;
66+ }
67+ else {
68+ condlog(0, "empty mpath.wwid kernel command line option");
69+ ret = -1;
70+ }
71+ if (!next)
72+ break;
73+ }
74+ return ret;
75+}
76diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h
77index 0c6ee54..e32a0b0 100644
78--- a/libmultipath/wwids.h
79+++ b/libmultipath/wwids.h
80@@ -17,6 +17,7 @@ int remember_wwid(char *wwid);
81 int check_wwids_file(char *wwid, int write_wwid);
82 int remove_wwid(char *wwid);
83 int replace_wwids(vector mp);
84+int remember_cmdline_wwid(void);
85
86 enum {
87 WWID_IS_NOT_FAILED = 0,
88diff --git a/multipath/main.c b/multipath/main.c
89index 6fdde03..7bac232 100644
90--- a/multipath/main.c
91+++ b/multipath/main.c
92@@ -109,7 +109,7 @@ usage (char * progname)
93 {
94 fprintf (stderr, VERSION_STRING);
95 fprintf (stderr, "Usage:\n");
96- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
97+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
98 fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname);
99 fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname);
100 fprintf (stderr, " %s -t\n", progname);
101@@ -123,6 +123,8 @@ usage (char * progname)
102 " -f flush a multipath device map\n"
103 " -F flush all multipath device maps\n"
104 " -a add a device wwid to the wwids file\n"
105+ " -A add devices from kernel command line mpath.wwids\n"
106+ " parameters to wwids file\n"
107 " -c check if a device should be a path in a multipath device\n"
108 " -C check if a multipath device has usable paths\n"
109 " -q allow queue_if_no_path when multipathd is not running\n"
110@@ -907,7 +909,7 @@ main (int argc, char *argv[])
111 exit(1);
112 multipath_conf = conf;
113 conf->retrigger_tries = 0;
114- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itquUwW")) != EOF ) {
115+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itquUwW")) != EOF ) {
116 switch(arg) {
117 case 1: printf("optarg : %s\n",optarg);
118 break;
119@@ -974,6 +976,10 @@ main (int argc, char *argv[])
120 case 't':
121 r = dump_config(conf);
122 goto out_free_config;
123+ case 'A':
124+ if (remember_cmdline_wwid() != 0)
125+ exit(1);
126+ exit(0);
127 case 'h':
128 usage(argv[0]);
129 exit(0);
130diff --git a/multipath/multipath.8 b/multipath/multipath.8
131index 914a8cb..8c6a4c1 100644
132--- a/multipath/multipath.8
133+++ b/multipath/multipath.8
134@@ -25,7 +25,7 @@ multipath \- Device mapper target autoconfig.
135 .RB [\| \-b\ \c
136 .IR bindings_file \|]
137 .RB [\| \-d \|]
138-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-u | \-U | \-w | \-W \|]
139+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-A | \-u | \-U | \-w | \-W \|]
140 .RB [\| \-p\ \c
141 .IR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
142 .RB [\| \-R\ \c
143@@ -135,6 +135,9 @@ Add the WWID for the specified device to the WWIDs file.
144 Check if the device specified in the program environment should be
145 a path in a multipath device.
146 .
147+.B \-A
148+add wwids from any kernel command line mpath.wwid parameters to the wwids file
149+.
150 .TP
151 .B \-U
152 Check if the device specified in the program environment is a multipath device
153diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
154index 17434ce..0fbcc46 100644
155--- a/multipathd/multipathd.service
156+++ b/multipathd/multipathd.service
157@@ -15,6 +15,7 @@ Type=notify
158 NotifyAccess=main
159 LimitCORE=infinity
160 ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath
161+ExecStartPre=-/sbin/multipath -A
162 ExecStart=/sbin/multipathd -d -s
163 ExecReload=/sbin/multipathd reconfigure
164 TasksMax=infinity
165--
1662.7.4
167