]> git.ipfire.org Git - people/pmueller/ipfire-3.x.git/blobdiff - multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch
multipath-tools: Update to snapshot from 2013-02-22
[people/pmueller/ipfire-3.x.git] / multipath-tools / patches / 0023-RH-multipath-wipe-wwid.patch
diff --git a/multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch b/multipath-tools/patches/0023-RH-multipath-wipe-wwid.patch
new file mode 100644 (file)
index 0000000..6de04bf
--- /dev/null
@@ -0,0 +1,239 @@
+---
+ libmultipath/discovery.c |    3 +
+ libmultipath/wwids.c     |   86 +++++++++++++++++++++++++++++++++++++++++++++++
+ libmultipath/wwids.h     |    1 
+ multipath/main.c         |   26 ++++++++++++--
+ multipath/multipath.8    |    5 ++
+ 5 files changed, 115 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -53,7 +53,8 @@ store_pathinfo (vector pathvec, vector h
+               goto out;
+       }
+       pp->udev = udev_device_ref(udevice);
+-      err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
++      err = pathinfo(pp, hwtable,
++                     (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST));
+       if (err)
+               goto out;
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -82,6 +82,92 @@ write_out_wwid(int fd, char *wwid) {
+ }
+ int
++do_remove_wwid(int fd, char *str) {
++      char buf[4097];
++      char *ptr;
++      off_t start = 0;
++      int bytes;
++
++      while (1) {
++              if (lseek(fd, start, SEEK_SET) < 0) {
++                      condlog(0, "wwid file read lseek failed : %s",
++                              strerror(errno));
++                      return -1;
++              }
++              bytes = read(fd, buf, 4096);
++              if (bytes < 0) {
++                      if (errno == EINTR || errno == EAGAIN)
++                              continue;
++                      condlog(0, "failed to read from wwids file : %s",
++                              strerror(errno));
++                      return -1;
++              }
++              if (!bytes) /* didn't find wwid to remove */
++                      return 1;
++              buf[bytes] = '\0';
++              ptr = strstr(buf, str);
++              if (ptr != NULL) {
++                      condlog(3, "found '%s'", str);
++                      if (lseek(fd, start + (ptr - buf), SEEK_SET) < 0) {
++                              condlog(0, "write lseek failed : %s",
++                                              strerror(errno));
++                              return -1;
++                      }
++                      while (1) {
++                              if (write(fd, "#", 1) < 0) {
++                                      if (errno == EINTR || errno == EAGAIN)
++                                              continue;
++                                      condlog(0, "failed to write to wwids file : %s", strerror(errno));
++                                      return -1;
++                              }
++                              return 0;
++                      }
++              }
++              ptr = strrchr(buf, '\n');
++              if (ptr == NULL) { /* shouldn't happen, assume it is EOF */
++                      condlog(4, "couldn't find newline, assuming end of file");
++                      return 1;
++              }
++              start = start + (ptr - buf) + 1;
++      }
++}
++
++
++int
++remove_wwid(char *wwid) {
++      int fd, len, can_write;
++      char *str;
++      int ret = -1;
++
++      len = strlen(wwid) + 4; /* two slashes the newline and a zero byte */
++      str = malloc(len);
++      if (str == NULL) {
++              condlog(0, "can't allocate memory to remove wwid : %s",
++                      strerror(errno));
++              return -1;
++      }
++      if (snprintf(str, len, "/%s/\n", wwid) >= len) {
++              condlog(0, "string overflow trying to remove wwid");
++              goto out;
++      }
++      condlog(3, "removing line '%s' from wwids file", str);
++      fd = open_file(conf->wwids_file, &can_write, WWIDS_FILE_HEADER);
++      if (fd < 0)
++              goto out;
++      if (!can_write) {
++              condlog(0, "cannot remove wwid. wwids file is read-only");
++              goto out_file;
++      }
++      ret = do_remove_wwid(fd, str);
++
++out_file:
++      close(fd);
++out:
++      free(str);
++      return ret;
++}
++
++int
+ check_wwids_file(char *wwid, int write_wwid)
+ {
+       int fd, can_write, found, ret;
+Index: multipath-tools-130222/libmultipath/wwids.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.h
++++ multipath-tools-130222/libmultipath/wwids.h
+@@ -15,5 +15,6 @@
+ int should_multipath(struct path *pp, vector pathvec);
+ int remember_wwid(char *wwid);
+ int check_wwids_file(char *wwid, int write_wwid);
++int remove_wwid(char *wwid);
+ #endif /* _WWIDS_H */
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -83,7 +83,7 @@ usage (char * progname)
+ {
+       fprintf (stderr, VERSION_STRING);
+       fprintf (stderr, "Usage:\n");
+-      fprintf (stderr, "  %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
++      fprintf (stderr, "  %s [-c|-w] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
+       fprintf (stderr, "  %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
+       fprintf (stderr, "  %s -F [-v lvl]\n", progname);
+       fprintf (stderr, "  %s -t\n", progname);
+@@ -104,6 +104,7 @@ usage (char * progname)
+               "  -B      treat the bindings file as read only\n" \
+               "  -p      policy failover|multibus|group_by_serial|group_by_prio\n" \
+               "  -b fil  bindings file location\n" \
++              "  -w      remove a device from the wwids file\n" \
+               "  -p pol  force all maps to specified path grouping policy :\n" \
+               "          . failover            one path per priority group\n" \
+               "          . multibus            all paths in one priority group\n" \
+@@ -212,7 +213,6 @@ get_dm_mpvec (vector curmp, vector pathv
+               if (!conf->dry_run)
+                       reinstate_paths(mpp);
+-              remember_wwid(mpp->wwid);
+       }
+       return 0;
+ }
+@@ -262,7 +262,7 @@ configure (void)
+       /*
+        * if we have a blacklisted device parameter, exit early
+        */
+-      if (dev && conf->dev_type == DEV_DEVNODE &&
++      if (dev && conf->dev_type == DEV_DEVNODE && conf->dry_run != 3 &&
+           (filter_devnode(conf->blist_devnode,
+                           conf->elist_devnode, dev) > 0)) {
+               if (conf->dry_run == 2)
+@@ -284,6 +284,17 @@ configure (void)
+                               condlog(3, "scope is nul");
+                       goto out;
+               }
++              if (conf->dry_run == 3) {
++                      r = remove_wwid(refwwid);
++                      if (r == 0)
++                              printf("wwid '%s' removed\n", refwwid);
++                      else if (r == 1) {
++                              printf("wwid '%s' not in wwids file\n",
++                                      refwwid);
++                              r = 0;
++                      }
++                      goto out;
++              }
+               condlog(3, "scope limited to %s", refwwid);
+               if (conf->dry_run == 2) {
+                       if (check_wwids_file(refwwid, 0) == 0){
+@@ -439,7 +450,7 @@ main (int argc, char *argv[])
+       if (dm_prereq())
+               exit(1);
+-      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) {
++      while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtqw")) != EOF ) {
+               switch(arg) {
+               case 1: printf("optarg : %s\n",optarg);
+                       break;
+@@ -504,6 +515,9 @@ main (int argc, char *argv[])
+               case 'h':
+                       usage(argv[0]);
+                       exit(0);
++              case 'w':
++                      conf->dry_run = 3;
++                      break;
+               case ':':
+                       fprintf(stderr, "Missing option argument\n");
+                       usage(argv[0]);
+@@ -555,6 +569,10 @@ main (int argc, char *argv[])
+               condlog(0, "the -c option requires a path to check");
+               goto out;
+       }
++      if (conf->dry_run == 3 && !conf->dev) {
++              condlog(0, "the -w option requires a device");
++              goto out;
++      }
+       if (conf->remove == FLUSH_ONE) {
+               if (conf->dev_type == DEV_DEVMAP) {
+                       r = dm_suspend_and_flush_map(conf->dev);
+Index: multipath-tools-130222/multipath/multipath.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.8
++++ multipath-tools-130222/multipath/multipath.8
+@@ -8,7 +8,7 @@ multipath \- Device mapper target autoco
+ .RB [\| \-b\ \c
+ .IR bindings_file \|]
+ .RB [\| \-d \|]
+-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r \|]
++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \-w \|]
+ .RB [\| \-p\ \c
+ .BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
+ .RB [\| device \|]
+@@ -68,6 +68,9 @@ check if a block device should be a path
+ .B \-q
+ allow device tables with queue_if_no_path when multipathd is not running
+ .TP
++.B \-w
++remove the wwid for the specified device from the wwids file
++.TP
+ .BI \-p " policy"
+ force new maps to use the specified policy:
+ .RS 1.2i