| 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> |
| |
| Upstream-Status: Pending |
| |
| Update this patch to new version 0.8.0 |
| |
| Signed-off-by: Changqing Li <changqing.li@windriver.com> |
| --- |
| libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++++++++++ |
| libmultipath/wwids.h | 1 + |
| multipath/main.c | 9 ++++++++- |
| multipath/multipath.8 | 3 +++ |
| multipathd/multipathd.service | 1 + |
| 5 files changed, 57 insertions(+), 1 deletion(-) |
| |
| diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c |
| index 53e7951..9ba9b62 100644 |
| --- a/libmultipath/wwids.c |
| +++ b/libmultipath/wwids.c |
| @@ -443,3 +443,47 @@ int op ## _wwid(const char *wwid) \ |
| declare_failed_wwid_op(is_failed, false) |
| declare_failed_wwid_op(mark_failed, true) |
| declare_failed_wwid_op(unmark_failed, true) |
| + |
| +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; |
| +} |
| diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h |
| index 0c6ee54..e32a0b0 100644 |
| --- a/libmultipath/wwids.h |
| +++ b/libmultipath/wwids.h |
| @@ -17,6 +17,7 @@ int remember_wwid(char *wwid); |
| int check_wwids_file(char *wwid, int write_wwid); |
| int remove_wwid(char *wwid); |
| int replace_wwids(vector mp); |
| +int remember_cmdline_wwid(void); |
| |
| enum { |
| WWID_IS_NOT_FAILED = 0, |
| diff --git a/multipath/main.c b/multipath/main.c |
| index 5abb118..c751b31 100644 |
| --- a/multipath/main.c |
| +++ b/multipath/main.c |
| @@ -134,6 +134,7 @@ usage (char * progname) |
| fprintf (stderr, VERSION_STRING); |
| fprintf (stderr, "Usage:\n"); |
| fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); |
| + fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); |
| fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname); |
| fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname); |
| fprintf (stderr, " %s [-t|-T]\n", progname); |
| @@ -147,6 +148,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" |
| @@ -870,7 +873,7 @@ main (int argc, char *argv[]) |
| exit(RTVL_FAIL); |
| multipath_conf = conf; |
| conf->retrigger_tries = 0; |
| - while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { |
| + while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { |
| switch(arg) { |
| case 1: printf("optarg : %s\n",optarg); |
| break; |
| @@ -937,6 +940,10 @@ main (int argc, char *argv[]) |
| case 't': |
| r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK; |
| goto out_free_config; |
| + case 'A': |
| + if (remember_cmdline_wwid() != 0) |
| + exit(1); |
| + exit(0); |
| case 'T': |
| cmd = CMD_DUMP_CONFIG; |
| break; |
| diff --git a/multipath/multipath.8 b/multipath/multipath.8 |
| index 9cdd05a..1e120f3 100644 |
| --- a/multipath/multipath.8 |
| +++ b/multipath/multipath.8 |
| @@ -167,6 +167,9 @@ itself doesn't attempt to do I/O on the device. |
| Check if the device specified in the program environment should be |
| a path in a multipath device. |
| . |
| +.B \-A |
| +add wwids from any kernel command line mpath.wwid parameters to the wwids file |
| +. |
| .TP |
| .B \-U |
| Check if the device specified in the program environment is a multipath device |
| diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service |
| index 17434ce..0fbcc46 100644 |
| --- a/multipathd/multipathd.service |
| +++ b/multipathd/multipathd.service |
| @@ -15,6 +15,7 @@ Type=notify |
| NotifyAccess=main |
| LimitCORE=infinity |
| ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath |
| +ExecStartPre=-/sbin/multipath -A |
| ExecStart=/sbin/multipathd -d -s |
| ExecReload=/sbin/multipathd reconfigure |
| TasksMax=infinity |
| -- |
| 2.7.4 |
| |