Skip to content
This repository has been archived by the owner on Nov 7, 2019. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andriy Gapon authored and Dan McDonald committed Dec 18, 2018
1 parent 36acdd1 commit 04e5635
Show file tree
Hide file tree
Showing 14 changed files with 362 additions and 62 deletions.
135 changes: 88 additions & 47 deletions usr/src/cmd/zpool/zpool_main.c
Expand Up @@ -220,8 +220,9 @@ get_usage(zpool_help_t idx)
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:
Expand All @@ -239,7 +240,7 @@ get_usage(zpool_help_t idx)
"[-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 "
Expand Down Expand Up @@ -491,6 +492,21 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props,
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> ...
*
Expand Down Expand Up @@ -849,15 +865,16 @@ zpool_do_labelclear(int argc, char **argv)
/*
* 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
* -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).
Expand All @@ -881,6 +898,7 @@ zpool_do_create(int argc, char **argv)
int c;
nvlist_t *nvroot = NULL;
char *poolname;
char *tname = NULL;
int ret = 1;
char *altroot = NULL;
char *mountpoint = NULL;
Expand All @@ -889,7 +907,7 @@ zpool_do_create(int argc, char **argv)
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;
Expand All @@ -914,11 +932,7 @@ zpool_do_create(int argc, char **argv)
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;
Expand Down Expand Up @@ -991,6 +1005,27 @@ zpool_do_create(int argc, char **argv)
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);
Expand Down Expand Up @@ -1196,8 +1231,8 @@ zpool_do_create(int argc, char **argv)
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);
Expand All @@ -1224,7 +1259,7 @@ zpool_do_create(int argc, char **argv)
/*
* zpool destroy <pool>
*
* -f Forcefully unmount any datasets
* -f Forcefully unmount any datasets
*
* Destroy the given pool. Automatically unmounts any datasets in the pool.
*/
Expand Down Expand Up @@ -2098,8 +2133,8 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
* zpool checkpoint <pool>
* checkpoint --discard <pool>
*
* -d Discard the checkpoint from a checkpointed
* --discard pool.
* -d Discard the checkpoint from a checkpointed
* --discard pool.
*
* Checkpoints the specified pool, by taking a "snapshot" of its
* current state. A pool can only have one checkpoint at a time.
Expand Down Expand Up @@ -2172,44 +2207,48 @@ zpool_do_checkpoint(int argc, char **argv)
* 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
* -c Read pool information from a cachefile instead of searching
* devices.
*
* -d Scan in a specific directory, other than /dev/dsk. More than
* -d Scan in a specific directory, other than /dev/dsk. More than
* one directory can be specified using multiple '-d' options.
*
* -D Scan for previously destroyed pools or import all or only
* specified destroyed pools.
* -D Scan for previously destroyed pools or import all or only
* specified destroyed pools.
*
* -R Temporarily import the pool, with all mountpoints relative to
* -R Temporarily import the pool, with all mountpoints relative to
* the given root. The pool will remain exported when the machine
* is rebooted.
*
* -V Import even in the presence of faulted vdevs. This is an
* intentionally undocumented option for testing purposes, and
* treats the pool configuration as complete, leaving any bad
* -V Import even in the presence of faulted vdevs. This is an
* intentionally undocumented option for testing purposes, and
* treats the pool configuration as complete, leaving any bad
* vdevs in the FAULTED state. In other words, it does verbatim
* import.
*
* -f Force import, even if it appears that the pool is active.
* -f Force import, even if it appears that the pool is active.
*
* -F Attempt rewind if necessary.
*
* -F Attempt rewind if necessary.
* -n See if rewind would work, but don't actually rewind.
*
* -n See if rewind would work, but don't actually rewind.
* -N Import the pool but don't mount datasets.
*
* -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.
* -T Specify a starting txg to use for import. This option is
* intentionally undocumented option for testing purposes.
*
* -a Import all pools found.
* -a Import all pools found.
*
* -o Set property=value and/or temporary mount options (without '=').
* -o Set property=value and/or temporary mount options (without '=').
*
* --rewind-to-checkpoint
* Import the pool and revert back to the checkpoint.
* --rewind-to-checkpoint
* Import the pool and revert back to the checkpoint.
*
* The import command scans for pools to import, and import pools based on pool
* name and GUID. The pool can also be renamed as part of the import process.
Expand Down Expand Up @@ -2251,7 +2290,7 @@ zpool_do_import(int argc, char **argv)
};

