summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool.830
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_main.c89
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c11
-rw-r--r--sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c19
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c32
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h2
7 files changed, 156 insertions, 29 deletions
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool.8 b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
index 168b936..f40473d 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool.8
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool.8
@@ -62,6 +62,7 @@
.Ar ...
.Op Fl m Ar mountpoint
.Op Fl R Ar root
+.Op Fl t Ar tempname
.Ar pool vdev ...
.Nm
.Cm destroy
@@ -115,6 +116,7 @@
.Op Fl m
.Op Fl N
.Op Fl R Ar root
+.Op Fl t
.Op Fl F Op Fl n
.Ar pool | id
.Op Ar newpool
@@ -966,6 +968,7 @@ do not actually discard any transactions.
.Ar ...
.Op Fl m Ar mountpoint
.Op Fl R Ar root
+.Op Fl t Ar tempname
.Ar pool vdev ...
.Xc
.Pp
@@ -1067,6 +1070,18 @@ or
.Qq Cm none .
For more information on dataset mount points, see
.Xr zfs 8 .
+.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
+.Sy 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
@@ -1321,6 +1336,7 @@ Searches for and imports all pools found.
.Op Fl m
.Op Fl N
.Op Fl R Ar root
+.Op Fl t
.Op Fl F Op Fl n
.Ar pool | id
.Op Ar newpool
@@ -1380,6 +1396,20 @@ Import the pool without mounting any file systems.
.It Fl R Ar root
Equivalent to
.Qq Fl o Cm cachefile=none,altroot= Ns Pa 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 F
Recovery mode for a non-importable pool. Attempt to return the pool to an
importable state by discarding the last few transactions. Not all damaged pools
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
index 51edeca..582b4f0 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -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:
@@ -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 "
@@ -489,6 +490,21 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props,
}
/*
+ * 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
@@ -850,15 +866,16 @@ errout:
/*
* 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).
@@ -882,6 +899,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;
@@ -890,7 +908,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;
@@ -922,11 +940,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;
@@ -999,6 +1013,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);
@@ -1205,8 +1240,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);
@@ -2162,7 +2197,8 @@ 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
* devices.
@@ -2191,6 +2227,9 @@ zpool_do_checkpoint(int argc, char **argv)
*
* -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.
*
@@ -2241,7 +2280,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':
@@ -2296,11 +2335,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;
@@ -2439,9 +2480,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': "
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
index 61c5325..1eec116 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
@@ -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,
@@ -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);
diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
index 0ee864a..0a69a51 100644
--- a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
+++ b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
@@ -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");
}
/*
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
index f24a7351..a71a940 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -4666,12 +4666,18 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
uint_t nspares, nl2cache;
uint64_t version, obj;
boolean_t has_features;
+ char *poolname;
+ nvlist_t *nvl;
+
+ if (nvlist_lookup_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_TNAME), &poolname) != 0)
+ poolname = (char *)pool;
/*
* If this pool already exists, return failure.
*/
mutex_enter(&spa_namespace_lock);
- if (spa_lookup(pool) != NULL) {
+ if (spa_lookup(poolname) != NULL) {
mutex_exit(&spa_namespace_lock);
return (SET_ERROR(EEXIST));
}
@@ -4679,9 +4685,12 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
/*
* Allocate a new spa_t structure.
*/
+ nvl = fnvlist_alloc();
+ fnvlist_add_string(nvl, ZPOOL_CONFIG_POOL_NAME, pool);
(void) nvlist_lookup_string(props,
zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
- spa = spa_add(pool, NULL, altroot);
+ spa = spa_add(poolname, nvl, altroot);
+ fnvlist_free(nvl);
spa_activate(spa, spa_mode_global);
if (props && (error = spa_prop_validate(spa, props))) {
@@ -4691,6 +4700,12 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
return (error);
}
+ /*
+ * Temporary pool names should never be written to disk.
+ */
+ if (poolname != pool)
+ spa->spa_import_flags |= ZFS_IMPORT_TEMP_NAME;
+
has_features = B_FALSE;
for (nvpair_t *elem = nvlist_next_nvpair(props, NULL);
elem != NULL; elem = nvlist_next_nvpair(props, elem)) {
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
index b0cc3f2..ff1fcb4 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
@@ -226,6 +226,7 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent)
nvlist_t *nvl;
boolean_t ccw_failure;
int error;
+ char *pool_name;
ASSERT(MUTEX_HELD(&spa_namespace_lock));
@@ -274,11 +275,18 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent)
if (nvl == NULL)
nvl = fnvlist_alloc();
- fnvlist_add_nvlist(nvl, spa->spa_name,
+ if (spa->spa_import_flags & ZFS_IMPORT_TEMP_NAME) {
+ pool_name = fnvlist_lookup_string(spa->spa_config,
+ ZPOOL_CONFIG_POOL_NAME);
+ } else {
+ pool_name = spa_name(spa);
+ }
+
+ fnvlist_add_nvlist(nvl, pool_name,
spa->spa_config);
mutex_exit(&spa->spa_props_lock);
- if (nvlist_lookup_nvlist(nvl, spa->spa_name, &nvroot) == 0)
+ if (nvlist_lookup_nvlist(nvl, pool_name, &nvroot) == 0)
spa_config_clean(nvroot);
}
@@ -382,6 +390,7 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
unsigned long hostid = 0;
boolean_t locked = B_FALSE;
uint64_t split_guid;
+ char *pool_name;
if (vd == NULL) {
vd = rvd;
@@ -398,10 +407,27 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
if (txg == -1ULL)
txg = spa->spa_config_txg;
+ /*
+ * Originally, users had to handle spa namespace collisions by either
+ * exporting the already imported pool or by specifying a new name for
+ * the pool with a conflicting name. In the case of root pools from
+ * virtual guests, neither approach to collision resolution is
+ * reasonable. This is addressed by extending the new name syntax with
+ * an option to specify that the new name is temporary. When specified,
+ * ZFS_IMPORT_TEMP_NAME will be set in spa->spa_import_flags to tell us
+ * to use the previous name, which we do below.
+ */
+ if (spa->spa_import_flags & ZFS_IMPORT_TEMP_NAME) {
+ pool_name = fnvlist_lookup_string(spa->spa_config,
+ ZPOOL_CONFIG_POOL_NAME);
+ } else {
+ pool_name = spa_name(spa);
+ }
+
config = fnvlist_alloc();
fnvlist_add_uint64(config, ZPOOL_CONFIG_VERSION, spa_version(spa));
- fnvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, spa_name(spa));
+ fnvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, pool_name);
fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, spa_state(spa));
fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG, txg);
fnvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa));
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
index a72d4db..6120296 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
@@ -214,6 +214,7 @@ typedef enum {
ZPOOL_PROP_MAXBLOCKSIZE,
ZPOOL_PROP_BOOTSIZE,
ZPOOL_PROP_CHECKPOINT,
+ ZPOOL_PROP_TNAME,
ZPOOL_NUM_PROPS
} zpool_prop_t;
@@ -1047,6 +1048,7 @@ typedef enum {
#define ZFS_IMPORT_MISSING_LOG 0x4
#define ZFS_IMPORT_ONLY 0x8
#define ZFS_IMPORT_CHECKPOINT 0x10
+#define ZFS_IMPORT_TEMP_NAME 0x20
/*
* Channel program argument/return nvlist keys and defaults.
OpenPOWER on IntegriCloud