Print this page
5882 Temporary pool names
Reviewed by: Matt Ahrens <matt@delphix.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>

@@ -218,12 +218,13 @@
         case HELP_CLEAR:
                 return (gettext("\tclear [-nF] <pool> [device]\n"));
         case HELP_CREATE:
                 return (gettext("\tcreate [-fnd] [-B] "
                     "[-o property=value] ... \n"
-                    "\t    [-O file-system-property=value] ... \n"
-                    "\t    [-m mountpoint] [-R root] <pool> <vdev> ...\n"));
+                    "\t    [-O file-system-property=value] ...\n"
+                    "\t    [-m mountpoint] [-R root] [-t tempname] "
+                    "<pool> <vdev> ...\n"));
         case HELP_CHECKPOINT:
                 return (gettext("\tcheckpoint [--discard] <pool> ...\n"));
         case HELP_DESTROY:
                 return (gettext("\tdestroy [-f] <pool>\n"));
         case HELP_DETACH:

@@ -237,11 +238,11 @@
                     "\timport [-o mntopts] [-o property=value] ... \n"
                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
                     "[-R root] [-F [-n]] -a\n"
                     "\timport [-o mntopts] [-o property=value] ... \n"
                     "\t    [-d dir | -c cachefile] [-D] [-f] [-m] [-N] "
-                    "[-R root] [-F [-n]]\n"
+                    "[-R root] [-F [-n]] [-t]\n"
                     "\t    [--rewind-to-checkpoint] <pool | id> [newpool]\n"));
         case HELP_IOSTAT:
                 return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
                     "[count]]\n"));
         case HELP_LABELCLEAR:

@@ -490,10 +491,25 @@
 
         return (0);
 }
 
 /*
+ * Set a default property pair (name, string-value) in a property nvlist
+ */
+static int
+add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
+    boolean_t poolprop)
+{
+        char *pval;
+
+        if (nvlist_lookup_string(*props, propname, &pval) == 0)
+                return (0);
+
+        return (add_prop_list(propname, propval, props, poolprop));
+}
+
+/*
  * zpool add [-fn] <pool> <vdev> ...
  *
  *      -f      Force addition of devices, even if they appear in use
  *      -n      Do not add the devices, but display the resulting layout if
  *              they were to be added.

@@ -847,19 +863,20 @@
 }
 
 /*
  * zpool create [-fnd] [-B] [-o property=value] ...
  *              [-O file-system-property=value] ...
- *              [-R root] [-m mountpoint] <pool> <dev> ...
+ *              [-R root] [-m mountpoint] [-t tempname] <pool> <dev> ...
  *
  *      -B      Create boot partition.
  *      -f      Force creation, even if devices appear in use
  *      -n      Do not create the pool, but display the resulting layout if it
  *              were to be created.
  *      -R      Create a pool under an alternate root
  *      -m      Set default mountpoint for the root dataset.  By default it's
  *              '/<pool>'
+ *      -t      Use the temporary name until the pool is exported.
  *      -o      Set property=value.
  *      -d      Don't automatically enable all supported pool features
  *              (individual features can be enabled with -o).
  *      -O      Set fsproperty=value in the pool's root file system
  *

@@ -879,19 +896,20 @@
         zpool_boot_label_t boot_type = ZPOOL_NO_BOOT_LABEL;
         uint64_t boot_size = 0;
         int c;
         nvlist_t *nvroot = NULL;
         char *poolname;
+        char *tname = NULL;
         int ret = 1;
         char *altroot = NULL;
         char *mountpoint = NULL;
         nvlist_t *fsprops = NULL;
         nvlist_t *props = NULL;
         char *propval;
 
         /* check options */
