multipath: better argument type checking
authorBenjamin Marzinski <bmarzins@redhat.com>
Tue, 11 Oct 2011 03:18:09 +0000 (22:18 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Tue, 11 Oct 2011 04:52:38 +0000 (06:52 +0200)
The way that multipath decided what you passed in as an argument didn't
always work.  If the argument was the name of a file, then multipath
assumed that it was a path.  That meant if you were in /dev/mapper and ran

# multipath -f <mpath_device_name>

It would fail, since it thought you gave it a path name, instead of a
multipath device name.  Now multipath will only treat the argument
as a path name if it is a block device with a different major number than
device-mapper's.  Also, I've switched the MAJOR/MINOR/MKDEV macros to
work like kpartx, so that they can handle minor numbers over 255.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
multipath/dev_t.h
multipath/main.c

index 90c64f3..aa80d5e 100644 (file)
@@ -1,15 +1,3 @@
-#define MINORBITS       20
-#define MINORMASK       ((1U << MINORBITS) - 1)
-
-#define MAJOR(dev)      ((unsigned int) ((dev) >> MINORBITS))
-#define MINOR(dev)      ((unsigned int) ((dev) & MINORMASK))
-#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))
-
-#define print_dev_t(buffer, dev)                                        \
-       sprintf((buffer), "%u:%u\n", MAJOR(dev), MINOR(dev))
-
-#define format_dev_t(buffer, dev)                                       \
-       ({                                                              \
-               sprintf(buffer, "%u:%u", MAJOR(dev), MINOR(dev));       \
-               buffer;                                                 \
-       })
+#define MAJOR(dev)      ((dev & 0xfff00) >> 8)
+#define MINOR(dev)      ((dev & 0xff) | ((dev >> 12) & 0xfff00))
+#define MKDEV(ma,mi)    ((mi & 0xff) | (ma << 8) | ((mi & ~0xff) << 12))
index 9c45b8b..2078fe3 100644 (file)
@@ -22,6 +22,8 @@
  * Copyright (c) 2005 Edward Goggin, EMC
  */
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <ctype.h>
@@ -51,6 +53,7 @@
 #include <errno.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include "dev_t.h"
 
 int logsink;
 
@@ -374,13 +377,29 @@ dump_config (void)
        return 0;
 }
 
+static int
+get_dev_type(char *dev) {
+       struct stat buf;
+       int i;
+
+       if (stat(dev, &buf) == 0 && S_ISBLK(buf.st_mode)) {
+               if (dm_is_dm_major(MAJOR(buf.st_rdev)))
+                       return DEV_DEVMAP;
+               return DEV_DEVNODE;
+       }
+       else if (sscanf(dev, "%d:%d", &i, &i) == 2)
+               return DEV_DEVT;
+       else
+               return DEV_DEVMAP;
+}
+
 int
 main (int argc, char *argv[])
 {
        int arg;
        extern char *optarg;
        extern int optind;
-       int i, r = 1;
+       int r = 1;
 
        if (getuid() != 0) {
                fprintf(stderr, "need to be root\n");
@@ -478,14 +497,7 @@ main (int argc, char *argv[])
                        goto out;
 
                strncpy(conf->dev, argv[optind], FILE_NAME_SIZE);
-
-               if (filepresent(conf->dev))
-                       conf->dev_type = DEV_DEVNODE;
-               else if (sscanf(conf->dev, "%d:%d", &i, &i) == 2)
-                       conf->dev_type = DEV_DEVT;
-               else
-                       conf->dev_type = DEV_DEVMAP;
-
+               conf->dev_type = get_dev_type(conf->dev);
        }
        conf->daemon = 0;