summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2018-12-18 12:56:14 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2018-12-18 12:56:14 +0000
commit41550557750bcfd086b0339d512607e83759f1f1 (patch)
treea786eb6e40c50846d36672be1c5c6f6b32498ff3
parentf4cb444376b6efe8770e521115e58d5df2379c97 (diff)
parent04e56356520b98d5a93c496b10f02530bb6647e0 (diff)
downloadillumos-joyent-41550557750bcfd086b0339d512607e83759f1f1.tar.gz
[illumos-gate merge]
commit 04e56356520b98d5a93c496b10f02530bb6647e0 5882 Temporary pool names commit 36acdd115a7d14b9a0ffd968d084ebeac2451a7e 10062 illumos.sh could be re-organized commit 4da7ed37ba5e1e12c0618eef16411d6fd67dd8c6 10060 loader: fix DEBUG messages in disk/part interfaces commit 922a2a1681b0f92b4d65daff3cbcd841293d5778 10058 loader: Add an ISO9660 "partition table" type to loader. commit 67deef8cbc83060db238a0f4ee252d1ba74641ef Conflicts: usr/src/tools/env/illumos.sh usr/src/cmd/zpool/zpool_main.c
-rw-r--r--usr/src/boot/Makefile.version2
-rw-r--r--usr/src/boot/sys/boot/common/disk.c40
-rw-r--r--usr/src/boot/sys/boot/common/part.c53
-rw-r--r--usr/src/boot/sys/boot/common/part.h10
-rw-r--r--usr/src/cmd/zpool/zpool_main.c137
-rw-r--r--usr/src/common/zfs/zpool_prop.c2
-rw-r--r--usr/src/lib/libzfs/common/libzfs_pool.c11
-rw-r--r--usr/src/man/man1m/zpool.1m30
-rw-r--r--usr/src/pkg/manifests/system-test-zfstest.mf6
-rw-r--r--usr/src/test/zfs-tests/runfiles/delphix.run6
-rw-r--r--usr/src/test/zfs-tests/runfiles/omnios.run6
-rw-r--r--usr/src/test/zfs-tests/runfiles/openindiana.run6
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh68
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_014_pos.ksh91
-rw-r--r--usr/src/tools/cw/cw.1onbld9
-rw-r--r--usr/src/tools/cw/cw.c104
-rw-r--r--usr/src/tools/env/illumos.sh160
-rw-r--r--usr/src/uts/common/fs/zfs/spa.c19
-rw-r--r--usr/src/uts/common/fs/zfs/spa_config.c30
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_ioctl.c10
-rw-r--r--usr/src/uts/common/sys/fs/zfs.h4
21 files changed, 558 insertions, 246 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version
index 143e416056..f7de1f0e03 100644
--- a/usr/src/boot/Makefile.version
+++ b/usr/src/boot/Makefile.version
@@ -33,4 +33,4 @@ LOADER_VERSION = 1.1
# Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes.
# The version is processed from left to right, the version number can only
# be increased.
-BOOT_VERSION = $(LOADER_VERSION)-2018.11.05.1
+BOOT_VERSION = $(LOADER_VERSION)-2018.12.11.1
diff --git a/usr/src/boot/sys/boot/common/disk.c b/usr/src/boot/sys/boot/common/disk.c
index 7d48e2842a..9e70f5256d 100644
--- a/usr/src/boot/sys/boot/common/disk.c
+++ b/usr/src/boot/sys/boot/common/disk.c
@@ -1,4 +1,4 @@
-/*-
+/*
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
* All rights reserved.
@@ -30,22 +30,23 @@
#include <sys/queue.h>
#include <stand.h>
#include <stdarg.h>
+#include <inttypes.h>
#include <bootstrap.h>
#include <part.h>
#include "disk.h"
#ifdef DISK_DEBUG
-# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
+#define DEBUG(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)
#else
-# define DEBUG(fmt, args...)
+#define DEBUG(fmt, args...)
#endif
struct open_disk {
struct ptable *table;
uint64_t mediasize;
uint64_t entrysize;
- u_int sectorsize;
+ uint_t sectorsize;
};
struct print_args {
@@ -56,7 +57,7 @@ struct print_args {
/* Convert size to a human-readable number. */
static char *
-display_size(uint64_t size, u_int sectorsize)
+display_size(uint64_t size, uint_t sectorsize)
{
static char buf[80];
char unit;
@@ -73,7 +74,7 @@ display_size(uint64_t size, u_int sectorsize)
size /= 1024;
unit = 'M';
}
- sprintf(buf, "%ld%cB", (long)size, unit);
+ snprintf(buf, sizeof (buf), "%" PRIu64 "%cB", size, unit);
return (buf);
}
@@ -96,7 +97,7 @@ ptblread(void *d, void *buf, size_t blocks, uint64_t offset)
* As the GPT backup partition is located at the end of the disk,
* to avoid reading past disk end, flag bcache not to use RA.
*/
- return (dev->dd.d_dev->dv_strategy(dev, F_READ | F_NORA , offset,
+ return (dev->dd.d_dev->dv_strategy(dev, F_READ | F_NORA, offset,
blocks * od->sectorsize, (char *)buf, NULL));
}
@@ -170,7 +171,7 @@ disk_print(struct disk_devdesc *dev, char *prefix, int verbose)
}
int
-disk_read(struct disk_devdesc *dev, void *buf, uint64_t offset, u_int blocks)
+disk_read(struct disk_devdesc *dev, void *buf, uint64_t offset, uint_t blocks)
{
struct open_disk *od;
int ret;
@@ -183,7 +184,7 @@ disk_read(struct disk_devdesc *dev, void *buf, uint64_t offset, u_int blocks)
}
int
-disk_write(struct disk_devdesc *dev, void *buf, uint64_t offset, u_int blocks)
+disk_write(struct disk_devdesc *dev, void *buf, uint64_t offset, uint_t blocks)
{
struct open_disk *od;
int ret;
@@ -196,7 +197,7 @@ disk_write(struct disk_devdesc *dev, void *buf, uint64_t offset, u_int blocks)
}
int
-disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *data)
+disk_ioctl(struct disk_devdesc *dev, unsigned long cmd, void *data)
{
struct open_disk *od = dev->dd.d_opendata;
@@ -205,7 +206,7 @@ disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *data)
switch (cmd) {
case DIOCGSECTORSIZE:
- *(u_int *)data = od->sectorsize;
+ *(uint_t *)data = od->sectorsize;
break;
case DIOCGMEDIASIZE:
if (dev->d_offset == 0)
@@ -221,7 +222,7 @@ disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *data)
}
int
-disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize)
+disk_open(struct disk_devdesc *dev, uint64_t mediasize, uint_t sectorsize)
{
struct open_disk *od;
struct ptable *table;
@@ -237,7 +238,7 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize)
table = NULL;
slice = dev->d_slice;
partition = dev->d_partition;
- od = (struct open_disk *)malloc(sizeof(struct open_disk));
+ od = (struct open_disk *)malloc(sizeof (struct open_disk));
if (od == NULL) {
DEBUG("no memory");
return (ENOMEM);
@@ -246,8 +247,8 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize)
od->entrysize = 0;
od->mediasize = mediasize;
od->sectorsize = sectorsize;
- DEBUG("%s unit %d, slice %d, partition %d => %p",
- disk_fmtdev(dev), dev->d_unit, dev->d_slice, dev->d_partition, od);
+ DEBUG("%s unit %d, slice %d, partition %d => %p", disk_fmtdev(dev),
+ dev->dd.d_unit, dev->d_slice, dev->d_partition, od);
/* Determine disk layout. */
od->table = ptable_open(dev, mediasize / sectorsize, sectorsize,
@@ -272,6 +273,9 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize)
dev->d_offset = part.start;
od->entrysize = part.end - part.start + 1;
}
+ } else if (ptable_gettype(od->table) == PTABLE_ISO9660) {
+ dev->d_offset = 0;
+ od->entrysize = mediasize;
} else if (slice >= 0) {
/* Try to get information about partition */
if (slice == 0)
@@ -340,8 +344,8 @@ out:
/* Save the slice and partition number to the dev */
dev->d_slice = slice;
dev->d_partition = partition;
- DEBUG("%s offset %lld => %p", disk_fmtdev(dev),
- (long long)dev->d_offset, od);
+ DEBUG("%s offset %" PRIu64 " => %p", disk_fmtdev(dev),
+ dev->d_offset, od);
}
return (rc);
}
@@ -358,7 +362,7 @@ disk_close(struct disk_devdesc *dev)
return (0);
}
-char*
+char *
disk_fmtdev(struct disk_devdesc *dev)
{
static char buf[128];
diff --git a/usr/src/boot/sys/boot/common/part.c b/usr/src/boot/sys/boot/common/part.c
index 25a9cf98a0..8a24eb2920 100644
--- a/usr/src/boot/sys/boot/common/part.c
+++ b/usr/src/boot/sys/boot/common/part.c
@@ -36,6 +36,8 @@
#include <sys/queue.h>
#include <sys/vtoc.h>
+#include <fs/cd9660/iso.h>
+
#include <zlib.h>
#include <part.h>
#include <uuid.h>
@@ -101,6 +103,7 @@ static struct parttypes {
{ PART_LINUX, "Linux" },
{ PART_LINUX_SWAP, "Linux swap" },
{ PART_DOS, "DOS/Windows" },
+ { PART_ISO9660, "ISO9660" },
{ PART_SOLARIS2, "Solaris 2" },
{ PART_ILLUMOS_UFS, "illumos UFS" },
{ PART_ILLUMOS_ZFS, "illumos ZFS" },
@@ -180,7 +183,7 @@ gpt_checkhdr(struct gpt_hdr *hdr, uint64_t lba_self,
}
sz = le32toh(hdr->hdr_size);
if (sz < 92 || sz > sectorsize) {
- DEBUG("invalid GPT header size: %d", sz);
+ DEBUG("invalid GPT header size: %u", sz);
return (NULL);
}
crc = le32toh(hdr->hdr_crc_self);
@@ -192,7 +195,7 @@ gpt_checkhdr(struct gpt_hdr *hdr, uint64_t lba_self,
hdr->hdr_crc_self = crc;
hdr->hdr_revision = le32toh(hdr->hdr_revision);
if (hdr->hdr_revision < GPT_HDR_REVISION) {
- DEBUG("unsupported GPT revision %d", hdr->hdr_revision);
+ DEBUG("unsupported GPT revision %u", hdr->hdr_revision);
return (NULL);
}
hdr->hdr_lba_self = le64toh(hdr->hdr_lba_self);
@@ -710,6 +713,45 @@ out:
return (table);
}
+#define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / table->sectorsize)
+
+static struct ptable *
+ptable_iso9660read(struct ptable *table, void *dev, diskread_t dread)
+{
+ uint8_t *buf;
+ struct iso_primary_descriptor *vd;
+ struct pentry *entry;
+
+ buf = malloc(table->sectorsize);
+ if (buf == NULL)
+ return (table);
+
+ if (dread(dev, buf, 1, cdb2devb(16)) != 0) {
+ DEBUG("read failed");
+ ptable_close(table);
+ table = NULL;
+ goto out;
+ }
+ vd = (struct iso_primary_descriptor *)buf;
+ if (bcmp(vd->id, ISO_STANDARD_ID, sizeof (vd->id)) != 0)
+ goto out;
+
+ entry = malloc(sizeof (*entry));
+ if (entry == NULL)
+ goto out;
+ entry->part.start = 0;
+ entry->part.end = table->sectors;
+ entry->part.type = PART_ISO9660;
+ entry->part.index = 0;
+ STAILQ_INSERT_TAIL(&table->entries, entry, entry);
+
+ table->type = PTABLE_ISO9660;
+
+out:
+ free(buf);
+ return (table);
+}
+
struct ptable *
ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, diskread_t *dread)
{
@@ -740,6 +782,13 @@ ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, diskread_t *dread)
table->type = PTABLE_NONE;
STAILQ_INIT(&table->entries);
+ if (ptable_iso9660read(table, dev, dread) == NULL) {
+ /* Read error. */
+ table = NULL;
+ goto out;
+ } else if (table->type == PTABLE_ISO9660)
+ goto out;
+
if (ptable_dklabelread(table, dev, dread) == NULL) { /* Read error. */
table = NULL;
goto out;
diff --git a/usr/src/boot/sys/boot/common/part.h b/usr/src/boot/sys/boot/common/part.h
index a554016d92..2881c78b64 100644
--- a/usr/src/boot/sys/boot/common/part.h
+++ b/usr/src/boot/sys/boot/common/part.h
@@ -1,4 +1,4 @@
-/*-
+/*
* Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
* All rights reserved.
*
@@ -22,8 +22,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#ifndef _PART_H_
@@ -37,7 +35,8 @@ enum ptable_type {
PTABLE_MBR,
PTABLE_GPT,
PTABLE_VTOC8,
- PTABLE_VTOC
+ PTABLE_VTOC,
+ PTABLE_ISO9660
};
enum partition_type {
@@ -53,6 +52,7 @@ enum partition_type {
PART_LINUX,
PART_LINUX_SWAP,
PART_DOS,
+ PART_ISO9660,
PART_SOLARIS2,
PART_ILLUMOS_UFS,
PART_ILLUMOS_ZFS,
@@ -64,7 +64,7 @@ enum partition_type {
PART_VTOC_BACKUP,
PART_VTOC_STAND,
PART_VTOC_VAR,
- PART_VTOC_HOME,
+ PART_VTOC_HOME
};
struct ptable_entry {
diff --git a/usr/src/cmd/zpool/zpool_main.c b/usr/src/cmd/zpool/zpool_main.c
index 742891a2a4..e82d8a089e 100644
--- a/usr/src/cmd/zpool/zpool_main.c
+++ b/usr/src/cmd/zpool/zpool_main.c
@@ -221,8 +221,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:
@@ -240,7 +241,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 "
@@ -493,6 +494,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;
@@ -915,11 +933,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;
@@ -992,6 +1006,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);
@@ -1197,8 +1232,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);
@@ -1225,7 +1260,7 @@ badusage:
/*
* zpool destroy <pool>
*
- * -f Forcefully unmount any datasets
+ * -f Forcefully unmount any datasets
*
* Destroy the given pool. Automatically unmounts any datasets in the pool.
*/
@@ -2099,8 +2134,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.
@@ -2173,46 +2208,50 @@ 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.
+ * -m Allow import with a missing log device.
*
- * -m Allow import with a missing log device.
+ * -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.
@@ -2254,7 +2293,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':
@@ -2309,11 +2348,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;
@@ -2452,9 +2493,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': "
@@ -3370,7 +3411,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
@@ -5842,7 +5883,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.
diff --git a/usr/src/common/zfs/zpool_prop.c b/usr/src/common/zfs/zpool_prop.c
index 0ee864ade5..0a69a51207 100644
--- a/usr/src/common/zfs/zpool_prop.c
+++ b/usr/src/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/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c
index 3d2cb06ac9..56e1d7032e 100644
--- a/usr/src/lib/libzfs/common/libzfs_pool.c
+++ b/usr/src/lib/libzfs/common/libzfs_pool.c
@@ -645,6 +645,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,
@@ -655,6 +656,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/usr/src/man/man1m/zpool.1m b/usr/src/man/man1m/zpool.1m
index 1e7b2b8cfc..9e7f36afed 100644
--- a/usr/src/man/man1m/zpool.1m
+++ b/usr/src/man/man1m/zpool.1m
@@ -59,6 +59,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
@@ -96,7 +97,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
@@ -868,6 +869,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
@@ -989,6 +991,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
@@ -1234,7 +1246,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
@@ -1325,6 +1337,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.
diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf
index ccd9d94f48..88f6f6bdc6 100644
--- a/usr/src/pkg/manifests/system-test-zfstest.mf
+++ b/usr/src/pkg/manifests/system-test-zfstest.mf
@@ -1420,6 +1420,9 @@ file \
path=opt/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_features_004_neg \
mode=0555
file \
+ path=opt/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname \
+ mode=0555
+file \
path=opt/zfs-tests/tests/functional/cli_root/zpool_destroy/zpool_destroy.cfg \
mode=0444
file \
@@ -1571,6 +1574,9 @@ file \
path=opt/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_013_neg \
mode=0555
file \
+ path=opt/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_014_pos \
+ mode=0555
+file \
path=opt/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_all_001_pos \
mode=0555
file \
diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run
index fac8836b72..57ed0506e3 100644
--- a/usr/src/test/zfs-tests/runfiles/delphix.run
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run
@@ -251,7 +251,8 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
'zpool_create_018_pos', 'zpool_create_019_pos', 'zpool_create_020_pos',
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
- 'zpool_create_features_003_pos', 'zpool_create_features_004_neg']
+ 'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
+ 'zpool_create_tempname']
[/opt/zfs-tests/tests/functional/cli_root/zpool_destroy]
tests = ['zpool_destroy_001_pos', 'zpool_destroy_002_pos',
@@ -282,7 +283,8 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
'zpool_import_003_pos', 'zpool_import_004_pos', 'zpool_import_005_pos',
'zpool_import_006_pos', 'zpool_import_007_pos', 'zpool_import_008_pos',
'zpool_import_009_neg', 'zpool_import_010_pos', 'zpool_import_011_neg',
- 'zpool_import_012_pos', 'zpool_import_013_neg', 'zpool_import_all_001_pos',
+ 'zpool_import_012_pos', 'zpool_import_013_neg', 'zpool_import_014_pos',
+ 'zpool_import_all_001_pos',
'zpool_import_features_001_pos', 'zpool_import_features_002_neg',
'zpool_import_features_003_pos', 'zpool_import_missing_001_pos',
'zpool_import_missing_002_pos', 'zpool_import_missing_003_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run
index 761e06c1cf..ca3181af77 100644
--- a/usr/src/test/zfs-tests/runfiles/omnios.run
+++ b/usr/src/test/zfs-tests/runfiles/omnios.run
@@ -243,7 +243,8 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
'zpool_create_018_pos', 'zpool_create_019_pos', 'zpool_create_020_pos',
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
- 'zpool_create_features_003_pos', 'zpool_create_features_004_neg']
+ 'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
+ 'zpool_create_tempname']
[/opt/zfs-tests/tests/functional/cli_root/zpool_destroy]
tests = ['zpool_destroy_001_pos', 'zpool_destroy_002_pos',
@@ -274,7 +275,8 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
'zpool_import_003_pos', 'zpool_import_004_pos', 'zpool_import_005_pos',
'zpool_import_006_pos', 'zpool_import_007_pos', 'zpool_import_008_pos',
'zpool_import_009_neg', 'zpool_import_010_pos', 'zpool_import_011_neg',
- 'zpool_import_012_pos', 'zpool_import_013_neg', 'zpool_import_all_001_pos',
+ 'zpool_import_012_pos', 'zpool_import_013_neg', 'zpool_import_014_pos',
+ 'zpool_import_all_001_pos',
'zpool_import_features_001_pos', 'zpool_import_features_002_neg',
'zpool_import_features_003_pos', 'zpool_import_missing_001_pos',
'zpool_import_missing_002_pos', 'zpool_import_missing_003_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run
index 5c6d853984..43a2a641c8 100644
--- a/usr/src/test/zfs-tests/runfiles/openindiana.run
+++ b/usr/src/test/zfs-tests/runfiles/openindiana.run
@@ -243,7 +243,8 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
'zpool_create_018_pos', 'zpool_create_019_pos', 'zpool_create_020_pos',
'zpool_create_021_pos', 'zpool_create_022_pos', 'zpool_create_023_neg',
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
- 'zpool_create_features_003_pos', 'zpool_create_features_004_neg']
+ 'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
+ 'zpool_create_tempname']
[/opt/zfs-tests/tests/functional/cli_root/zpool_destroy]
tests = ['zpool_destroy_001_pos', 'zpool_destroy_002_pos',
@@ -274,7 +275,8 @@ tests = ['zpool_import_001_pos', 'zpool_import_002_pos',
'zpool_import_003_pos', 'zpool_import_004_pos', 'zpool_import_005_pos',
'zpool_import_006_pos', 'zpool_import_007_pos', 'zpool_import_008_pos',
'zpool_import_009_neg', 'zpool_import_010_pos', 'zpool_import_011_neg',
- 'zpool_import_012_pos', 'zpool_import_013_neg', 'zpool_import_all_001_pos',
+ 'zpool_import_012_pos', 'zpool_import_013_neg', 'zpool_import_014_pos',
+ 'zpool_import_all_001_pos',
'zpool_import_features_001_pos', 'zpool_import_features_002_neg',
'zpool_import_features_003_pos', 'zpool_import_missing_001_pos',
'zpool_import_missing_002_pos', 'zpool_import_missing_003_pos',
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh
new file mode 100644
index 0000000000..eb0a1375f5
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh
@@ -0,0 +1,68 @@
+#!/bin/ksh -p
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# 'zpool create -t <tempname>' can create a pool with the specified temporary
+# name. The pool should be present in the namespace as <tempname> until exported
+#
+# STRATEGY:
+# 1. Create a pool with '-t' option
+# 2. Verify the pool is created with the specified temporary name
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ destroy_pool $TESTPOOL
+ destroy_pool $TEMPPOOL
+
+}
+
+log_assert "'zpool create -t <tempname>' can create a pool with the specified" \
+ " temporary name."
+log_onexit cleanup
+
+TEMPPOOL="tempname.$$"
+typeset poolprops=('comment=text' 'listsnapshots=on' 'autoexpand=on'
+ 'autoreplace=on' 'delegation=off' 'failmode=continue')
+typeset fsprops=('canmount=off' 'mountpoint=none' 'utf8only=on'
+ 'casesensitivity=mixed' 'version=1' 'normalization=formKD')
+
+for poolprop in "${poolprops[@]}"; do
+ for fsprop in "${fsprops[@]}"; do
+ # 1. Create a pool with '-t' option
+ log_must zpool create -t $TEMPPOOL \
+ -O $fsprop -o $poolprop $TESTPOOL $DISKS
+ # 2. Verify the pool is created with the specified temporary name
+ log_must poolexists $TEMPPOOL
+ log_mustnot poolexists $TESTPOOL
+ propname="$(awk -F= '{print $1}' <<< $fsprop)"
+ propval="$(awk -F= '{print $2}' <<< $fsprop)"
+ log_must test "$(get_prop $propname $TEMPPOOL)" == "$propval"
+ propname="$(awk -F= '{print $1}' <<< $poolprop)"
+ propval="$(awk -F= '{print $2}' <<< $poolprop)"
+ log_must test "$(get_pool_prop $propname $TEMPPOOL)" == "$propval"
+ # Cleanup
+ destroy_pool $TEMPPOOL
+ done
+done
+
+log_pass "'zpool create -t <tempname>' successfully creates pools with" \
+ " temporary names"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_014_pos.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_014_pos.ksh
new file mode 100644
index 0000000000..d70bced265
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_014_pos.ksh
@@ -0,0 +1,91 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2016, loli10K. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
+
+#
+# DESCRIPTION:
+# Temporary pool names should not be persisted on devices.
+#
+# STRATEGY:
+# 1. Create pool A, then export it.
+# 2. Re-import the pool with a temporary name B, then export it.
+# 3. Verify device labels still contain the expected pool name (A).
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+ typeset dt
+ for dt in $poolB $poolA; do
+ destroy_pool $dt
+ done
+
+ log_must rm -rf $DEVICE_DIR/*
+ typeset i=0
+ while (( i < $MAX_NUM )); do
+ log_must mkfile $FILE_SIZE ${DEVICE_DIR}/${DEVICE_FILE}$i
+ ((i += 1))
+ done
+}
+
+#
+# Verify name of (exported) pool from device $1 label is equal to $2
+# $1 device
+# $2 pool name
+#
+function verify_pool_name
+{
+ typeset device=$1
+ typeset poolname=$2
+ typeset labelname
+
+ zdb -e -l $device | grep " name:" | {
+ while read labelname ; do
+ if [[ "name: '$poolname'" != "$labelname" ]]; then
+ return 1
+ fi
+ done
+ }
+ return 0
+}
+
+log_assert "Temporary pool names should not be persisted on devices."
+log_onexit cleanup
+
+poolA=poolA.$$; poolB=poolB.$$;
+
+log_must zpool create $poolA $VDEV0
+log_must zpool export $poolA
+
+log_must zpool import -t $poolA $poolB -d $DEVICE_DIR
+log_must zpool export $poolB
+
+log_must eval "verify_pool_name $VDEV0 $poolA"
+
+log_pass "Temporary pool names are not persisted on devices."
diff --git a/usr/src/tools/cw/cw.1onbld b/usr/src/tools/cw/cw.1onbld
index 62800bb727..da3f224cd2 100644
--- a/usr/src/tools/cw/cw.1onbld
+++ b/usr/src/tools/cw/cw.1onbld
@@ -137,10 +137,11 @@ will invoke each shadow compiler, with the outputs modified (as well as any
translation for compiler style) as follows:
.Bl -enum
.It
-If
-.Nm cw
-is invoked to link-edit without compilation (the input files are all objects),
-the shadow compiler is not invoked.
+If neither of
+.Fl c ,
+.Fl S
+appears in the argument list (that is, linking is attempted or only the
+pre-processor is invoked), the shadow compilers will not be invoked.
.It
If the
.Fl o Ar filename
diff --git a/usr/src/tools/cw/cw.c b/usr/src/tools/cw/cw.c
index 91d62075dc..c68ace9848 100644
--- a/usr/src/tools/cw/cw.c
+++ b/usr/src/tools/cw/cw.c
@@ -308,7 +308,7 @@ typedef struct cw_ictx {
int i_oldargc;
char **i_oldargv;
pid_t i_pid;
- char *i_discard;
+ char i_discard[MAXPATHLEN];
char *i_stderr;
} cw_ictx_t;
@@ -553,35 +553,6 @@ xlate(struct aelist *h, const char *xarg, const char **table)
}
}
-/*
- * The compiler wants the output file to end in appropriate extension. If
- * we're generating a name from whole cloth (path == NULL), we assume that
- * extension to be .o, otherwise we match the extension of the caller.
- */
-static char *
-discard_file_name(const char *path)
-{
- char *ret, *ext, *file;
-
- if (path == NULL) {
- ext = ".o";
- } else {
- ext = strrchr(path, '.');
- }
-
- if ((ret = calloc(MAXPATHLEN, sizeof (char))) == NULL)
- nomem();
-
- if ((file = tempnam(NULL, ".cw")) == NULL)
- nomem();
-
- (void) strlcpy(ret, file, MAXPATHLEN);
- if (ext != NULL)
- (void) strlcat(ret, ext, MAXPATHLEN);
- free(file);
- return (ret);
-}
-
static void
do_gcc(cw_ictx_t *ctx)
{
@@ -591,7 +562,7 @@ do_gcc(cw_ictx_t *ctx)
cw_op_t op = CW_O_LINK;
char *model = NULL;
char *nameflag;
- int mflag = 0;
+ int mflag = 0;
if (ctx->i_flags & CW_F_PROG) {
newae(ctx->i_ae, "--version");
@@ -659,12 +630,10 @@ do_gcc(cw_ictx_t *ctx)
* output is always discarded for the secondary
* compiler.
*/
- if ((ctx->i_flags & CW_F_SHADOW) && in_output) {
- ctx->i_discard = discard_file_name(arg);
+ if ((ctx->i_flags & CW_F_SHADOW) && in_output)
newae(ctx->i_ae, ctx->i_discard);
- } else {
+ else
newae(ctx->i_ae, arg);
- }
in_output = 0;
continue;
}
@@ -780,7 +749,6 @@ do_gcc(cw_ictx_t *ctx)
newae(ctx->i_ae, arg);
} else if (ctx->i_flags & CW_F_SHADOW) {
newae(ctx->i_ae, "-o");
- ctx->i_discard = discard_file_name(arg);
newae(ctx->i_ae, ctx->i_discard);
} else {
newae(ctx->i_ae, arg);
@@ -1219,16 +1187,8 @@ do_gcc(cw_ictx_t *ctx)
free(nameflag);
- /*
- * When compiling multiple source files in a single invocation some
- * compilers output objects into the current directory with
- * predictable and conventional names.
- *
- * We prevent any attempt to compile multiple files at once so that
- * any such objects created by a shadow can't escape into a later
- * link-edit.
- */
- if (c_files > 1 && op != CW_O_PREPROCESS) {
+ if (c_files > 1 && (ctx->i_flags & CW_F_SHADOW) &&
+ op != CW_O_PREPROCESS) {
errx(2, "multiple source files are "
"allowed only with -E or -P");
}
@@ -1296,19 +1256,15 @@ do_gcc(cw_ictx_t *ctx)
exit(2);
}
- if (ctx->i_flags & CW_F_SHADOW) {
- if (op == CW_O_PREPROCESS)
- exit(0);
- else if (op == CW_O_LINK && c_files == 0)
- exit(0);
- }
+ if ((op == CW_O_LINK || op == CW_O_PREPROCESS) &&
+ (ctx->i_flags & CW_F_SHADOW))
+ exit(0);
if (model != NULL)
newae(ctx->i_ae, model);
if (!nolibc)
newae(ctx->i_ae, "-lc");
if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
- ctx->i_discard = discard_file_name(NULL);
newae(ctx->i_ae, "-o");
newae(ctx->i_ae, ctx->i_discard);
}
@@ -1317,7 +1273,7 @@ do_gcc(cw_ictx_t *ctx)
static void
do_cc(cw_ictx_t *ctx)
{
- int in_output = 0, seen_o = 0, c_files = 0;
+ int in_output = 0, seen_o = 0;
cw_op_t op = CW_O_LINK;
char *nameflag;
@@ -1331,7 +1287,6 @@ do_cc(cw_ictx_t *ctx)
while (--ctx->i_oldargc > 0) {
char *arg = *++ctx->i_oldargv;
- size_t arglen = strlen(arg);
if (strncmp(arg, "-_CC=", 5) == 0) {
newae(ctx->i_ae, strchr(arg, '=') + 1);
@@ -1339,17 +1294,10 @@ do_cc(cw_ictx_t *ctx)
}
if (*arg != '-') {
- if (!in_output && arglen > 2 &&
- arg[arglen - 2] == '.' &&
- (arg[arglen - 1] == 'S' || arg[arglen - 1] == 's' ||
- arg[arglen - 1] == 'c' || arg[arglen - 1] == 'i'))
- c_files++;
-
if (in_output == 0 || !(ctx->i_flags & CW_F_SHADOW)) {
newae(ctx->i_ae, arg);
} else {
in_output = 0;
- ctx->i_discard = discard_file_name(arg);
newae(ctx->i_ae, ctx->i_discard);
}
continue;
@@ -1374,7 +1322,6 @@ do_cc(cw_ictx_t *ctx)
newae(ctx->i_ae, arg);
} else if (ctx->i_flags & CW_F_SHADOW) {
newae(ctx->i_ae, "-o");
- ctx->i_discard = discard_file_name(arg);
newae(ctx->i_ae, ctx->i_discard);
} else {
newae(ctx->i_ae, arg);
@@ -1398,22 +1345,12 @@ do_cc(cw_ictx_t *ctx)
free(nameflag);
- /* See the comment on this same code in do_gcc() */
- if (c_files > 1 && op != CW_O_PREPROCESS) {
- errx(2, "multiple source files are "
- "allowed only with -E or -P");
- }
-
- if (ctx->i_flags & CW_F_SHADOW) {
- if (op == CW_O_PREPROCESS)
- exit(0);
- else if (op == CW_O_LINK && c_files == 0)
- exit(0);
- }
+ if ((op == CW_O_LINK || op == CW_O_PREPROCESS) &&
+ (ctx->i_flags & CW_F_SHADOW))
+ exit(0);
if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
newae(ctx->i_ae, "-o");
- ctx->i_discard = discard_file_name(NULL);
newae(ctx->i_ae, ctx->i_discard);
}
}
@@ -1523,7 +1460,6 @@ reap(cw_ictx_t *ctx)
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
(void) unlink(ctx->i_discard);
- free(ctx->i_discard);
if (stat(ctx->i_stderr, &s) < 0) {
warn("stat failed on child cleanup");
@@ -1554,6 +1490,20 @@ reap(cw_ictx_t *ctx)
static int
exec_ctx(cw_ictx_t *ctx, int block)
{
+ char *file;
+
+ /*
+ * To avoid offending cc's sensibilities, the name of its output
+ * file must end in '.o'.
+ */
+ if ((file = tempnam(NULL, ".cw")) == NULL) {
+ nomem();
+ return (-1);
+ }
+ (void) strlcpy(ctx->i_discard, file, MAXPATHLEN);
+ (void) strlcat(ctx->i_discard, ".o", MAXPATHLEN);
+ free(file);
+
if ((ctx->i_stderr = tempnam(NULL, ".cw")) == NULL) {
nomem();
return (-1);
diff --git a/usr/src/tools/env/illumos.sh b/usr/src/tools/env/illumos.sh
index 51c2a458c1..a47b711347 100644
--- a/usr/src/tools/env/illumos.sh
+++ b/usr/src/tools/env/illumos.sh
@@ -23,14 +23,18 @@
# Copyright 2012 Joshua M. Clulow <josh@sysmgr.org>
# Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
+# Copyright (c) 2018, Joyent, Inc.
#
+# - This file is sourced by "bldenv.sh" and "nightly.sh" and should not
+# be executed directly.
+# - This script is only interpreted by ksh93 and explicitly allows the
+# use of ksh93 language extensions.
+
+
+# -----------------------------------------------------------------------------
+# Parameters you are likely to want to change
+# -----------------------------------------------------------------------------
-# Configuration variables for the runtime environment of the nightly
-# build script and other tools for construction and packaging of
-# releases.
-# This example is suitable for building an illumos workspace, which
-# will contain the resulting archives. It is based off the onnv
-# release. It sets NIGHTLY_OPTIONS to make nightly do:
# DEBUG build only (-D, -F)
# do not bringover from the parent (-n)
# runs 'make check' (-C)
@@ -39,18 +43,83 @@
# creates packages for PIT/RE (-p)
# checks for changes in ELF runpaths (-r)
# build and use this workspace's tools in $SRC/tools (-t)
-#
-# - This file is sourced by "bldenv.sh" and "nightly.sh" and should not
-# be executed directly.
-# - This script is only interpreted by ksh93 and explicitly allows the
-# use of ksh93 language extensions.
-#
export NIGHTLY_OPTIONS='-FnCDAmprt'
+# Some scripts optionally send mail messages to MAILTO.
+#export MAILTO=
+
# CODEMGR_WS - where is your workspace at
-#export CODEMGR_WS="$HOME/ws/illumos-gate"
export CODEMGR_WS="`git rev-parse --show-toplevel`"
+# Compilers may be specified using the following variables:
+# PRIMARY_CC - primary C compiler
+# PRIMARY_CCC - primary C++ compiler
+#
+# SHADOW_CCS - list of shadow C compilers
+# SHADOW_CCCS - list of shadow C++ compilers
+#
+# Each entry has the form <name>,<path to binary>,<style> where name is a
+# free-form name (possibly used in the makefiles to guard options), path is
+# the path to the executable. style is the 'style' of command line taken by
+# the compiler, currently either gnu (or gcc) or sun (or cc), which is also
+# used by Makefiles to guard options.
+#
+# __SUNC and __GNUC must still be set to reflect the style of the primary
+# compiler (and to influence the default primary, otherwise)
+#
+# for example:
+# export PRIMARY_CC=gcc4,/opt/gcc/4.4.4/bin/gcc,gnu
+# export PRIMARY_CCC=gcc4,/opt/gcc/4.4.4/bin/g++,gnu
+# export SHADOW_CCS=studio12,/opt/SUNWspro/bin/cc,sun
+# export SHADOW_CCCS=studio12,/opt/SUNWspro/bin/CC,sun
+#
+# There can be several space-separated entries in SHADOW_* to run multiple
+# shadow compilers.
+#
+# To disable shadow compilation, unset SHADOW_* or set them to the empty string.
+#
+export SHADOW_CCS=gcc7,/usr/gcc/7/bin/gcc,gnu
+export SHADOW_CCCS=gcc7,/usr/gcc/7/bin/g++,gnu
+
+# Comment this out to disable support for SMB printing, i.e. if you
+# don't want to bother providing the CUPS headers this needs.
+export ENABLE_SMB_PRINTING=
+
+# If your distro uses certain versions of Perl, make sure either Makefile.master
+# contains your new defaults OR your .env file sets them.
+# These are how you would override for building on OmniOS r151028, for example.
+#export PERL_VERSION=5.28
+#export PERL_ARCH=i86pc-solaris-thread-multi-64int
+#export PERL_PKGVERS=
+
+# If your distro uses certain versions of Python, make sure either
+# Makefile.master contains your new defaults OR your .env file sets them.
+#export PYTHON_VERSION=2.7
+#export PYTHON_PKGVERS=-27
+#export PYTHON_SUFFIX=
+#export PYTHON3_VERSION=3.5
+#export PYTHON3_PKGVERS=-35
+#export PYTHON3_SUFFIX=m
+
+# To disable building with either Python2 or Python 3 (or both), uncomment
+# these lines:
+#export BUILDPY2='#'
+#export BUILDPY3='#'
+
+# Set if your distribution has different package versioning
+#export PKGVERS_BRANCH=2018.0.0.17900
+
+# Skip Java 8 builds on distributions that don't support it
+#export BLD_JAVA_8=
+
+# POST_NIGHTLY can be any command to be run at the end of nightly. See
+# nightly(1) for interactions between environment variables and this command.
+#POST_NIGHTLY=
+
+# -----------------------------------------------------------------------------
+# You are less likely to need to modify parameters below.
+# -----------------------------------------------------------------------------
+
# Maximum number of dmake jobs. The recommended number is 2 + NCPUS,
# where NCPUS is the number of logical CPUs on your build system.
function maxjobs
@@ -98,16 +167,14 @@ ONBLD_BIN='/opt/onbld/bin'
export PARENT_WS=''
# CLONE_WS is the workspace nightly should do a bringover from.
+# The bringover, if any, is done as STAFFER.
export CLONE_WS='ssh://anonhg@hg.illumos.org/illumos-gate'
-# The bringover, if any, is done as STAFFER.
# Set STAFFER to your own login as gatekeeper or developer
# The point is to use group "staff" and avoid referencing the parent
# workspace as root.
-# Some scripts optionally send mail messages to MAILTO.
-#
export STAFFER="$LOGNAME"
-export MAILTO="$STAFFER"
+export MAILTO="${MAILTO:-$STAFFER}"
# If you wish the mail messages to be From: an arbitrary address, export
# MAILFROM.
@@ -196,36 +263,6 @@ export BUILD_TOOLS='/opt'
export SPRO_ROOT='/opt/SUNWspro'
export SPRO_VROOT="$SPRO_ROOT"
-# Compilers may be specified using the following variables:
-# PRIMARY_CC - primary C compiler
-# PRIMARY_CCC - primary C++ compiler
-#
-# SHADOW_CCS - list of shadow C compilers
-# SHADOW_CCCS - list of shadow C++ compilers
-#
-# Each entry has the form <name>,<path to binary>,<style> where name is a
-# free-form name (possibly used in the makefiles to guard options), path is
-# the path to the executable. style is the 'style' of command line taken by
-# the compiler, currently either gnu (or gcc) or sun (or cc), which is also
-# used by Makefiles to guard options.
-#
-# __SUNC and __GNUC must still be set to reflect the style of the primary
-# compiler (and to influence the default primary, otherwise)
-#
-# for example:
-# export PRIMARY_CC=gcc4,/opt/gcc/4.4.4/bin/gcc,gnu
-# export PRIMARY_CCC=gcc4,/opt/gcc/4.4.4/bin/g++,gnu
-# export SHADOW_CCS=studio12,/opt/SUNWspro/bin/cc,sun
-# export SHADOW_CCCS=studio12,/opt/SUNWspro/bin/CC,sun
-#
-# There can be several space-separated entries in SHADOW_* to run multiple
-# shadow compilers.
-#
-# To disable shadow compilation, unset SHADOW_* or set them to the empty string.
-#
-export SHADOW_CCS=gcc7,/usr/gcc/7/bin/gcc,gnu
-export SHADOW_CCCS=gcc7,/usr/gcc/7/bin/g++,gnu
-
# This goes along with lint - it is a series of the form "A [y|n]" which
# means "go to directory A and run 'make lint'" Then mail me (y) the
# difference in the lint output. 'y' should only be used if the area you're
@@ -237,37 +274,8 @@ export SHADOW_CCCS=gcc7,/usr/gcc/7/bin/g++,gnu
# if the 'N' option is not specified, is to run this test.
#CHECK_PATHS='y'
-# POST_NIGHTLY can be any command to be run at the end of nightly. See
-# nightly(1) for interactions between environment variables and this command.
-#POST_NIGHTLY=
-
-# Comment this out to disable support for SMB printing, i.e. if you
-# don't want to bother providing the CUPS headers this needs.
-export ENABLE_SMB_PRINTING=
-
-# If your distro uses certain versions of Perl, make sure either Makefile.master
-# contains your new defaults OR your .env file sets them.
-# These are how you would override for building on OmniOS r151028, for example.
-#export PERL_VERSION=5.28
-#export PERL_ARCH=i86pc-solaris-thread-multi-64int
-#export PERL_PKGVERS=-5161
-
#
# These checks ensure that if we accidentally run a program linked against the
# proto area, that we then fail the build.
#
export LD_TOXIC_PATH="$ROOT/lib:$ROOT/usr/lib"
-
-# If your distro uses certain versions of Python, make sure either
-# Makefile.master contains your new defaults OR your .env file sets them.
-#export PYTHON_VERSION=2.7
-#export PYTHON_PKGVERS=-27
-#export PYTHON_SUFFIX=
-#export PYTHON3_VERSION=3.5
-#export PYTHON3_PKGVERS=-35
-#export PYTHON3_SUFFIX=m
-
-# To disable building with either Python2 or Python 3 (or both), uncomment
-# these lines:
-#export BUILDPY2='#'
-#export BUILDPY3='#'
diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c
index dcfaf2902a..92ec682e29 100644
--- a/usr/src/uts/common/fs/zfs/spa.c
+++ b/usr/src/uts/common/fs/zfs/spa.c
@@ -4600,12 +4600,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));
}
@@ -4613,9 +4619,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))) {
@@ -4625,6 +4634,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/usr/src/uts/common/fs/zfs/spa_config.c b/usr/src/uts/common/fs/zfs/spa_config.c
index 7d568ffcf8..ad61dd0723 100644
--- a/usr/src/uts/common/fs/zfs/spa_config.c
+++ b/usr/src/uts/common/fs/zfs/spa_config.c
@@ -208,6 +208,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));
@@ -254,7 +255,14 @@ 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);
}
@@ -359,6 +367,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;
@@ -375,10 +384,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/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
index 3f3798c1c7..fa9d7028c2 100644
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
@@ -1496,6 +1496,7 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
nvlist_t *config, *props = NULL;
nvlist_t *rootprops = NULL;
nvlist_t *zplprops = NULL;
+ char *spa_name = zc->zc_name;
if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
zc->zc_iflags, &config))
@@ -1511,6 +1512,7 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
if (props) {
nvlist_t *nvl = NULL;
uint64_t version = SPA_VERSION;
+ char *tname;
(void) nvlist_lookup_uint64(props,
zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
@@ -1533,6 +1535,10 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
zplprops, NULL);
if (error != 0)
goto pool_props_bad;
+
+ if (nvlist_lookup_string(props,
+ zpool_prop_to_name(ZPOOL_PROP_TNAME), &tname) == 0)
+ spa_name = tname;
}
error = spa_create(zc->zc_name, config, props, zplprops);
@@ -1540,9 +1546,9 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
/*
* Set the remaining root properties
*/
- if (!error && (error = zfs_set_prop_nvlist(zc->zc_name,
+ if (!error && (error = zfs_set_prop_nvlist(spa_name,
ZPROP_SRC_LOCAL, rootprops, NULL)) != 0)
- (void) spa_destroy(zc->zc_name);
+ (void) spa_destroy(spa_name);
pool_props_bad:
nvlist_free(rootprops);
diff --git a/usr/src/uts/common/sys/fs/zfs.h b/usr/src/uts/common/sys/fs/zfs.h
index f85062f66b..4c26edaecd 100644
--- a/usr/src/uts/common/sys/fs/zfs.h
+++ b/usr/src/uts/common/sys/fs/zfs.h
@@ -210,6 +210,7 @@ typedef enum {
ZPOOL_PROP_MAXBLOCKSIZE,
ZPOOL_PROP_BOOTSIZE,
ZPOOL_PROP_CHECKPOINT,
+ ZPOOL_PROP_TNAME,
ZPOOL_NUM_PROPS
} zpool_prop_t;
@@ -855,7 +856,7 @@ typedef struct vdev_stat {
* is passed between kernel and userland as an nvlist uint64 array.
*/
typedef struct ddt_object {
- uint64_t ddo_count; /* number of elments in ddt */
+ uint64_t ddo_count; /* number of elments in ddt */
uint64_t ddo_dspace; /* size of ddt on disk */
uint64_t ddo_mspace; /* size of ddt in-core */
} ddt_object_t;
@@ -1061,6 +1062,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.