-        while ((c = getopt(argc, argv, ":fndBR:m:o:O:")) != -1) {
+        while ((c = getopt(argc, argv, ":fndBR:m:o:O:t:")) != -1) {
                 switch (c) {
                 case 'f':
                         force = B_TRUE;
                         break;
                 case 'n':

@@ -912,15 +930,11 @@
                 case 'R':
                         altroot = optarg;
                         if (add_prop_list(zpool_prop_to_name(
                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
                                 goto errout;
-                        if (nvlist_lookup_string(props,
-                            zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
-                            &propval) == 0)
-                                break;
-                        if (add_prop_list(zpool_prop_to_name(
+                        if (add_prop_list_default(zpool_prop_to_name(
                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
                                 goto errout;
                         break;
                 case 'm':
                         /* Equivalent to -O mountpoint=optarg */

@@ -989,10 +1003,31 @@
                         } else if (add_prop_list(optarg, propval, &fsprops,
                             B_FALSE)) {
                                 goto errout;
                         }
                         break;
+                case 't':
+                        /*
+                         * Sanity check temporary pool name.
+                         */
+                        if (strchr(optarg, '/') != NULL) {
+                                (void) fprintf(stderr, gettext("cannot create "
+                                    "'%s': invalid character '/' in temporary "
+                                    "name\n"), optarg);
+                                (void) fprintf(stderr, gettext("use 'zfs "
+                                    "create' to create a dataset\n"));
+                                goto errout;
+                        }
+
+                        if (add_prop_list(zpool_prop_to_name(
+                            ZPOOL_PROP_TNAME), optarg, &props, B_TRUE))
+                                goto errout;
+                        if (add_prop_list_default(zpool_prop_to_name(
+                            ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
+                                goto errout;
+                        tname = optarg;
+                        break;
                 case ':':
                         (void) fprintf(stderr, gettext("missing argument for "
                             "'%c' option\n"), optopt);
                         goto badusage;
                 case '?':

@@ -1194,12 +1229,12 @@
                 }
 
                 ret = 1;
                 if (zpool_create(g_zfs, poolname,
                     nvroot, props, fsprops) == 0) {
-                        zfs_handle_t *pool = zfs_open(g_zfs, poolname,
-                            ZFS_TYPE_FILESYSTEM);
+                        zfs_handle_t *pool = zfs_open(g_zfs,
+                            tname ? tname : poolname, ZFS_TYPE_FILESYSTEM);
                         if (pool != NULL) {
                                 if (zfs_mount(pool, NULL, 0) == 0)
                                         ret = zfs_shareall(pool);
                                 zfs_close(pool);
                         }

@@ -2170,11 +2205,12 @@
 /*
  * zpool import [-d dir] [-D]
  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
  *              [-d dir | -c cachefile] [-f] -a
  *       import [-o mntopts] [-o prop=value] ... [-R root] [-D]
- *              [-d dir | -c cachefile] [-f] [-n] [-F] <pool | id> [newpool]
+ *              [-d dir | -c cachefile] [-f] [-n] [-F] [-t]
+ *              <pool | id> [newpool]
  *
  *       -c     Read pool information from a cachefile instead of searching
  *              devices.
  *
  *       -d     Scan in a specific directory, other than /dev/dsk.  More than

@@ -2199,10 +2235,13 @@
  *
  *       -n     See if rewind would work, but don't actually rewind.
  *
  *       -N     Import the pool but don't mount datasets.
  *
+ *      -t      Use newpool as a temporary pool name instead of renaming
+ *              the pool.
+ *
  *       -T     Specify a starting txg to use for import. This option is
  *              intentionally undocumented option for testing purposes.
  *
  *       -a     Import all pools found.
  *

@@ -2249,11 +2288,11 @@
                 {"rewind-to-checkpoint", no_argument, NULL, CHECKPOINT_OPT},
                 {0, 0, 0, 0}
         };
 
         /* check options */
-        while ((c = getopt_long(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX",
+        while ((c = getopt_long(argc, argv, ":aCc:d:DEfFmnNo:rR:tT:VX",
             long_options, NULL)) != -1) {
                 switch (c) {
                 case 'a':
                         do_all = B_TRUE;
                         break;

@@ -2304,15 +2343,17 @@
                         break;
                 case 'R':
                         if (add_prop_list(zpool_prop_to_name(
                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
                                 goto error;
-                        if (nvlist_lookup_string(props,
-                            zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
-                            &propval) == 0)
+                        if (add_prop_list_default(zpool_prop_to_name(
+                            ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
+                                goto error;
                                 break;
-                        if (add_prop_list(zpool_prop_to_name(
+                case 't':
+                        flags |= ZFS_IMPORT_TEMP_NAME;
+                        if (add_prop_list_default(zpool_prop_to_name(
                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
                                 goto error;
                         break;
                 case 'T':
                         errno = 0;

@@ -2447,13 +2488,13 @@
         if (pools != NULL && idata.exists &&
             (argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
                 (void) fprintf(stderr, gettext("cannot import '%s': "
                     "a pool with that name already exists\n"),
                     argv[0]);
-                (void) fprintf(stderr, gettext("use the form '%s "
-                    "<pool | id> <newpool>' to give it a new name\n"),
-                    "zpool import");
+                (void) fprintf(stderr, gettext("use the form 'zpool import "
+                    "[-t] <pool | id> <newpool>' to give it a new temporary "
+                    "or permanent name\n"));
                 err = 1;
         } else if (pools == NULL && idata.exists) {
                 (void) fprintf(stderr, gettext("cannot import '%s': "
                     "a pool with that name is already created/imported,\n"),
                     argv[0]);