Skip to content

Commit

Permalink
Rename "noalloc" vdev property to "allocating"
Browse files Browse the repository at this point in the history
Add support for read-only "removing" vdev property
Simplify get vdev prop interface to always require pool name
Refactor space management for non-allocating devices
Add ability to remove user vdev property by setting value to ""
  • Loading branch information
mmaybee authored and allanjude committed Jun 8, 2021
1 parent 2debf5f commit 72d3020
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 111 deletions.
4 changes: 1 addition & 3 deletions cmd/zhack/zhack.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,6 @@ static int
zhack_do_zap(int argc, char **argv)
{
spa_t *spa;
objset_t *os;
uint64_t obj;
char *target;

Expand All @@ -493,9 +492,8 @@ zhack_do_zap(int argc, char **argv)
obj = strtoull(argv[1], NULL, 0);

zhack_spa_open(target, B_TRUE, FTAG, &spa);
os = spa->spa_meta_objset;

dump_obj(os, obj, argv[1]);
dump_obj(spa->spa_meta_objset, obj, argv[1]);

spa_close(spa, FTAG);

Expand Down
5 changes: 3 additions & 2 deletions cmd/zpool/zpool_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,9 @@ for_each_vdev_cb(zpool_handle_t *zhp, nvlist_t *nv, pool_vdev_iter_f func,
if (nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) != 0)
return (ret);

/* Don't run our function on root vdevs */
if (strcmp(type, VDEV_TYPE_ROOT) != 0) {
/* Don't run our function on root or indirect vdevs */
if ((strcmp(type, VDEV_TYPE_ROOT) != 0) &&
(strcmp(type, VDEV_TYPE_INDIRECT) != 0)) {
ret |= func(zhp, nv, data);
}

Expand Down
57 changes: 23 additions & 34 deletions cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ static zpool_command_t command_table[] = {
#define VDEV_ALLOC_CLASS_LOGS "logs"

static zpool_command_t *current_command;
static zfs_type_t current_prop_type = ZFS_TYPE_POOL;
static zfs_type_t current_prop_type = (ZFS_TYPE_POOL | ZFS_TYPE_VDEV);
static char history_str[HIS_MAX_RECORD_LEN];
static boolean_t log_history = B_TRUE;
static uint_t timestamp_fmt = NODATE;
Expand Down Expand Up @@ -488,7 +488,7 @@ print_prop_cb(int prop, void *cb)
}

/*
* Callback routine that will print out a pool property value.
* Callback routine that will print out a vdev property value.
*/
static int
print_vdev_prop_cb(int prop, void *cb)
Expand Down Expand Up @@ -540,6 +540,7 @@ usage(boolean_t requested)
}

if (current_command != NULL &&
current_prop_type != (ZFS_TYPE_POOL | ZFS_TYPE_VDEV) &&
((strcmp(current_command->name, "set") == 0) ||
(strcmp(current_command->name, "get") == 0) ||
(strcmp(current_command->name, "list") == 0))) {
Expand Down Expand Up @@ -826,7 +827,7 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props,
(!zpool_prop_feature(propname) ||
zpool_prop_vdev(propname))) {
(void) fprintf(stderr, gettext("property '%s' is "
"not a valid pool property\n"), propname);
"not a valid pool or vdev property\n"), propname);
return (2);
}

Expand Down Expand Up @@ -9886,6 +9887,7 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data)
zprop_list_t *pl;

for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
char *prop_name;
/*
* Skip the special fake placeholder. This will also skip
* over the name property when 'all' is specified.
Expand All @@ -9896,21 +9898,14 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data)

if (pl->pl_prop == ZPROP_INVAL) {
/* User Properties */
if (zpool_get_vdev_prop(zhp, vdevname, pl->pl_prop,
pl->pl_user_prop, value, sizeof (value), &srctype,
cbp->cb_literal) == 0) {
zprop_print_one_property(
vdevname, cbp, pl->pl_user_prop, value,
srctype, NULL, NULL);
}
prop_name = pl->pl_user_prop;
} else {
if (zpool_get_vdev_prop(zhp, vdevname, pl->pl_prop,
NULL, value, sizeof (value), &srctype,
cbp->cb_literal) != 0)
continue;

zprop_print_one_property(
vdevname, cbp, vdev_prop_to_name(pl->pl_prop),
prop_name = (char *)vdev_prop_to_name(pl->pl_prop);
}
if (zpool_get_vdev_prop(zhp, vdevname, pl->pl_prop,
prop_name, value, sizeof (value), &srctype,
cbp->cb_literal) == 0) {
zprop_print_one_property(vdevname, cbp, prop_name,
value, srctype, NULL, NULL);
}
}
Expand Down Expand Up @@ -9956,20 +9951,20 @@ get_callback(zpool_handle_t *zhp, void *data)
int vid;

