mirror of
https://git.proxmox.com/git/mirror_zfs
synced 2025-05-02 15:45:03 +00:00
JSON output support for zpool get
This commit adds support for zpool get command to output the list of properties for ZFS Pools and VDEVS in JSON format using '-j' option. Man page for zpool get is updated to include '-j' option. Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Ameer Hamza <ahamza@ixsystems.com> Signed-off-by: Umer Saleem <usaleem@ixsystems.com> Closes #16217
This commit is contained in:
parent
5cbdd5ea4f
commit
eb2b824bde
@ -1972,26 +1972,6 @@ fill_dataset_info(nvlist_t *list, zfs_handle_t *zhp, boolean_t as_int)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
zprop_collect_property(const char *name, zprop_get_cbdata_t *cbp,
|
|
||||||
const char *propname, const char *value, zprop_source_t sourcetype,
|
|
||||||
const char *source, const char *recvd_value, nvlist_t *nvl)
|
|
||||||
{
|
|
||||||
if (cbp->cb_json) {
|
|
||||||
if ((sourcetype & cbp->cb_sources) == 0)
|
|
||||||
return (0);
|
|
||||||
else {
|
|
||||||
return (zprop_nvlist_one_property(propname, value,
|
|
||||||
sourcetype, source, recvd_value, nvl,
|
|
||||||
cbp->cb_json_as_int));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
zprop_print_one_property(name, cbp,
|
|
||||||
propname, value, sourcetype, source, recvd_value);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zfs get [-rHp] [-j [--json-int]] [-o all | field[,field]...]
|
* zfs get [-rHp] [-j [--json-int]] [-o all | field[,field]...]
|
||||||
* [-s source[,source]...]
|
* [-s source[,source]...]
|
||||||
|
@ -139,7 +139,9 @@ enum zpool_options {
|
|||||||
ZPOOL_OPTION_POWER = 1024,
|
ZPOOL_OPTION_POWER = 1024,
|
||||||
ZPOOL_OPTION_ALLOW_INUSE,
|
ZPOOL_OPTION_ALLOW_INUSE,
|
||||||
ZPOOL_OPTION_ALLOW_REPLICATION_MISMATCH,
|
ZPOOL_OPTION_ALLOW_REPLICATION_MISMATCH,
|
||||||
ZPOOL_OPTION_ALLOW_ASHIFT_MISMATCH
|
ZPOOL_OPTION_ALLOW_ASHIFT_MISMATCH,
|
||||||
|
ZPOOL_OPTION_POOL_KEY_GUID,
|
||||||
|
ZPOOL_OPTION_JSON_NUMS_AS_INT
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -440,7 +442,8 @@ get_usage(zpool_help_t idx)
|
|||||||
case HELP_EVENTS:
|
case HELP_EVENTS:
|
||||||
return (gettext("\tevents [-vHf [pool] | -c]\n"));
|
return (gettext("\tevents [-vHf [pool] | -c]\n"));
|
||||||
case HELP_GET:
|
case HELP_GET:
|
||||||
return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
|
return (gettext("\tget [-Hp] [-j [--json-int, "
|
||||||
|
"--json-pool-key-guid]] [-o \"all\" | field[,...]] "
|
||||||
"<\"all\" | property[,...]> <pool> ...\n"));
|
"<\"all\" | property[,...]> <pool> ...\n"));
|
||||||
case HELP_SET:
|
case HELP_SET:
|
||||||
return (gettext("\tset <property=value> <pool>\n"
|
return (gettext("\tset <property=value> <pool>\n"
|
||||||
@ -898,6 +901,109 @@ print_spare_list(nvlist_t *nv, int indent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generates an nvlist with output version for every command based on params.
|
||||||
|
* Purpose of this is to add a version of JSON output, considering the schema
|
||||||
|
* format might be updated for each command in future.
|
||||||
|
*
|
||||||
|
* Schema:
|
||||||
|
*
|
||||||
|
* "output_version": {
|
||||||
|
* "command": string,
|
||||||
|
* "vers_major": integer,
|
||||||
|
* "vers_minor": integer,
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
static nvlist_t *
|
||||||
|
zpool_json_schema(int maj_v, int min_v)
|
||||||
|
{
|
||||||
|
char cmd[MAX_CMD_LEN];
|
||||||
|
nvlist_t *sch = fnvlist_alloc();
|
||||||
|
nvlist_t *ov = fnvlist_alloc();
|
||||||
|
|
||||||
|
snprintf(cmd, MAX_CMD_LEN, "zpool %s", current_command->name);
|
||||||
|
fnvlist_add_string(ov, "command", cmd);
|
||||||
|
fnvlist_add_uint32(ov, "vers_major", maj_v);
|
||||||
|
fnvlist_add_uint32(ov, "vers_minor", min_v);
|
||||||
|
fnvlist_add_nvlist(sch, "output_version", ov);
|
||||||
|
fnvlist_free(ov);
|
||||||
|
return (sch);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_pool_info(nvlist_t *list, zpool_handle_t *zhp, boolean_t addtype,
|
||||||
|
boolean_t as_int)
|
||||||
|
{
|
||||||
|
nvlist_t *config = zpool_get_config(zhp, NULL);
|
||||||
|
uint64_t guid = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID);
|
||||||
|
uint64_t txg = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG);
|
||||||
|
|
||||||
|
fnvlist_add_string(list, "name", zpool_get_name(zhp));
|
||||||
|
if (addtype)
|
||||||
|
fnvlist_add_string(list, "type", "POOL");
|
||||||
|
fnvlist_add_string(list, "state", zpool_get_state_str(zhp));
|
||||||
|
if (as_int) {
|
||||||
|
if (guid)
|
||||||
|
fnvlist_add_uint64(list, ZPOOL_CONFIG_POOL_GUID, guid);
|
||||||
|
if (txg)
|
||||||
|
fnvlist_add_uint64(list, ZPOOL_CONFIG_POOL_TXG, txg);
|
||||||
|
fnvlist_add_uint64(list, "spa_version", SPA_VERSION);
|
||||||
|
fnvlist_add_uint64(list, "zpl_version", ZPL_VERSION);
|
||||||
|
} else {
|
||||||
|
char value[ZFS_MAXPROPLEN];
|
||||||
|
if (guid) {
|
||||||
|
snprintf(value, ZFS_MAXPROPLEN, "%llu",
|
||||||
|
(u_longlong_t)guid);
|
||||||
|
fnvlist_add_string(list, ZPOOL_CONFIG_POOL_GUID, value);
|
||||||
|
}
|
||||||
|
if (txg) {
|
||||||
|
snprintf(value, ZFS_MAXPROPLEN, "%llu",
|
||||||
|
(u_longlong_t)txg);
|
||||||
|
fnvlist_add_string(list, ZPOOL_CONFIG_POOL_TXG, value);
|
||||||
|
}
|
||||||
|
fnvlist_add_string(list, "spa_version", SPA_VERSION_STRING);
|
||||||
|
fnvlist_add_string(list, "zpl_version", ZPL_VERSION_STRING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_vdev_info(nvlist_t *list, zpool_handle_t *zhp, char *name,
|
||||||
|
boolean_t as_int)
|
||||||
|
{
|
||||||
|
boolean_t spare, l2c, log;
|
||||||
|
const char *path, *phys, *devid;
|
||||||
|
nvlist_t *nvdev = zpool_find_vdev(zhp, name, &spare, &l2c, &log);
|
||||||
|
|
||||||
|
fnvlist_add_string(list, "name", name);
|
||||||
|
fnvlist_add_string(list, "type", "VDEV");
|
||||||
|
if (nvdev) {
|
||||||
|
const char *type = fnvlist_lookup_string(nvdev,
|
||||||
|
ZPOOL_CONFIG_TYPE);
|
||||||
|
if (type)
|
||||||
|
fnvlist_add_string(list, "vdev_type", type);
|
||||||
|
uint64_t guid = fnvlist_lookup_uint64(nvdev, ZPOOL_CONFIG_GUID);
|
||||||
|
if (guid) {
|
||||||
|
if (as_int) {
|
||||||
|
fnvlist_add_uint64(list, "guid", guid);
|
||||||
|
} else {
|
||||||
|
char buf[ZFS_MAXPROPLEN];
|
||||||
|
snprintf(buf, ZFS_MAXPROPLEN, "%llu",
|
||||||
|
(u_longlong_t)guid);
|
||||||
|
fnvlist_add_string(list, "guid", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvlist_lookup_string(nvdev, ZPOOL_CONFIG_PATH, &path) == 0)
|
||||||
|
fnvlist_add_string(list, "path", path);
|
||||||
|
if (nvlist_lookup_string(nvdev, ZPOOL_CONFIG_PHYS_PATH,
|
||||||
|
&phys) == 0)
|
||||||
|
fnvlist_add_string(list, "phys_path", phys);
|
||||||
|
if (nvlist_lookup_string(nvdev, ZPOOL_CONFIG_DEVID,
|
||||||
|
&devid) == 0)
|
||||||
|
fnvlist_add_string(list, "devid", devid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static boolean_t
|
static boolean_t
|
||||||
prop_list_contains_feature(nvlist_t *proplist)
|
prop_list_contains_feature(nvlist_t *proplist)
|
||||||
{
|
{
|
||||||
@ -10346,35 +10452,6 @@ zpool_do_history(int argc, char **argv)
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Generates an nvlist with output version for every command based on params.
|
|
||||||
* Purpose of this is to add a version of JSON output, considering the schema
|
|
||||||
* format might be updated for each command in future.
|
|
||||||
*
|
|
||||||
* Schema:
|
|
||||||
*
|
|
||||||
* "output_version": {
|
|
||||||
* "command": string,
|
|
||||||
* "vers_major": integer,
|
|
||||||
* "vers_minor": integer,
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
static nvlist_t *
|
|
||||||
zpool_json_schema(int maj_v, int min_v)
|
|
||||||
{
|
|
||||||
char cmd[MAX_CMD_LEN];
|
|
||||||
nvlist_t *sch = fnvlist_alloc();
|
|
||||||
nvlist_t *ov = fnvlist_alloc();
|
|
||||||
|
|
||||||
snprintf(cmd, MAX_CMD_LEN, "zpool %s", current_command->name);
|
|
||||||
fnvlist_add_string(ov, "command", cmd);
|
|
||||||
fnvlist_add_uint32(ov, "vers_major", maj_v);
|
|
||||||
fnvlist_add_uint32(ov, "vers_minor", min_v);
|
|
||||||
fnvlist_add_nvlist(sch, "output_version", ov);
|
|
||||||
|
|
||||||
return (sch);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct ev_opts {
|
typedef struct ev_opts {
|
||||||
int verbose;
|
int verbose;
|
||||||
int scripted;
|
int scripted;
|
||||||
@ -10769,6 +10846,17 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data)
|
|||||||
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
|
zprop_get_cbdata_t *cbp = (zprop_get_cbdata_t *)data;
|
||||||
char value[ZFS_MAXPROPLEN];
|
char value[ZFS_MAXPROPLEN];
|
||||||
zprop_source_t srctype;
|
zprop_source_t srctype;
|
||||||
|
nvlist_t *props, *item, *d;
|
||||||
|
props = item = d = NULL;
|
||||||
|
|
||||||
|
if (cbp->cb_json) {
|
||||||
|
d = fnvlist_lookup_nvlist(cbp->cb_jsobj, "vdevs");
|
||||||
|
if (d == NULL) {
|
||||||
|
fprintf(stderr, "vdevs obj not found.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
props = fnvlist_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
for (zprop_list_t *pl = cbp->cb_proplist; pl != NULL;
|
for (zprop_list_t *pl = cbp->cb_proplist; pl != NULL;
|
||||||
pl = pl->pl_next) {
|
pl = pl->pl_next) {
|
||||||
@ -10790,11 +10878,24 @@ get_callback_vdev(zpool_handle_t *zhp, char *vdevname, void *data)
|
|||||||
if (zpool_get_vdev_prop(zhp, vdevname, pl->pl_prop,
|
if (zpool_get_vdev_prop(zhp, vdevname, pl->pl_prop,
|
||||||
prop_name, value, sizeof (value), &srctype,
|
prop_name, value, sizeof (value), &srctype,
|
||||||
cbp->cb_literal) == 0) {
|
cbp->cb_literal) == 0) {
|
||||||
zprop_print_one_property(vdevname, cbp, prop_name,
|
zprop_collect_property(vdevname, cbp, prop_name,
|
||||||
value, srctype, NULL, NULL);
|
value, srctype, NULL, NULL, props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cbp->cb_json) {
|
||||||
|
if (!nvlist_empty(props)) {
|
||||||
|
item = fnvlist_alloc();
|
||||||
|
fill_vdev_info(item, zhp, vdevname,
|
||||||
|
cbp->cb_json_as_int);
|
||||||
|
fnvlist_add_nvlist(item, "properties", props);
|
||||||
|
fnvlist_add_nvlist(d, vdevname, item);
|
||||||
|
fnvlist_add_nvlist(cbp->cb_jsobj, "vdevs", d);
|
||||||
|
fnvlist_free(item);
|
||||||
|
}
|
||||||
|
fnvlist_free(props);
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10836,8 +10937,18 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
zprop_source_t srctype;
|
zprop_source_t srctype;
|
||||||
zprop_list_t *pl;
|
zprop_list_t *pl;
|
||||||
int vid;
|
int vid;
|
||||||
|
int err = 0;
|
||||||
|
nvlist_t *props, *item, *d;
|
||||||
|
props = item = d = NULL;
|
||||||
|
|
||||||
if (cbp->cb_type == ZFS_TYPE_VDEV) {
|
if (cbp->cb_type == ZFS_TYPE_VDEV) {
|
||||||
|
if (cbp->cb_json) {
|
||||||
|
nvlist_t *pool = fnvlist_alloc();
|
||||||
|
fill_pool_info(pool, zhp, B_FALSE, cbp->cb_json_as_int);
|
||||||
|
fnvlist_add_nvlist(cbp->cb_jsobj, "pool", pool);
|
||||||
|
fnvlist_free(pool);
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(cbp->cb_vdevs.cb_names[0], "all-vdevs") == 0) {
|
if (strcmp(cbp->cb_vdevs.cb_names[0], "all-vdevs") == 0) {
|
||||||
for_each_vdev(zhp, get_callback_vdev_cb, data);
|
for_each_vdev(zhp, get_callback_vdev_cb, data);
|
||||||
} else {
|
} else {
|
||||||
@ -10857,6 +10968,14 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(cbp->cb_type == ZFS_TYPE_POOL);
|
assert(cbp->cb_type == ZFS_TYPE_POOL);
|
||||||
|
if (cbp->cb_json) {
|
||||||
|
d = fnvlist_lookup_nvlist(cbp->cb_jsobj, "pools");
|
||||||
|
if (d == NULL) {
|
||||||
|
fprintf(stderr, "pools obj not found.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
props = fnvlist_alloc();
|
||||||
|
}
|
||||||
for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
|
for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) {
|
||||||
/*
|
/*
|
||||||
* Skip the special fake placeholder. This will also
|
* Skip the special fake placeholder. This will also
|
||||||
@ -10874,9 +10993,9 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
value, sizeof (value), &srctype) != 0)
|
value, sizeof (value), &srctype) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
zprop_print_one_property(zpool_get_name(zhp),
|
err = zprop_collect_property(
|
||||||
cbp, pl->pl_user_prop, value, srctype,
|
zpool_get_name(zhp), cbp, pl->pl_user_prop,
|
||||||
NULL, NULL);
|
value, srctype, NULL, NULL, props);
|
||||||
} else if (pl->pl_prop == ZPROP_INVAL &&
|
} else if (pl->pl_prop == ZPROP_INVAL &&
|
||||||
(zpool_prop_feature(pl->pl_user_prop) ||
|
(zpool_prop_feature(pl->pl_user_prop) ||
|
||||||
zpool_prop_unsupported(pl->pl_user_prop))) {
|
zpool_prop_unsupported(pl->pl_user_prop))) {
|
||||||
@ -10885,10 +11004,10 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
if (zpool_prop_get_feature(zhp,
|
if (zpool_prop_get_feature(zhp,
|
||||||
pl->pl_user_prop, value,
|
pl->pl_user_prop, value,
|
||||||
sizeof (value)) == 0) {
|
sizeof (value)) == 0) {
|
||||||
zprop_print_one_property(
|
err = zprop_collect_property(
|
||||||
zpool_get_name(zhp), cbp,
|
zpool_get_name(zhp), cbp,
|
||||||
pl->pl_user_prop, value, srctype,
|
pl->pl_user_prop, value, srctype,
|
||||||
NULL, NULL);
|
NULL, NULL, props);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (zpool_get_prop(zhp, pl->pl_prop, value,
|
if (zpool_get_prop(zhp, pl->pl_prop, value,
|
||||||
@ -10896,10 +11015,37 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
cbp->cb_literal) != 0)
|
cbp->cb_literal) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
zprop_print_one_property(zpool_get_name(zhp),
|
err = zprop_collect_property(
|
||||||
cbp, zpool_prop_to_name(pl->pl_prop),
|
zpool_get_name(zhp), cbp,
|
||||||
value, srctype, NULL, NULL);
|
zpool_prop_to_name(pl->pl_prop),
|
||||||
|
value, srctype, NULL, NULL, props);
|
||||||
}
|
}
|
||||||
|
if (err != 0)
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cbp->cb_json) {
|
||||||
|
if (!nvlist_empty(props)) {
|
||||||
|
item = fnvlist_alloc();
|
||||||
|
fill_pool_info(item, zhp, B_TRUE,
|
||||||
|
cbp->cb_json_as_int);
|
||||||
|
fnvlist_add_nvlist(item, "properties", props);
|
||||||
|
if (cbp->cb_json_pool_key_guid) {
|
||||||
|
char buf[256];
|
||||||
|
uint64_t guid = fnvlist_lookup_uint64(
|
||||||
|
zpool_get_config(zhp, NULL),
|
||||||
|
ZPOOL_CONFIG_POOL_GUID);
|
||||||
|
snprintf(buf, 256, "%llu",
|
||||||
|
(u_longlong_t)guid);
|
||||||
|
fnvlist_add_nvlist(d, buf, item);
|
||||||
|
} else {
|
||||||
|
const char *name = zpool_get_name(zhp);
|
||||||
|
fnvlist_add_nvlist(d, name, item);
|
||||||
|
}
|
||||||
|
fnvlist_add_nvlist(cbp->cb_jsobj, "pools", d);
|
||||||
|
fnvlist_free(item);
|
||||||
|
}
|
||||||
|
fnvlist_free(props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10914,6 +11060,9 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
* -o List of columns to display. Defaults to
|
* -o List of columns to display. Defaults to
|
||||||
* "name,property,value,source".
|
* "name,property,value,source".
|
||||||
* -p Display values in parsable (exact) format.
|
* -p Display values in parsable (exact) format.
|
||||||
|
* -j Display output in JSON format.
|
||||||
|
* --json-int Display numbers as integers instead of strings.
|
||||||
|
* --json-pool-key-guid Set pool GUID as key for pool objects.
|
||||||
*
|
*
|
||||||
* Get properties of pools in the system. Output space statistics
|
* Get properties of pools in the system. Output space statistics
|
||||||
* for each one as well as other attributes.
|
* for each one as well as other attributes.
|
||||||
@ -10927,6 +11076,7 @@ zpool_do_get(int argc, char **argv)
|
|||||||
int c, i;
|
int c, i;
|
||||||
char *propstr = NULL;
|
char *propstr = NULL;
|
||||||
char *vdev = NULL;
|
char *vdev = NULL;
|
||||||
|
nvlist_t *data = NULL;
|
||||||
|
|
||||||
cb.cb_first = B_TRUE;
|
cb.cb_first = B_TRUE;
|
||||||
|
|
||||||
@ -10942,8 +11092,16 @@ zpool_do_get(int argc, char **argv)
|
|||||||
cb.cb_vdevs.cb_name_flags |= VDEV_NAME_TYPE_ID;
|
cb.cb_vdevs.cb_name_flags |= VDEV_NAME_TYPE_ID;
|
||||||
current_prop_type = cb.cb_type;
|
current_prop_type = cb.cb_type;
|
||||||
|
|
||||||
|
struct option long_options[] = {
|
||||||
|
{"json-int", no_argument, NULL, ZPOOL_OPTION_JSON_NUMS_AS_INT},
|
||||||
|
{"json-pool-key-guid", no_argument, NULL,
|
||||||
|
ZPOOL_OPTION_POOL_KEY_GUID},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
|
while ((c = getopt_long(argc, argv, ":jHpo:", long_options,
|
||||||
|
NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'p':
|
case 'p':
|
||||||
cb.cb_literal = B_TRUE;
|
cb.cb_literal = B_TRUE;
|
||||||
@ -10951,6 +11109,18 @@ zpool_do_get(int argc, char **argv)
|
|||||||
case 'H':
|
case 'H':
|
||||||
cb.cb_scripted = B_TRUE;
|
cb.cb_scripted = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'j':
|
||||||
|
cb.cb_json = B_TRUE;
|
||||||
|
cb.cb_jsobj = zpool_json_schema(0, 1);
|
||||||
|
data = fnvlist_alloc();
|
||||||
|
break;
|
||||||
|
case ZPOOL_OPTION_POOL_KEY_GUID:
|
||||||
|
cb.cb_json_pool_key_guid = B_TRUE;
|
||||||
|
break;
|
||||||
|
case ZPOOL_OPTION_JSON_NUMS_AS_INT:
|
||||||
|
cb.cb_json_as_int = B_TRUE;
|
||||||
|
cb.cb_literal = B_TRUE;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
memset(&cb.cb_columns, 0, sizeof (cb.cb_columns));
|
memset(&cb.cb_columns, 0, sizeof (cb.cb_columns));
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -11005,6 +11175,18 @@ found:
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
|
if (!cb.cb_json && cb.cb_json_as_int) {
|
||||||
|
(void) fprintf(stderr, gettext("'--json-int' only works with"
|
||||||
|
" '-j' option\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cb.cb_json && cb.cb_json_pool_key_guid) {
|
||||||
|
(void) fprintf(stderr, gettext("'json-pool-key-guid' only"
|
||||||
|
" works with '-j' option\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
(void) fprintf(stderr, gettext("missing property "
|
(void) fprintf(stderr, gettext("missing property "
|
||||||
"argument\n"));
|
"argument\n"));
|
||||||
@ -11039,6 +11221,10 @@ found:
|
|||||||
cb.cb_type = ZFS_TYPE_VDEV;
|
cb.cb_type = ZFS_TYPE_VDEV;
|
||||||
argc = 1; /* One pool to process */
|
argc = 1; /* One pool to process */
|
||||||
} else {
|
} else {
|
||||||
|
if (cb.cb_json) {
|
||||||
|
nvlist_free(cb.cb_jsobj);
|
||||||
|
nvlist_free(data);
|
||||||
|
}
|
||||||
fprintf(stderr, gettext("Expected a list of vdevs in"
|
fprintf(stderr, gettext("Expected a list of vdevs in"
|
||||||
" \"%s\", but got:\n"), argv[0]);
|
" \"%s\", but got:\n"), argv[0]);
|
||||||
error_list_unresolved_vdevs(argc - 1, argv + 1,
|
error_list_unresolved_vdevs(argc - 1, argv + 1,
|
||||||
@ -11048,6 +11234,10 @@ found:
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (cb.cb_json) {
|
||||||
|
nvlist_free(cb.cb_jsobj);
|
||||||
|
nvlist_free(data);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* The first arg isn't the name of a valid pool.
|
* The first arg isn't the name of a valid pool.
|
||||||
*/
|
*/
|
||||||
@ -11070,9 +11260,22 @@ found:
|
|||||||
cb.cb_proplist = &fake_name;
|
cb.cb_proplist = &fake_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cb.cb_json) {
|
||||||
|
if (cb.cb_type == ZFS_TYPE_VDEV)
|
||||||
|
fnvlist_add_nvlist(cb.cb_jsobj, "vdevs", data);
|
||||||
|
else
|
||||||
|
fnvlist_add_nvlist(cb.cb_jsobj, "pools", data);
|
||||||
|
fnvlist_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, cb.cb_type,
|
ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist, cb.cb_type,
|
||||||
cb.cb_literal, get_callback, &cb);
|
cb.cb_literal, get_callback, &cb);
|
||||||
|
|
||||||
|
if (ret == 0 && cb.cb_json)
|
||||||
|
zcmd_print_json(cb.cb_jsobj);
|
||||||
|
else if (ret != 0 && cb.cb_json)
|
||||||
|
nvlist_free(cb.cb_jsobj);
|
||||||
|
|
||||||
if (cb.cb_proplist == &fake_name)
|
if (cb.cb_proplist == &fake_name)
|
||||||
zprop_free_list(fake_name.pl_next);
|
zprop_free_list(fake_name.pl_next);
|
||||||
else
|
else
|
||||||
|
@ -666,6 +666,7 @@ typedef struct zprop_get_cbdata {
|
|||||||
vdev_cbdata_t cb_vdevs;
|
vdev_cbdata_t cb_vdevs;
|
||||||
nvlist_t *cb_jsobj;
|
nvlist_t *cb_jsobj;
|
||||||
boolean_t cb_json_as_int;
|
boolean_t cb_json_as_int;
|
||||||
|
boolean_t cb_json_pool_key_guid;
|
||||||
} zprop_get_cbdata_t;
|
} zprop_get_cbdata_t;
|
||||||
|
|
||||||
#define ZFS_SET_NOMOUNT 1
|
#define ZFS_SET_NOMOUNT 1
|
||||||
@ -682,6 +683,10 @@ _LIBZFS_H void zprop_print_one_property(const char *, zprop_get_cbdata_t *,
|
|||||||
_LIBZFS_H int zprop_nvlist_one_property(const char *, const char *,
|
_LIBZFS_H int zprop_nvlist_one_property(const char *, const char *,
|
||||||
zprop_source_t, const char *, const char *, nvlist_t *, boolean_t);
|
zprop_source_t, const char *, const char *, nvlist_t *, boolean_t);
|
||||||
|
|
||||||
|
_LIBZFS_H int zprop_collect_property(const char *, zprop_get_cbdata_t *,
|
||||||
|
const char *, const char *, zprop_source_t, const char *,
|
||||||
|
const char *, nvlist_t *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterator functions.
|
* Iterator functions.
|
||||||
*/
|
*/
|
||||||
|
@ -1590,6 +1590,26 @@ zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
|
|||||||
(void) printf("\n");
|
(void) printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zprop_collect_property(const char *name, zprop_get_cbdata_t *cbp,
|
||||||
|
const char *propname, const char *value, zprop_source_t sourcetype,
|
||||||
|
const char *source, const char *recvd_value, nvlist_t *nvl)
|
||||||
|
{
|
||||||
|
if (cbp->cb_json) {
|
||||||
|
if ((sourcetype & cbp->cb_sources) == 0)
|
||||||
|
return (0);
|
||||||
|
else {
|
||||||
|
return (zprop_nvlist_one_property(propname, value,
|
||||||
|
sourcetype, source, recvd_value, nvl,
|
||||||
|
cbp->cb_json_as_int));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zprop_print_one_property(name, cbp,
|
||||||
|
propname, value, sourcetype, source, recvd_value);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a numeric suffix, convert the value into a number of bits that the
|
* Given a numeric suffix, convert the value into a number of bits that the
|
||||||
* resulting value must be shifted.
|
* resulting value must be shifted.
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
.Nm zpool
|
.Nm zpool
|
||||||
.Cm get
|
.Cm get
|
||||||
.Op Fl Hp
|
.Op Fl Hp
|
||||||
|
.Op Fl j Op Ar --json-int, --json-pool-key-guid
|
||||||
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
||||||
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
||||||
.Oo Ar pool Oc Ns …
|
.Oo Ar pool Oc Ns …
|
||||||
@ -44,6 +45,7 @@
|
|||||||
.Nm zpool
|
.Nm zpool
|
||||||
.Cm get
|
.Cm get
|
||||||
.Op Fl Hp
|
.Op Fl Hp
|
||||||
|
.Op Fl j Op Ar --json-int
|
||||||
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
||||||
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
||||||
.Ar pool
|
.Ar pool
|
||||||
@ -67,6 +69,7 @@
|
|||||||
.Nm zpool
|
.Nm zpool
|
||||||
.Cm get
|
.Cm get
|
||||||
.Op Fl Hp
|
.Op Fl Hp
|
||||||
|
.Op Fl j Op Ar --json-int, --json-pool-key-guid
|
||||||
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
||||||
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
||||||
.Oo Ar pool Oc Ns …
|
.Oo Ar pool Oc Ns …
|
||||||
@ -95,6 +98,14 @@ See the
|
|||||||
.Xr zpoolprops 7
|
.Xr zpoolprops 7
|
||||||
manual page for more information on the available pool properties.
|
manual page for more information on the available pool properties.
|
||||||
.Bl -tag -compact -offset Ds -width "-o field"
|
.Bl -tag -compact -offset Ds -width "-o field"
|
||||||
|
.It Fl j Op Ar --json-int, --json-pool-key-guid
|
||||||
|
Display the list of properties in JSON format.
|
||||||
|
Specify
|
||||||
|
.Sy --json-int
|
||||||
|
to display the numbers in integer format instead of strings in JSON output.
|
||||||
|
Specify
|
||||||
|
.Sy --json-pool-key-guid
|
||||||
|
to set pool GUID as key for pool objects instead of pool name.
|
||||||
.It Fl H
|
.It Fl H
|
||||||
Scripted mode.
|
Scripted mode.
|
||||||
Do not display headers, and separate fields by a single tab instead of arbitrary
|
Do not display headers, and separate fields by a single tab instead of arbitrary
|
||||||
@ -108,6 +119,7 @@ Display numbers in parsable (exact) values.
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm zpool
|
.Nm zpool
|
||||||
.Cm get
|
.Cm get
|
||||||
|
.Op Fl j Op Ar --json-int
|
||||||
.Op Fl Hp
|
.Op Fl Hp
|
||||||
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
.Op Fl o Ar field Ns Oo , Ns Ar field Oc Ns …
|
||||||
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
.Sy all Ns | Ns Ar property Ns Oo , Ns Ar property Oc Ns …
|
||||||
@ -145,6 +157,11 @@ See the
|
|||||||
.Xr vdevprops 7
|
.Xr vdevprops 7
|
||||||
manual page for more information on the available pool properties.
|
manual page for more information on the available pool properties.
|
||||||
.Bl -tag -compact -offset Ds -width "-o field"
|
.Bl -tag -compact -offset Ds -width "-o field"
|
||||||
|
.It Fl j Op Ar --json-int
|
||||||
|
Display the list of properties in JSON format.
|
||||||
|
Specify
|
||||||
|
.Sy --json-int
|
||||||
|
to display the numbers in integer format instead of strings in JSON output.
|
||||||
.It Fl H
|
.It Fl H
|
||||||
Scripted mode.
|
Scripted mode.
|
||||||
Do not display headers, and separate fields by a single tab instead of arbitrary
|
Do not display headers, and separate fields by a single tab instead of arbitrary
|
||||||
|
Loading…
Reference in New Issue
Block a user