diff options
| author | Don Brady <don.brady@delphix.com> | 2019-04-12 15:10:57 +0000 |
|---|---|---|
| committer | Dan McDonald <danmcd@joyent.com> | 2019-04-13 00:31:22 -0400 |
| commit | 663207adb1669640c01c5ec6949ce78fd806efae (patch) | |
| tree | 16342a5e43b1009b87750b355927a34144204b4a /usr/src/lib/libzfs | |
| parent | 78a53e201c2691debc57ede24c524118299ab18c (diff) | |
| download | illumos-joyent-663207adb1669640c01c5ec6949ce78fd806efae.tar.gz | |
10601 Pool allocation classes
10757 Add -gLp to zpool subcommands for alt vdev names
Portions contributed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Portions contributed by: HÃ¥kan Johansson <f96hajo@chalmers.se>
Portions contributed by: Richard Yao <ryao@gentoo.org>
Portions contributed by: Chunwei Chen <david.chen@nutanix.com>
Portions contributed by: loli10K <ezomori.nozomu@gmail.com>
Reviewed by: Pavel Zakharov <pavel.zakharov@delphix.com>
Reviewed by: Richard Laager <rlaager@wiktel.com>
Reviewed by: Alek Pinchuk <apinchuk@datto.com>
Reviewed by: Andreas Dilger <andreas.dilger@chamcloud.com>
Reviewed by: DHE <git@dehacked.net>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Gregor Kopka <gregor@kopka.net>
Reviewed by: Kash Pande <kash@tripleback.net>
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Tony Hutter <hutter2@llnl.gov>
Reviewed by: George Melikov <mail@gmelikov.ru>
Reviewed by: Giuseppe Di Natale <guss80@gmail.com>
Reviewed by: bunder2015 <omfgbunder@gmail.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>
Reviewed by: Kody Kantor <kody.kantor@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib/libzfs')
| -rw-r--r-- | usr/src/lib/libzfs/common/libzfs.h | 10 | ||||
| -rw-r--r-- | usr/src/lib/libzfs/common/libzfs_dataset.c | 30 | ||||
| -rw-r--r-- | usr/src/lib/libzfs/common/libzfs_pool.c | 91 |
3 files changed, 115 insertions, 16 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h index ef26165d30..fa005259c2 100644 --- a/usr/src/lib/libzfs/common/libzfs.h +++ b/usr/src/lib/libzfs/common/libzfs.h @@ -258,6 +258,7 @@ typedef struct splitflags { /* after splitting, import the pool */ int import : 1; + int name_flags; } splitflags_t; /* @@ -425,8 +426,15 @@ struct zfs_cmd; extern const char *zfs_history_event_names[]; +typedef enum { + VDEV_NAME_PATH = 1 << 0, + VDEV_NAME_GUID = 1 << 1, + VDEV_NAME_FOLLOW_LINKS = 1 << 2, + VDEV_NAME_TYPE_ID = 1 << 3, +} vdev_name_t; + extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *, - boolean_t verbose); + int name_flags); extern int zpool_upgrade(zpool_handle_t *, uint64_t); extern int zpool_get_history(zpool_handle_t *, nvlist_t **); extern int zpool_history_unpack(char *, uint64_t, uint64_t *, diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index f27322b694..662e207eea 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -1173,6 +1173,36 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, } break; } + + case ZFS_PROP_SPECIAL_SMALL_BLOCKS: + if (zpool_hdl != NULL) { + char state[64] = ""; + + /* + * Issue a warning but do not fail so that + * tests for setable properties succeed. + */ + if (zpool_prop_get_feature(zpool_hdl, + "feature@allocation_classes", state, + sizeof (state)) != 0 || + strcmp(state, ZFS_FEATURE_ACTIVE) != 0) { + (void) fprintf(stderr, gettext( + "%s: property requires a special " + "device in the pool\n"), propname); + } + } + if (intval != 0 && + (intval < SPA_MINBLOCKSIZE || + intval > SPA_OLD_MAXBLOCKSIZE || !ISP2(intval))) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "invalid '%s=%d' property: must be zero or " + "a power of 2 from 512B to 128K"), propname, + intval); + (void) zfs_error(hdl, EZFS_BADPROP, errbuf); + goto error; + } + break; + case ZFS_PROP_MLSLABEL: { /* diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index b749022bf7..2a538a974a 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -26,6 +26,7 @@ * Copyright 2016 Nexenta Systems, Inc. * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com> * Copyright (c) 2017 Datto Inc. + * Copyright (c) 2017, Intel Corporation. */ #include <ctype.h> @@ -1126,6 +1127,30 @@ zpool_get_state(zpool_handle_t *zhp) } /* + * Check if vdev list contains a special vdev + */ +static boolean_t +zpool_has_special_vdev(nvlist_t *nvroot) +{ + nvlist_t **child; + uint_t children; + + if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &child, + &children) == 0) { + for (uint_t c = 0; c < children; c++) { + char *bias; + + if (nvlist_lookup_string(child[c], + ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0 && + strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0) { + return (B_TRUE); + } + } + } + return (B_FALSE); +} + +/* * Create the named pool, using the provided vdev list. It is assumed * that the consumer has already validated the contents of the nvlist, so we * don't have to worry about error semantics. @@ -1170,6 +1195,17 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot, fsprops, zoned, NULL, NULL, msg)) == NULL) { goto create_failed; } + + if (nvlist_exists(zc_fsprops, + zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)) && + !zpool_has_special_vdev(nvroot)) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "%s property requires a special vdev"), + zfs_prop_to_name(ZFS_PROP_SPECIAL_SMALL_BLOCKS)); + (void) zfs_error(hdl, EZFS_BADPROP, msg); + goto create_failed; + } + if (!zc_props && (nvlist_alloc(&zc_props, NV_UNIQUE_NAME, 0) != 0)) { goto create_failed; @@ -1694,7 +1730,7 @@ print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv, return; for (c = 0; c < children; c++) { - vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE); + vname = zpool_vdev_name(hdl, NULL, child[c], VDEV_NAME_TYPE_ID); print_vdev_tree(hdl, vname, child[c], indent + 2); free(vname); } @@ -2885,7 +2921,7 @@ zpool_vdev_attach(zpool_handle_t *zhp, verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL), ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0); - if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL) + if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL) return (-1); /* @@ -3076,11 +3112,11 @@ find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren, for (mc = 0; mc < mchildren; mc++) { uint_t sc; char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp, - mchild[mc], B_FALSE); + mchild[mc], 0); for (sc = 0; sc < schildren; sc++) { char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp, - schild[sc], B_FALSE); + schild[sc], 0); boolean_t result = (strcmp(mpath, spath) == 0); free(spath); @@ -3671,20 +3707,33 @@ set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path) */ char * zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv, - boolean_t verbose) + int name_flags) { - char *path, *devid; + char *path, *devid, *env; uint64_t value; char buf[64]; vdev_stat_t *vs; uint_t vsc; - if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, - &value) == 0) { - verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, - &value) == 0); - (void) snprintf(buf, sizeof (buf), "%llu", - (u_longlong_t)value); + env = getenv("ZPOOL_VDEV_NAME_PATH"); + if (env && (strtoul(env, NULL, 0) > 0 || + !strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2))) + name_flags |= VDEV_NAME_PATH; + + env = getenv("ZPOOL_VDEV_NAME_GUID"); + if (env && (strtoul(env, NULL, 0) > 0 || + !strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2))) + name_flags |= VDEV_NAME_GUID; + + env = getenv("ZPOOL_VDEV_NAME_FOLLOW_LINKS"); + if (env && (strtoul(env, NULL, 0) > 0 || + !strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2))) + name_flags |= VDEV_NAME_FOLLOW_LINKS; + + if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 || + name_flags & VDEV_NAME_GUID) { + nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value); + (void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value); path = buf; } else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) { @@ -3726,11 +3775,23 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv, devid_str_free(newdevid); } + if (name_flags & VDEV_NAME_FOLLOW_LINKS) { + char *rp = realpath(path, NULL); + if (rp) { + strlcpy(buf, rp, sizeof (buf)); + path = buf; + free(rp); + } + } + if (strncmp(path, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0) path += strlen(ZFS_DISK_ROOTD); - if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, - &value) == 0 && value) { + /* + * Remove the partition from the path it this is a whole disk. + */ + if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value) + == 0 && value && !(name_flags & VDEV_NAME_PATH)) { int pathlen = strlen(path); char *tmp = zfs_strdup(hdl, path); @@ -3770,7 +3831,7 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv, * We identify each top-level vdev by using a <type-id> * naming convention. */ - if (verbose) { + if (name_flags & VDEV_NAME_TYPE_ID) { uint64_t id; verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID, |