if (cbp->cb_type == ZFS_TYPE_VDEV) {
if (strcmp(cbp->cb_vdevs.cb_names[0], "all") == 0) {
if (strcmp(cbp->cb_vdevs.cb_names[0], "all-vdevs") == 0) {
for_each_vdev(zhp, get_callback_vdev_width_cb, data);
for_each_vdev(zhp, get_callback_vdev_cb, data);
} else {
/* Adjust column widths for vdev properties */
for (vid = 0; vid < cbp->cb_vdevs.cb_names_count;
vid++) {
/* Adjust column widths for vdev properties */
vdev_expand_proplist(zhp,
cbp->cb_vdevs.cb_names[vid],
&cbp->cb_proplist);
}
/* Display the properties */
for (vid = 0; vid < cbp->cb_vdevs.cb_names_count;
vid++) {
/* Display the properties */
get_callback_vdev(zhp,
cbp->cb_vdevs.cb_names[vid], data);
}
Expand Down Expand Up @@ -10133,24 +10128,18 @@ zpool_do_get(int argc, char **argv)
/* No args, so just print the defaults. */
} else if (are_all_pools(argc, argv)) {
/* All the args are pool names */
} else if (are_vdevs_in_pool(argc, argv, NULL, &cb.cb_vdevs)) {
/* All the args are vdevs */
cb.cb_vdevs.cb_names = argv;
cb.cb_vdevs.cb_names_count = argc;
cb.cb_type = ZFS_TYPE_VDEV;
argc = 0; /* No pools to process */
} else if (are_all_pools(1, argv)) {
/* The first arg is a pool name */
if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0],
&cb.cb_vdevs) || (strcmp(argv[1], "all") == 0)) {
/* ...and the rest are vdev names */
if ((argc == 2 && strcmp(argv[1], "all-vdevs") == 0) ||
are_vdevs_in_pool(argc - 1, argv + 1, argv[0],
&cb.cb_vdevs)) {
/* ... and the rest are vdev names */
cb.cb_vdevs.cb_names = argv + 1;
cb.cb_vdevs.cb_names_count = argc - 1;
cb.cb_type = ZFS_TYPE_VDEV;
argc = 1; /* One pool to process */
} else {
fprintf(stderr, gettext("Expected either a list of "));
fprintf(stderr, gettext("pools, or list of vdevs in"));
fprintf(stderr, gettext("Expected a list of vdevs in"));
fprintf(stderr, " \"%s\", ", argv[0]);
fprintf(stderr, gettext("but got:\n"));
error_list_unresolved_vdevs(argc - 1, argv + 1,
Expand All @@ -10161,11 +10150,11 @@ zpool_do_get(int argc, char **argv)
}
} else {
/*
* The args don't make sense. The first arg isn't a pool name,
* nor are all the args vdevs.
* The first arg isn't a pool name,
*/
fprintf(stderr, gettext("Unable to parse pools/vdevs list.\n"));
fprintf(stderr, gettext("missing pool name.\n"));
fprintf(stderr, "\n");
usage(B_FALSE);
return (1);
}

Expand Down
13 changes: 7 additions & 6 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,8 @@ typedef enum {
VDEV_PROP_BYTES_FREE,
VDEV_PROP_BYTES_CLAIM,
VDEV_PROP_BYTES_TRIM,
VDEV_PROP_NOALLOC,
VDEV_PROP_REMOVING,
VDEV_PROP_ALLOCATING,
VDEV_NUM_PROPS
} vdev_prop_t;

Expand Down Expand Up @@ -1152,7 +1153,6 @@ typedef struct vdev_stat {
uint64_t vs_checksum_errors; /* checksum errors */
uint64_t vs_initialize_errors; /* initializing errors */
uint64_t vs_self_healed; /* self-healed bytes */
uint64_t vs_noalloc; /* allocations halted? */
uint64_t vs_scan_removing; /* removing? */
uint64_t vs_scan_processed; /* scan processed bytes */
uint64_t vs_fragmentation; /* device fragmentation */
Expand All @@ -1173,6 +1173,7 @@ typedef struct vdev_stat {
uint64_t vs_configured_ashift; /* TLV vdev_ashift */
uint64_t vs_logical_ashift; /* vdev_logical_ashift */
uint64_t vs_physical_ashift; /* vdev_physical_ashift */
uint64_t vs_noalloc; /* allocations halted? */
} vdev_stat_t;

/* BEGIN CSTYLED */
Expand Down Expand Up @@ -1577,14 +1578,14 @@ typedef enum {
/*
* The following are names used when invoking ZFS_IOC_VDEV_GET_PROP.
*/
#define ZPOOL_VDEV_GET_PROPS_VDEV "vdevprops_get_vdev"
#define ZPOOL_VDEV_GET_PROPS_PROPS "vdevprops_get_props"
#define ZPOOL_VDEV_PROPS_GET_VDEV "vdevprops_get_vdev"
#define ZPOOL_VDEV_PROPS_GET_PROPS "vdevprops_get_props"

/*
* The following are names used when invoking ZFS_IOC_VDEV_SET_PROP.
*/
#define ZPOOL_VDEV_SET_PROPS_VDEV "vdevprops_set_vdev"
#define ZPOOL_VDEV_SET_PROPS_PROPS "vdevprops_set_props"
#define ZPOOL_VDEV_PROPS_SET_VDEV "vdevprops_set_vdev"
#define ZPOOL_VDEV_PROPS_SET_PROPS "vdevprops_set_props"

/*
* The following are names used when invoking ZFS_IOC_WAIT_FS.
Expand Down
1 change: 1 addition & 0 deletions include/sys/spa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ struct spa {
uint64_t spa_missing_tvds; /* unopenable tvds on load */
uint64_t spa_missing_tvds_allowed; /* allow loading spa? */

uint64_t spa_nonallocating_dspace;
spa_removing_phys_t spa_removing_phys;
spa_vdev_removal_t *spa_vdev_removal;

Expand Down
40 changes: 26 additions & 14 deletions lib/libzfs/libzfs_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -5074,8 +5074,8 @@ zpool_get_vdev_prop_value(nvlist_t *nvprop, vdev_prop_t prop, char *prop_name,
verify(nvlist_lookup_string(nv, ZPROP_VALUE,
&strval) == 0);
} else {
src = ZPROP_SRC_NONE;
strval = "-";
/* user prop not found */
return (-1);
}
(void) strlcpy(buf, strval, len);
if (srctype)
Expand Down Expand Up @@ -5230,7 +5230,8 @@ zpool_get_vdev_prop(zpool_handle_t *zhp, const char *vdevname, vdev_prop_t prop,
char *prop_name, char *buf, size_t len, zprop_source_t *srctype,
boolean_t literal)
{
nvlist_t *tgt, *reqnvl, *reqprops, *retprops;
nvlist_t *tgt, *reqnvl, *reqprops;
nvlist_t *retprops = NULL;
uint64_t vdev_guid;
boolean_t avail_spare, l2cache;
char errbuf[1024];
Expand All @@ -5244,8 +5245,12 @@ zpool_get_vdev_prop(zpool_handle_t *zhp, const char *vdevname, vdev_prop_t prop,
}

if ((tgt = zpool_find_vdev(zhp, vdevname, &avail_spare, &l2cache,
NULL)) == NULL)
return (-1);
NULL)) == NULL) {
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "can not find %s in %s"),
vdevname, zhp->zpool_name);
return (zfs_error(zhp->zpool_hdl, EZFS_NODEVICE, errbuf));
}

verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID, &vdev_guid) == 0);

Expand All @@ -5254,19 +5259,26 @@ zpool_get_vdev_prop(zpool_handle_t *zhp, const char *vdevname, vdev_prop_t prop,
if (nvlist_alloc(&reqprops, NV_UNIQUE_NAME, 0) != 0)
return (no_memory(zhp->zpool_hdl));

fnvlist_add_uint64(reqnvl, ZPOOL_VDEV_GET_PROPS_VDEV, vdev_guid);
fnvlist_add_uint64(reqnvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);

if (prop != VDEV_PROP_INVAL && prop_name == NULL)
prop_name = (char *)vdev_prop_to_name(prop);
if (prop != VDEV_PROP_INVAL) {
/* prop_name overrides prop value */
if (prop_name != NULL)
prop = vdev_name_to_prop(prop_name);
else
prop_name = (char *)vdev_prop_to_name(prop);
}

if (prop != VDEV_PROP_INVAL)
assert(prop < VDEV_NUM_PROPS);
assert(prop_name != NULL);
if (nvlist_add_uint64(reqprops, prop_name, prop) != 0) {
nvlist_free(reqnvl);
nvlist_free(reqprops);
return (no_memory(zhp->zpool_hdl));
}

fnvlist_add_nvlist(reqnvl, ZPOOL_VDEV_GET_PROPS_PROPS, reqprops);
fnvlist_add_nvlist(reqnvl, ZPOOL_VDEV_PROPS_GET_PROPS, reqprops);

(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "cannot get vdev property %s from %s in %s"),
Expand Down Expand Up @@ -5301,7 +5313,7 @@ zpool_get_all_vdev_props(zpool_handle_t *zhp, const char *vdevname,
uint64_t vdev_guid;
boolean_t avail_spare, l2cache;
char errbuf[1024];
int ret = -1;
int ret;

verify(zhp != NULL);
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
Expand All @@ -5323,7 +5335,7 @@ zpool_get_all_vdev_props(zpool_handle_t *zhp, const char *vdevname,
if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
return (no_memory(zhp->zpool_hdl));

fnvlist_add_uint64(nvl, ZPOOL_VDEV_GET_PROPS_VDEV, vdev_guid);
fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_GET_VDEV, vdev_guid);

ret = lzc_get_vdev_prop(zhp->zpool_name, nvl, outnvl);

Expand All @@ -5343,7 +5355,7 @@ int
zpool_set_vdev_prop(zpool_handle_t *zhp, const char *vdevname,
const char *propname, const char *propval)
{
int ret = -1;
int ret;
char errbuf[1024];
vdev_prop_t vprop;
nvlist_t *nvl = NULL;
Expand Down Expand Up @@ -5380,7 +5392,7 @@ zpool_set_vdev_prop(zpool_handle_t *zhp, const char *vdevname,
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
return (no_memory(zhp->zpool_hdl));

fnvlist_add_uint64(nvl, ZPOOL_VDEV_SET_PROPS_VDEV, vdev_guid);
fnvlist_add_uint64(nvl, ZPOOL_VDEV_PROPS_SET_VDEV, vdev_guid);

if (nvlist_add_string(props, propname, propval) != 0) {
nvlist_free(props);
Expand All @@ -5399,7 +5411,7 @@ zpool_set_vdev_prop(zpool_handle_t *zhp, const char *vdevname,
nvlist_free(props);
props = realprops;

fnvlist_add_nvlist(nvl, ZPOOL_VDEV_SET_PROPS_PROPS, props);
fnvlist_add_nvlist(nvl, ZPOOL_VDEV_PROPS_SET_PROPS, props);

ret = lzc_set_vdev_prop(zhp->zpool_name, nvl, &outnvl);

Expand Down
13 changes: 7 additions & 6 deletions module/zcommon/zpool_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,12 +359,16 @@ vdev_prop_init(void)
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "CLAIMBYTE");
zprop_register_number(VDEV_PROP_BYTES_TRIM, "trim_bytes", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<bytes>", "TRIMBYTE");
/* XXX - register this as an index (yes | no) type? */
zprop_register_number(VDEV_PROP_REMOVING, "removing", 0,
PROP_READONLY, ZFS_TYPE_VDEV, "<boolean>", "REMOVING");

/* default numeric properties */

/* default index (boolean) properties */
zprop_register_index(VDEV_PROP_NOALLOC, "noalloc", 0,
PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off", "NOALLOC", boolean_table);
zprop_register_index(VDEV_PROP_ALLOCATING, "allocating", 1,
PROP_DEFAULT, ZFS_TYPE_VDEV, "on | off", "ALLOCATING",
boolean_table);

/* default index properties */

Expand Down Expand Up @@ -400,10 +404,7 @@ vdev_prop_user(const char *name)
foundsep = B_TRUE;
}

if (!foundsep)
return (B_FALSE);

return (B_TRUE);
return (foundsep);
}

/*
Expand Down
Loading

0 comments on commit 72d3020

Please sign in to comment.