#include "zfeature_common.h"
static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
+static boolean_t zpool_vdev_is_interior(const char *name);
typedef struct prop_flags {
int create:1; /* Validate property on creation */
return (0);
}
-static char *
+static const char *
zpool_get_prop_string(zpool_handle_t *zhp, zpool_prop_t prop,
zprop_source_t *src)
{
/*
* Map VDEV STATE to printed strings.
*/
-char *
+const char *
zpool_state_to_name(vdev_state_t state, vdev_aux_t aux)
{
switch (state) {
bootfs_name_valid(const char *pool, char *bootfs)
{
int len = strlen(pool);
+ if (bootfs[0] == '\0')
+ return (B_TRUE);
if (!zfs_name_valid(bootfs, ZFS_TYPE_FILESYSTEM|ZFS_TYPE_SNAPSHOT))
return (B_FALSE);
const char *propname = nvpair_name(elem);
prop = zpool_name_to_prop(propname);
- if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
+ if (prop == ZPOOL_PROP_INVAL && zpool_prop_feature(propname)) {
int err;
char *fname = strchr(propname, '@') + 1;
goto error;
}
+ if (!flags.create &&
+ strcmp(strval, ZFS_FEATURE_DISABLED) == 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' can only be set to "
+ "'disabled' at creation time"), propname);
+ (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
+
if (nvlist_add_uint64(retprops, propname, 0) != 0) {
(void) no_memory(hdl);
goto error;
/*
* Make sure this property is valid and applies to this type.
*/
- if (prop == ZPROP_INVAL) {
+ if (prop == ZPOOL_PROP_INVAL) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid property '%s'"), propname);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
* bootfs property value has to be a dataset name and
* the dataset has to be in the same pool as it sets to.
*/
- if (strval[0] != '\0' && !bootfs_name_valid(poolname,
- strval)) {
+ if (!bootfs_name_valid(poolname, strval)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
"is an invalid name"), strval);
(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
break;
}
- verify(strncmp(type, VDEV_TYPE_RAIDZ,
- strlen(VDEV_TYPE_RAIDZ)) == 0 ||
- strncmp(type, VDEV_TYPE_MIRROR,
- strlen(VDEV_TYPE_MIRROR)) == 0);
+ verify(zpool_vdev_is_interior(type));
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
&id) == 0);
/*
* Determine if we have an "interior" top-level vdev (i.e mirror/raidz).
*/
-boolean_t
+static boolean_t
zpool_vdev_is_interior(const char *name)
{
if (strncmp(name, VDEV_TYPE_RAIDZ, strlen(VDEV_TYPE_RAIDZ)) == 0 ||
+ strncmp(name, VDEV_TYPE_SPARE, strlen(VDEV_TYPE_SPARE)) == 0 ||
+ strncmp(name,
+ VDEV_TYPE_REPLACING, strlen(VDEV_TYPE_REPLACING)) == 0 ||
strncmp(name, VDEV_TYPE_MIRROR, strlen(VDEV_TYPE_MIRROR)) == 0)
return (B_TRUE);
return (B_FALSE);
{
zfs_cmd_t zc = {"\0"};
char msg[1024];
+ char *pathname;
nvlist_t *tgt;
boolean_t avail_spare, l2cache, islog;
libzfs_handle_t *hdl = zhp->zpool_hdl;
if (avail_spare)
return (zfs_error(hdl, EZFS_ISSPARE, msg));
- if (flags & ZFS_ONLINE_EXPAND ||
- zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) {
+ if ((flags & ZFS_ONLINE_EXPAND ||
+ zpool_get_prop_int(zhp, ZPOOL_PROP_AUTOEXPAND, NULL)) &&
+ nvlist_lookup_string(tgt, ZPOOL_CONFIG_PATH, &pathname) == 0) {
uint64_t wholedisk = 0;
(void) nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_WHOLE_DISK,
nvlist_t **varray = NULL, *zc_props = NULL;
uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
libzfs_handle_t *hdl = zhp->zpool_hdl;
- uint64_t vers;
+ uint64_t vers, readonly = B_FALSE;
boolean_t freelist = B_FALSE, memory_err = B_TRUE;
int retval = 0;
if ((zc_props = zpool_valid_proplist(hdl, zhp->zpool_name,
props, vers, flags, msg)) == NULL)
return (-1);
+ (void) nvlist_lookup_uint64(zc_props,
+ zpool_prop_to_name(ZPOOL_PROP_READONLY), &readonly);
+ if (readonly) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property %s can only be set at import time"),
+ zpool_prop_to_name(ZPOOL_PROP_READONLY));
+ return (-1);
+ }
}
if (nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
char buf[PATH_BUF_LEN];
char tmpbuf[PATH_BUF_LEN];
+ /*
+ * vdev_name will be "root"/"root-0" for the root vdev, but it is the
+ * zpool name that will be displayed to the user.
+ */
+ verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
+ if (zhp != NULL && strcmp(type, "root") == 0)
+ return (zfs_strdup(hdl, zpool_get_name(zhp)));
+
env = getenv("ZPOOL_VDEV_NAME_PATH");
if (env && (strtoul(env, NULL, 0) > 0 ||
!strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
/*
* For a block device only use the name.
*/
- verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
!(name_flags & VDEV_NAME_PATH)) {
path = strrchr(path, '/');
return (zfs_strip_partition(path));
}
} else {
- verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &path) == 0);
+ path = type;
/*
* If it's a raidz device, we need to stick in the parity level.