Allow fetching the pool from the device at mount
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 25 Jun 2013 22:43:09 +0000 (15:43 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 26 Jun 2013 22:20:09 +0000 (15:20 -0700)
To simplify integration with the xfstests test suite the
mount.zfs helper has been extended.  When passed a block
device (/dev/sdX) to mount, instead of a pool/dataset,
the pool name will be read from any existing zfs label
and used.  This allows you to mount the root dataset of
a zfs filesystem by specifing any of the member vdevs.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
cmd/mount_zfs/mount_zfs.c

index fd685fa..27a9014 100644 (file)
@@ -211,17 +211,55 @@ out:
 }
 
 /*
- * If a file or directory in your current working directory is named
- * 'dataset' then mount(8) will prepend your current working directory
- * to dataset.  The is no way to prevent this behavior so we simply
- * check for it and strip the prepended patch when it is added.
+ * Return the pool/dataset to mount given the name passed to mount.  This
+ * is expected to be of the form pool/dataset, however may also refer to
+ * a block device if that device contains a valid zfs label.
  */
 static char *
 parse_dataset(char *dataset)
 {
        char cwd[PATH_MAX];
+       struct stat64 statbuf;
+       int error;
        int len;
 
+       /*
+        * We expect a pool/dataset to be provided, however if we're
+        * given a device which is a member of a zpool we attempt to
+        * extract the pool name stored in the label.  Given the pool
+        * name we can mount the root dataset.
+        */
+       error = stat64(dataset, &statbuf);
+       if (error == 0) {
+               nvlist_t *config;
+               char *name;
+               int fd;
+
+               fd = open(dataset, O_RDONLY);
+               if (fd < 0)
+                       goto out;
+
+               error = zpool_read_label(fd, &config);
+               (void) close(fd);
+               if (error)
+                       goto out;
+
+               error = nvlist_lookup_string(config,
+                   ZPOOL_CONFIG_POOL_NAME, &name);
+               if (error == 0)
+                       dataset = strdup(name);
+
+               nvlist_free(config);
+               return (dataset);
+       }
+out:
+       /*
+        * If a file or directory in your current working directory is
+        * named 'dataset' then mount(8) will prepend your current working
+        * directory to the dataset.  There is no way to prevent this
+        * behavior so we simply check for it and strip the prepended
+        * patch when it is added.
+        */
        if (getcwd(cwd, PATH_MAX) == NULL)
                return (dataset);