mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Create zap for root vdev
And add it to the AVZ, this is not backwards compatible with older pools
due to an assertion in spa_sync() that verifies the number of ZAPs of
all vdevs matches the number of ZAPs in the AVZ.
Granted, the assertion only applies to #DEBUG builds - still, a feature
flag is introduced to avoid the assertion, com.klarasystems:vdev_zaps_v2
Notably, this allows to get/set properties on the root vdev:
% zpool set user:prop=value <pool> root-0
Before this commit, it was already possible to get/set properties on
top-level vdevs with the syntax <type>-<vdev_id> (e.g. mirror-0):
% zpool set user:prop=value <pool> mirror-0
This syntax also applies to the root vdev as it is is of type 'root'
with a vdev_id of 0, root-0. The keyword 'root' as an alias for
'root-0'.
The following tests have been added:
- zpool get all properties from root vdev
- zpool set a property on root vdev
- verify root vdev ZAP is created
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Wing <rob.wing@klarasystems.com>
Sponsored-by: Seagate Technology
Submitted-by: Klara, Inc.
Closes #14405
This commit is contained in:
+44
-23
@@ -10001,33 +10001,33 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
get_callback_vdev_width_cb(void *zhp_data, nvlist_t *nv, void *data)
|
||||
{
|
||||
zpool_handle_t *zhp = zhp_data;
|
||||
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
|
||||
char *vdevname = zpool_vdev_name(g_zfs, zhp, nv,
|
||||
cbp->cb_vdevs.cb_name_flags);
|
||||
int ret;
|
||||
|
||||
/* Adjust the column widths for the vdev properties */
|
||||
ret = vdev_expand_proplist(zhp, vdevname, &cbp->cb_proplist);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
get_callback_vdev_cb(void *zhp_data, nvlist_t *nv, void *data)
|
||||
{
|
||||
zpool_handle_t *zhp = zhp_data;
|
||||
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
|
||||
char *vdevname = zpool_vdev_name(g_zfs, zhp, nv,
|
||||
cbp->cb_vdevs.cb_name_flags);
|
||||
char *vdevname;
|
||||
const char *type;
|
||||
int ret;
|
||||
|
||||
/* Display the properties */
|
||||
/*
|
||||
* zpool_vdev_name() transforms the root vdev name (i.e., root-0) to the
|
||||
* pool name for display purposes, which is not desired. Fallback to
|
||||
* zpool_vdev_name() when not dealing with the root vdev.
|
||||
*/
|
||||
type = fnvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE);
|
||||
if (zhp != NULL && strcmp(type, "root") == 0)
|
||||
vdevname = strdup("root-0");
|
||||
else
|
||||
vdevname = zpool_vdev_name(g_zfs, zhp, nv,
|
||||
cbp->cb_vdevs.cb_name_flags);
|
||||
|
||||
(void) vdev_expand_proplist(zhp, vdevname, &cbp->cb_proplist);
|
||||
|
||||
ret = get_callback_vdev(zhp, vdevname, data);
|
||||
|
||||
free(vdevname);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -10042,7 +10042,6 @@ get_callback(zpool_handle_t *zhp, void *data)
|
||||
|
||||
if (cbp->cb_type == ZFS_TYPE_VDEV) {
|
||||
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 */
|
||||
@@ -10119,6 +10118,7 @@ zpool_do_get(int argc, char **argv)
|
||||
int ret;
|
||||
int c, i;
|
||||
char *propstr = NULL;
|
||||
char *vdev = NULL;
|
||||
|
||||
cb.cb_first = B_TRUE;
|
||||
|
||||
@@ -10216,10 +10216,17 @@ found:
|
||||
} else if (are_all_pools(1, argv)) {
|
||||
/* The first arg is a pool name */
|
||||
if ((argc == 2 && strcmp(argv[1], "all-vdevs") == 0) ||
|
||||
(argc == 2 && strcmp(argv[1], "root") == 0) ||
|
||||
are_vdevs_in_pool(argc - 1, argv + 1, argv[0],
|
||||
&cb.cb_vdevs)) {
|
||||
|
||||
if (strcmp(argv[1], "root") == 0)
|
||||
vdev = strdup("root-0");
|
||||
else
|
||||
vdev = strdup(argv[1]);
|
||||
|
||||
/* ... and the rest are vdev names */
|
||||
cb.cb_vdevs.cb_names = argv + 1;
|
||||
cb.cb_vdevs.cb_names = &vdev;
|
||||
cb.cb_vdevs.cb_names_count = argc - 1;
|
||||
cb.cb_type = ZFS_TYPE_VDEV;
|
||||
argc = 1; /* One pool to process */
|
||||
@@ -10264,6 +10271,9 @@ found:
|
||||
else
|
||||
zprop_free_list(cb.cb_proplist);
|
||||
|
||||
if (vdev != NULL)
|
||||
free(vdev);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -10365,6 +10375,7 @@ zpool_do_set(int argc, char **argv)
|
||||
{
|
||||
set_cbdata_t cb = { 0 };
|
||||
int error;
|
||||
char *vdev = NULL;
|
||||
|
||||
current_prop_type = ZFS_TYPE_POOL;
|
||||
if (argc > 1 && argv[1][0] == '-') {
|
||||
@@ -10413,13 +10424,20 @@ zpool_do_set(int argc, char **argv)
|
||||
|
||||
/* argv[1], when supplied, is vdev name */
|
||||
if (argc == 2) {
|
||||
if (!are_vdevs_in_pool(1, argv + 1, argv[0], &cb.cb_vdevs)) {
|
||||
|
||||
if (strcmp(argv[1], "root") == 0)
|
||||
vdev = strdup("root-0");
|
||||
else
|
||||
vdev = strdup(argv[1]);
|
||||
|
||||
if (!are_vdevs_in_pool(1, &vdev, argv[0], &cb.cb_vdevs)) {
|
||||
(void) fprintf(stderr, gettext(
|
||||
"cannot find '%s' in '%s': device not in pool\n"),
|
||||
argv[1], argv[0]);
|
||||
vdev, argv[0]);
|
||||
free(vdev);
|
||||
return (EINVAL);
|
||||
}
|
||||
cb.cb_vdevs.cb_names = argv + 1;
|
||||
cb.cb_vdevs.cb_names = &vdev;
|
||||
cb.cb_vdevs.cb_names_count = 1;
|
||||
cb.cb_type = ZFS_TYPE_VDEV;
|
||||
}
|
||||
@@ -10427,6 +10445,9 @@ zpool_do_set(int argc, char **argv)
|
||||
error = for_each_pool(1, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
|
||||
B_FALSE, set_callback, &cb);
|
||||
|
||||
if (vdev != NULL)
|
||||
free(vdev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user