aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris/lib
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib/opensolaris/lib')
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h10
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c30
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c88
-rw-r--r--cddl/contrib/opensolaris/lib/libzpool/common/util.c23
4 files changed, 130 insertions, 21 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index 9e022cf896a0..a1344f324729 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -260,6 +260,7 @@ typedef struct splitflags {
/* after splitting, import the pool */
int import : 1;
+ int name_flags;
} splitflags_t;
/*
@@ -428,8 +429,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/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
index cdf20b8543fd..e0728e3b6285 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
@@ -1186,6 +1186,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:
{
#ifdef illumos
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
index 3800001992b6..c2dac2362f10 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
+++ b/cddl/contrib/opensolaris/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 <sys/types.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);
}
@@ -2892,7 +2928,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);
/*
@@ -3093,11 +3129,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);
@@ -3685,9 +3721,9 @@ 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;
@@ -3695,6 +3731,21 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
int have_stats;
int have_path;
+ 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;
+
have_stats = nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
(uint64_t **)&vs, &vsc) == 0;
have_path = nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0;
@@ -3704,11 +3755,10 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
* come back at the same device path. Display the device by GUID.
*/
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 ||
+ (name_flags & VDEV_NAME_GUID) != 0 ||
have_path && have_stats && vs->vs_state <= VDEV_STATE_CANT_OPEN) {
- verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
- &value) == 0);
- (void) snprintf(buf, sizeof (buf), "%llu",
- (u_longlong_t)value);
+ nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value);
+ (void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value);
path = buf;
} else if (have_path) {
@@ -3750,11 +3800,23 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
}
#ifdef illumos
+ 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);
@@ -3798,7 +3860,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,
diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/util.c b/cddl/contrib/opensolaris/lib/libzpool/common/util.c
index 71894c2af290..d2ed31a46832 100644
--- a/cddl/contrib/opensolaris/lib/libzpool/common/util.c
+++ b/cddl/contrib/opensolaris/lib/libzpool/common/util.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2017, Intel Corporation.
*/
#include <assert.h>
@@ -49,7 +50,6 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
uint_t c, children;
char used[6], avail[6];
char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6];
- char *prefix = "";
if (indent == 0 && desc != NULL) {
(void) printf(" "
@@ -59,15 +59,24 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
}
if (desc != NULL) {
- (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
-
- if (is_log)
- prefix = "log ";
+ char *suffix = "", *bias = NULL;
+ char bias_suffix[32];
+ (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
+ (void) nvlist_lookup_string(nv, ZPOOL_CONFIG_ALLOCATION_BIAS,
+ &bias);
if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
(uint64_t **)&vs, &c) != 0)
vs = &v0;
+ if (bias != NULL) {
+ (void) snprintf(bias_suffix, sizeof (bias_suffix),
+ " (%s)", bias);
+ suffix = bias_suffix;
+ } else if (is_log) {
+ suffix = " (log)";
+ }
+
sec = MAX(1, vs->vs_timestamp / NANOSEC);
nicenum(vs->vs_alloc, used, sizeof (used));
@@ -84,9 +93,9 @@ show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
(void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
indent, "",
- prefix,
- (int)(indent + strlen(prefix) - 25 - (vs->vs_space ? 0 : 12)),
desc,
+ (int)(indent+strlen(desc)-25-(vs->vs_space ? 0 : 12)),
+ suffix,
vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
rops, wops, rbytes, wbytes, rerr, werr, cerr);