blob: dc291b812879dbd25fcb1da78d3e9527b06831a4 [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001From 15179c830521d8f37f9254ebc6bbf150a409f956 Mon Sep 17 00:00:00 2001
2From: Benjamin Marzinski <bmarzins@redhat.com>
3Date: Fri, 17 Oct 2014 11:20:34 -0500
4Subject: [PATCH 06/14] 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 bc70a27..88bb72b 100644
26--- a/libmultipath/wwids.c
27+++ b/libmultipath/wwids.c
28@@ -321,3 +321,47 @@ remember_wwid(char *wwid)
29 condlog(4, "wwid %s already in wwids file", wwid);
30 return 0;
31 }
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 9527012..b665232 100644
78--- a/libmultipath/wwids.h
79+++ b/libmultipath/wwids.h
80@@ -17,5 +17,6 @@ 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 #endif /* _WWIDS_H */
87diff --git a/multipath/main.c b/multipath/main.c
88index 4174d43..72585b0 100644
89--- a/multipath/main.c
90+++ b/multipath/main.c
91@@ -102,7 +102,7 @@ usage (char * progname)
92 {
93 fprintf (stderr, VERSION_STRING);
94 fprintf (stderr, "Usage:\n");
95- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
96+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
97 fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname);
98 fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname);
99 fprintf (stderr, " %s -t\n", progname);
100@@ -116,6 +116,8 @@ usage (char * progname)
101 " -f flush a multipath device map\n"
102 " -F flush all multipath device maps\n"
103 " -a add a device wwid to the wwids file\n"
104+ " -A add devices from kernel command line mpath.wwids\n"
105+ " parameters to wwids file\n"
106 " -c check if a device should be a path in a multipath device\n"
107 " -q allow queue_if_no_path when multipathd is not running\n"
108 " -d dry run, do not create or update devmaps\n"
109@@ -522,7 +524,7 @@ main (int argc, char *argv[])
110 exit(1);
111 multipath_conf = conf;
112 conf->retrigger_tries = 0;
113- while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrR:itquwW")) != EOF ) {
114+ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrR:itquwW")) != EOF ) {
115 switch(arg) {
116 case 1: printf("optarg : %s\n",optarg);
117 break;
118@@ -586,6 +588,10 @@ main (int argc, char *argv[])
119 case 't':
120 r = dump_config(conf);
121 goto out_free_config;
122+ case 'A':
123+ if (remember_cmdline_wwid() != 0)
124+ exit(1);
125+ exit(0);
126 case 'h':
127 usage(argv[0]);
128 exit(0);
129diff --git a/multipath/multipath.8 b/multipath/multipath.8
130index b9436e5..b9ad6b1 100644
131--- a/multipath/multipath.8
132+++ b/multipath/multipath.8
133@@ -25,7 +25,7 @@ multipath \- Device mapper target autoconfig.
134 .RB [\| \-b\ \c
135 .IR bindings_file \|]
136 .RB [\| \-d \|]
137-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \|-i | \-a | \|-u | \-w | \-W \|]
138+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \|-i | \-a | \-A | \-u | \-w | \-W \|]
139 .RB [\| \-p\ \c
140 .IR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
141 .RB [\| \-R\ \c
142@@ -122,6 +122,9 @@ Add the WWID for the specified device to the WWIDs file.
143 Check if the device specified in the program environment should be
144 a path in a multipath device.
145 .
146+.B \-A
147+add wwids from any kernel command line mpath.wwid parameters to the wwids file
148+.
149 .TP
150 .B \-w
151 Remove the WWID for the specified device from the WWIDs file.
152diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
153index fafd088..a623a3f 100644
154--- a/multipathd/multipathd.service
155+++ b/multipathd/multipathd.service
156@@ -15,6 +15,7 @@ Type=notify
157 NotifyAccess=main
158 LimitCORE=infinity
159 ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath
160+ExecStartPre=-/sbin/multipath -A
161 ExecStart=/sbin/multipathd -d -s
162 ExecReload=/sbin/multipathd reconfigure
163
164--
1652.8.1
166