diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-12-18 12:56:14 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2018-12-18 12:56:14 +0000 |
| commit | 41550557750bcfd086b0339d512607e83759f1f1 (patch) | |
| tree | a786eb6e40c50846d36672be1c5c6f6b32498ff3 | |
| parent | f4cb444376b6efe8770e521115e58d5df2379c97 (diff) | |
| parent | 04e56356520b98d5a93c496b10f02530bb6647e0 (diff) | |
| download | illumos-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
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. |