/* 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':
Expand Down Expand Up @@ -2306,11 +2345,13 @@ zpool_do_import(int argc, char **argv)
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)
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 error;
break;
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;
Expand Down Expand Up @@ -2449,9 +2490,9 @@ zpool_do_import(int argc, char **argv)
(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': "
Expand Down Expand Up @@ -3367,7 +3408,7 @@ list_callback(zpool_handle_t *zhp, void *data)
* -o List of properties to display. Defaults to
* "name,size,allocated,free,expandsize,fragmentation,capacity,"
* "dedupratio,health,altroot"
* -p Diplay values in parsable (exact) format.
* -p Diplay values in parsable (exact) format.
* -T Display a timestamp in date(1) or Unix format
*
* List all pools in the system, whether or not they're healthy. Output space
Expand Down Expand Up @@ -5839,7 +5880,7 @@ get_callback(zpool_handle_t *zhp, void *data)
* by a single tab.
* -o List of columns to display. Defaults to
* "name,property,value,source".
* -p Diplay values in parsable (exact) format.
* -p Diplay values in parsable (exact) format.
*
* Get properties of pools in the system. Output space statistics
* for each one as well as other attributes.
Expand Down
2 changes: 2 additions & 0 deletions usr/src/common/zfs/zpool_prop.c
Expand Up @@ -136,6 +136,8 @@ zpool_prop_init(void)
PROP_READONLY, ZFS_TYPE_POOL, "NAME");
zprop_register_hidden(ZPOOL_PROP_MAXBLOCKSIZE, "maxblocksize",
PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_POOL, "MAXBLOCKSIZE");
zprop_register_hidden(ZPOOL_PROP_TNAME, "tname", PROP_TYPE_STRING,
PROP_ONETIME, ZFS_TYPE_POOL, "TNAME");
}

/*
Expand Down
11 changes: 11 additions & 0 deletions usr/src/lib/libzfs/common/libzfs_pool.c
Expand Up @@ -644,6 +644,7 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
goto error;
}
break;

case ZPOOL_PROP_READONLY:
if (!flags.import) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
Expand All @@ -654,6 +655,16 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
}
break;

case ZPOOL_PROP_TNAME:
if (!flags.create) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"property '%s' can only be set at "
"creation time"), propname);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}
break;

default:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"property '%s'(%d) not defined"), propname, prop);
Expand Down
30 changes: 28 additions & 2 deletions usr/src/man/man1m/zpool.1m
Expand Up @@ -58,6 +58,7 @@
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
.Oo Fl O Ar file-system-property Ns = Ns Ar value Oc Ns ...
.Op Fl R Ar root
.Op Fl t Ar tempname
.Ar pool vdev Ns ...
.Nm
.Cm destroy
Expand Down Expand Up @@ -95,7 +96,7 @@
.Op Fl R Ar root
.Nm
.Cm import
.Op Fl Dfm
.Op Fl Dfmt
.Op Fl F Op Fl n
.Op Fl -rewind-to-checkpoint
.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir
Expand Down Expand Up @@ -867,6 +868,7 @@ specified device or devices are cleared.
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
.Oo Fl O Ar file-system-property Ns = Ns Ar value Oc Ns ...
.Op Fl R Ar root
.Op Fl t Ar tempname
.Ar pool vdev Ns ...
.Xc
Creates a new storage pool containing the virtual devices specified on the
Expand Down Expand Up @@ -988,6 +990,16 @@ for a list of valid properties that can be set.
.It Fl R Ar root
Equivalent to
.Fl o Sy cachefile Ns = Ns Sy none Fl o Sy altroot Ns = Ns Ar root
.It Fl t Ar tempname
Sets the in-core pool name to
.Pa tempname
while the on-disk name will be the name specified as the pool name
.Pa pool .
This will set the default cachefile property to
.Sy none.
This is intended to handle name space collisions when creating pools
for other systems, such as virtual machines or physical machines
whose pools live on network block devices.
.El
.It Xo
.Nm
Expand Down Expand Up @@ -1233,7 +1245,7 @@ property to
.It Xo
.Nm
.Cm import
.Op Fl Dfm
.Op Fl Dfmt
.Op Fl F Op Fl n
.Op Fl -rewind-to-checkpoint
.Op Fl c Ar cachefile Ns | Ns Fl d Ar dir
Expand Down Expand Up @@ -1324,6 +1336,20 @@ and the
.Sy altroot
property to
.Ar root .
.It Fl t
Used with
.Ar newpool .
Specifies that
.Ar newpool
is temporary.
Temporary pool names last until export.
Ensures that the original pool name will be used in all label updates and
therefore is retained upon export.
Will also set
.Sy cachefile
property to
.Sy none
when not explicitly specified.
.It Fl -rewind-to-checkpoint
Rewinds pool to the checkpointed state.
Once the pool is imported with this flag there is no way to undo the rewind.
Expand Down

0 comments on commit 04e5635

Please sign in to comment.