Add 'no_partitions' feature
authorHannes Reinecke <hare@suse.de>
Wed, 23 Jul 2008 12:15:12 +0000 (14:15 +0200)
committerHannes Reinecke <hare@suse.de>
Tue, 3 May 2011 07:53:44 +0000 (09:53 +0200)
The 'no_partitions' feature serves as a trigger for kpartx for not
creating any partitions on that device. This is required if eg
the device is used as a system disk for VM guests.

Signed-off-by: Hannes Reinecke <hare@suse.de>
kpartx/devmapper.c
kpartx/devmapper.h
kpartx/kpartx.c
multipath/multipath.conf.5

index cb7e8a7..4adb8ee 100644 (file)
@@ -12,6 +12,7 @@
 
 #define UUID_PREFIX "part%d-"
 #define MAX_PREFIX_LEN 8
+#define PARAMS_SIZE 1024
 
 #ifndef LIBDM_API_COOKIE
 static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
@@ -278,3 +279,62 @@ out:
        return r;
 }
 
+int
+dm_get_map(int major, int minor, char * outparams)
+{
+       int r = 1;
+       struct dm_task *dmt;
+       void *next = NULL;
+       uint64_t start, length;
+       char *target_type = NULL;
+       char *params = NULL;
+
+       if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
+               return 1;
+
+       dm_task_set_major(dmt, major);
+       dm_task_set_minor(dmt, minor);
+       dm_task_no_open_count(dmt);
+
+       if (!dm_task_run(dmt))
+               goto out;
+
+       /* Fetch 1st target */
+       next = dm_get_next_target(dmt, next, &start, &length,
+                                 &target_type, &params);
+
+       if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
+               r = 0;
+out:
+       dm_task_destroy(dmt);
+       return r;
+}
+
+#define FEATURE_NO_PART "no_partitions"
+
+int
+dm_no_partitions(int major, int minor)
+{
+       char params[PARAMS_SIZE], *ptr;
+       int i, num_features;
+
+       if (dm_get_map(major, minor, params))
+               return 0;
+
+       ptr = params;
+       num_features = strtoul(params, &ptr, 10);
+       if ((ptr == params) || num_features == 0) {
+               /* No features found, return success */
+               return 0;
+       }
+       for (i = 0; (i < num_features); i++) {
+               if (!ptr || ptr > params + strlen(params))
+                       break;
+               /* Skip whitespaces */
+               while(ptr && *ptr == ' ') ptr++;
+               if (!strncmp(ptr, FEATURE_NO_PART, strlen(FEATURE_NO_PART)))
+                       return 1;
+               ptr = strchr(ptr, ' ');
+       }
+       return 0;
+}
index 6226129..8e350a0 100644 (file)
@@ -11,3 +11,4 @@ char * dm_mapname(int major, int minor);
 dev_t dm_get_first_dep(char *devname);
 char * dm_mapuuid(int major, int minor);
 int dm_devn (char * mapname, int *major, int *minor);
+int dm_no_partitions(int major, int minor);
index b70c463..5007ce2 100644 (file)
@@ -336,6 +336,11 @@ main(int argc, char **argv){
 
        if (!mapname)
                mapname = device + off;
+       else if (dm_no_partitions((unsigned int)MAJOR(buf.st_rdev),
+                                 (unsigned int)MINOR(buf.st_rdev))) {
+               /* Feature 'no_partitions' is set, return */
+               return 0;
+       }
 
        fd = open(device, O_RDONLY);
 
index 27e1b53..8edaccd 100644 (file)
@@ -167,13 +167,24 @@ Default value is \fBnone\fR.
 .RE
 .TP
 .B features
-Specify any device-mapper features to be used. The most common of
-these features is
-.I "1 queue_if_no_path" 
-Note that this can also be set via the
+Specify any device-mapper features to be used. Syntax is
+.I num list
+where
+.I num
+is the number of features in
+.I list.
+Possible values for the feature list are
+.RS
+.TP 12
+.B queue_if_no_path
+Queue IO if no path is active; identical to the
 .I no_path_retry
 keyword.
 .TP
+.B no_partitions
+Disable automatic partitions generation via kpartx.
+.RE
+.TP
 .B path_checker
 The default method used to determine the paths' state. Possible values
 are