JSON output support for zpool status

This commit adds support for zpool status command to displpay status
of ZFS pools in JSON format using '-j' option. Status information is
collected in nvlist which is later dumped on stdout in JSON format.
Existing options for zpool status work with '-j' flag. man page for
zpool status is updated accordingly.

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:
Umer Saleem 2024-05-09 16:54:47 +05:00 committed by Brian Behlendorf
parent 4e6b3f7e1d
commit 959e963c81
9 changed files with 1928 additions and 451 deletions

File diff suppressed because it is too large Load Diff

View File

@ -469,7 +469,8 @@ _LIBZFS_H int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
char *altroot); char *altroot);
_LIBZFS_H int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *, _LIBZFS_H int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
nvlist_t *, int); nvlist_t *, int);
_LIBZFS_H void zpool_print_unsup_feat(nvlist_t *config); _LIBZFS_H void zpool_collect_unsup_feat(nvlist_t *config, char *buf,
size_t size);
/* /*
* Miscellaneous pool functions * Miscellaneous pool functions
@ -500,7 +501,7 @@ _LIBZFS_H void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *,
size_t); size_t);
_LIBZFS_H int zfs_ioctl(libzfs_handle_t *, int, struct zfs_cmd *); _LIBZFS_H int zfs_ioctl(libzfs_handle_t *, int, struct zfs_cmd *);
_LIBZFS_H void zpool_explain_recover(libzfs_handle_t *, const char *, int, _LIBZFS_H void zpool_explain_recover(libzfs_handle_t *, const char *, int,
nvlist_t *); nvlist_t *, char *, size_t);
_LIBZFS_H int zpool_checkpoint(zpool_handle_t *); _LIBZFS_H int zpool_checkpoint(zpool_handle_t *);
_LIBZFS_H int zpool_discard_checkpoint(zpool_handle_t *); _LIBZFS_H int zpool_discard_checkpoint(zpool_handle_t *);
_LIBZFS_H boolean_t zpool_is_draid_spare(const char *); _LIBZFS_H boolean_t zpool_is_draid_spare(const char *);

View File

@ -39,5 +39,7 @@
void print_timestamp(uint_t); void print_timestamp(uint_t);
/* Return timestamp in either Unix or standard format in provided buffer */ /* Return timestamp in either Unix or standard format in provided buffer */
void get_timestamp(uint_t, char *, int); void get_timestamp(uint_t, char *, int);
/* convert time_t to standard format */
void format_timestamp(time_t, char *, int);
#endif /* _STATCOMMON_H */ #endif /* _STATCOMMON_H */

View File

@ -84,3 +84,23 @@ get_timestamp(uint_t timestamp_fmt, char *buf, int len)
strftime(buf, len, fmt, localtime_r(&t, &tm)); strftime(buf, len, fmt, localtime_r(&t, &tm));
} }
} }
/*
* Format the provided time stamp to human readable format
*/
void
format_timestamp(time_t t, char *buf, int len)
{
struct tm tm;
static const char *fmt = NULL;
if (t == 0) {
snprintf(buf, len, "-");
return;
}
/* We only need to retrieve this once per invocation */
if (fmt == NULL)
fmt = nl_langinfo(_DATE_FMT);
strftime(buf, len, fmt, localtime_r(&t, &tm));
}

View File

@ -143,7 +143,9 @@
<elf-symbol name='avl_update_gt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='avl_update_gt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='avl_update_lt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='avl_update_lt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='avl_walk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='avl_walk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='format_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -1151,6 +1153,18 @@
<parameter type-id='3502e3ff' name='timestamp_fmt'/> <parameter type-id='3502e3ff' name='timestamp_fmt'/>
<return type-id='48b5725f'/> <return type-id='48b5725f'/>
</function-decl> </function-decl>
<function-decl name='get_timestamp' mangled-name='get_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_timestamp'>
<parameter type-id='3502e3ff' name='timestamp_fmt'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='95e97e5e' name='len'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='format_timestamp' mangled-name='format_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='format_timestamp'>
<parameter type-id='c9d12d66' name='t'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='95e97e5e' name='len'/>
<return type-id='48b5725f'/>
</function-decl>
</abi-instr> </abi-instr>
<abi-instr address-size='64' path='lib/libuutil/uu_alloc.c' language='LANG_C99'> <abi-instr address-size='64' path='lib/libuutil/uu_alloc.c' language='LANG_C99'>
<type-decl name='char' size-in-bits='8' id='a84c031d'/> <type-decl name='char' size-in-bits='8' id='a84c031d'/>

View File

@ -179,10 +179,12 @@
<elf-symbol name='fletcher_4_native' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='fletcher_4_native' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='fletcher_4_native_varsize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='fletcher_4_native_varsize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='fletcher_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='fletcher_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='format_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='fsleep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='fsleep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_dataset_depth' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_dataset_depth' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getprop_uint64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getprop_uint64' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -280,6 +282,7 @@
<elf-symbol name='vdev_prop_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='vdev_prop_to_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='vdev_prop_user' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='vdev_prop_user' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='vdev_prop_values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='vdev_prop_values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zcmd_print_json' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfeature_depends_on' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfeature_depends_on' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfeature_is_supported' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfeature_is_supported' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfeature_is_valid_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfeature_is_valid_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -452,6 +455,7 @@
<elf-symbol name='zfs_userspace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_userspace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_valid_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_valid_proplist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_version_kernel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_version_kernel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_version_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_version_print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_version_print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_version_userland' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_version_userland' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zfs_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -524,7 +528,7 @@
<elf-symbol name='zpool_prefetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_prefetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_prepare_and_label_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_prepare_and_label_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_prepare_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_prepare_disk' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_print_unsup_feat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_collect_unsup_feat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_prop_align_right' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_prop_column_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_prop_column_name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_prop_default_numeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_prop_default_numeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -577,12 +581,14 @@
<elf-symbol name='zpool_vdev_split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_vdev_split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_wait' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_wait_status' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_collect_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_free_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_free_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_get_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_get_list' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_index_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_index_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_iter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_iter_common' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_iter_common' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_name_to_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_nvlist_one_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_print_one_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_print_one_property' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_random_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_random_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zprop_register_hidden' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zprop_register_hidden' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -1284,6 +1290,18 @@
<parameter type-id='3502e3ff' name='timestamp_fmt'/> <parameter type-id='3502e3ff' name='timestamp_fmt'/>
<return type-id='48b5725f'/> <return type-id='48b5725f'/>
</function-decl> </function-decl>
<function-decl name='get_timestamp' mangled-name='get_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_timestamp'>
<parameter type-id='3502e3ff' name='timestamp_fmt'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='95e97e5e' name='len'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='format_timestamp' mangled-name='format_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='format_timestamp'>
<parameter type-id='c9d12d66' name='t'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='95e97e5e' name='len'/>
<return type-id='48b5725f'/>
</function-decl>
</abi-instr> </abi-instr>
<abi-instr address-size='64' path='lib/libtpool/thread_pool.c' language='LANG_C99'> <abi-instr address-size='64' path='lib/libtpool/thread_pool.c' language='LANG_C99'>
<array-type-def dimensions='1' type-id='49ef3ffd' size-in-bits='1024' id='a14403f5'> <array-type-def dimensions='1' type-id='49ef3ffd' size-in-bits='1024' id='a14403f5'>
@ -6456,6 +6474,8 @@
<parameter type-id='80f4b756' name='name'/> <parameter type-id='80f4b756' name='name'/>
<parameter type-id='95e97e5e' name='reason'/> <parameter type-id='95e97e5e' name='reason'/>
<parameter type-id='5ce45b60' name='config'/> <parameter type-id='5ce45b60' name='config'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='b59d7dce' name='size'/>
<return type-id='48b5725f'/> <return type-id='48b5725f'/>
</function-decl> </function-decl>
<function-decl name='zpool_import' mangled-name='zpool_import' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_import'> <function-decl name='zpool_import' mangled-name='zpool_import' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_import'>
@ -6465,8 +6485,10 @@
<parameter type-id='26a90f95' name='altroot'/> <parameter type-id='26a90f95' name='altroot'/>
<return type-id='95e97e5e'/> <return type-id='95e97e5e'/>
</function-decl> </function-decl>
<function-decl name='zpool_print_unsup_feat' mangled-name='zpool_print_unsup_feat' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_print_unsup_feat'> <function-decl name='zpool_collect_unsup_feat' mangled-name='zpool_collect_unsup_feat' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_collect_unsup_feat'>
<parameter type-id='5ce45b60' name='config'/> <parameter type-id='5ce45b60' name='config'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='b59d7dce' name='size'/>
<return type-id='48b5725f'/> <return type-id='48b5725f'/>
</function-decl> </function-decl>
<function-decl name='zpool_import_props' mangled-name='zpool_import_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_import_props'> <function-decl name='zpool_import_props' mangled-name='zpool_import_props' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_import_props'>
@ -8194,6 +8216,20 @@
<parameter type-id='2e45de5d' name='argtype'/> <parameter type-id='2e45de5d' name='argtype'/>
<return type-id='9200a744'/> <return type-id='9200a744'/>
</function-decl> </function-decl>
<function-decl name='zcmd_print_json' mangled-name='zcmd_print_json' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zcmd_print_json'>
<parameter type-id='5ce45b60' name='nvl'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zprop_nvlist_one_property' mangled-name='zprop_nvlist_one_property' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_nvlist_one_property'>
<parameter type-id='80f4b756' name='propname'/>
<parameter type-id='80f4b756' name='value'/>
<parameter type-id='a2256d42' name='sourcetype'/>
<parameter type-id='80f4b756' name='source'/>
<parameter type-id='80f4b756' name='recvd_value'/>
<parameter type-id='5ce45b60' name='nvl'/>
<parameter type-id='c19b74c3' name='as_int'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='zprop_print_one_property' mangled-name='zprop_print_one_property' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_print_one_property'> <function-decl name='zprop_print_one_property' mangled-name='zprop_print_one_property' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_print_one_property'>
<parameter type-id='80f4b756' name='name'/> <parameter type-id='80f4b756' name='name'/>
<parameter type-id='0d2a0670' name='cbp'/> <parameter type-id='0d2a0670' name='cbp'/>
@ -8204,6 +8240,17 @@
<parameter type-id='80f4b756' name='recvd_value'/> <parameter type-id='80f4b756' name='recvd_value'/>
<return type-id='48b5725f'/> <return type-id='48b5725f'/>
</function-decl> </function-decl>
<function-decl name='zprop_collect_property' mangled-name='zprop_collect_property' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_collect_property'>
<parameter type-id='80f4b756' name='name'/>
<parameter type-id='0d2a0670' name='cbp'/>
<parameter type-id='80f4b756' name='propname'/>
<parameter type-id='80f4b756' name='value'/>
<parameter type-id='a2256d42' name='sourcetype'/>
<parameter type-id='80f4b756' name='source'/>
<parameter type-id='80f4b756' name='recvd_value'/>
<parameter type-id='5ce45b60' name='nvl'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='zprop_get_list' mangled-name='zprop_get_list' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_get_list'> <function-decl name='zprop_get_list' mangled-name='zprop_get_list' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zprop_get_list'>
<parameter type-id='b0382bb3' name='hdl'/> <parameter type-id='b0382bb3' name='hdl'/>
<parameter type-id='26a90f95' name='props'/> <parameter type-id='26a90f95' name='props'/>
@ -8232,6 +8279,9 @@
<function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'> <function-decl name='use_color' mangled-name='use_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='use_color'>
<return type-id='95e97e5e'/> <return type-id='95e97e5e'/>
</function-decl> </function-decl>
<function-decl name='zfs_version_nvlist' mangled-name='zfs_version_nvlist' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_version_nvlist'>
<return type-id='5ce45b60'/>
</function-decl>
<function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'> <function-decl name='printf_color' mangled-name='printf_color' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='printf_color'>
<parameter type-id='80f4b756' name='color'/> <parameter type-id='80f4b756' name='color'/>
<parameter type-id='80f4b756' name='format'/> <parameter type-id='80f4b756' name='format'/>

View File

@ -1990,23 +1990,18 @@ zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
void void
zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason, zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
nvlist_t *config) nvlist_t *config, char *buf, size_t size)
{ {
nvlist_t *nv = NULL; nvlist_t *nv = NULL;
int64_t loss = -1; int64_t loss = -1;
uint64_t edata = UINT64_MAX; uint64_t edata = UINT64_MAX;
uint64_t rewindto; uint64_t rewindto;
struct tm t; struct tm t;
char timestr[128]; char timestr[128], temp[1024];
if (!hdl->libzfs_printerr) if (!hdl->libzfs_printerr)
return; return;
if (reason >= 0)
(void) printf(dgettext(TEXT_DOMAIN, "action: "));
else
(void) printf(dgettext(TEXT_DOMAIN, "\t"));
/* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */ /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 || if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 || nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
@ -2017,56 +2012,61 @@ zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS, (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
&edata); &edata);
(void) printf(dgettext(TEXT_DOMAIN, (void) snprintf(buf, size, dgettext(TEXT_DOMAIN,
"Recovery is possible, but will result in some data loss.\n")); "Recovery is possible, but will result in some data loss.\n"));
if (localtime_r((time_t *)&rewindto, &t) != NULL && if (localtime_r((time_t *)&rewindto, &t) != NULL &&
ctime_r((time_t *)&rewindto, timestr) != NULL) { ctime_r((time_t *)&rewindto, timestr) != NULL) {
timestr[24] = 0; timestr[24] = 0;
(void) printf(dgettext(TEXT_DOMAIN, (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
"\tReturning the pool to its state as of %s\n" "\tReturning the pool to its state as of %s\n"
"\tshould correct the problem. "), "\tshould correct the problem. "), timestr);
timestr); (void) strlcat(buf, temp, size);
} else { } else {
(void) printf(dgettext(TEXT_DOMAIN, (void) strlcat(buf, dgettext(TEXT_DOMAIN,
"\tReverting the pool to an earlier state " "\tReverting the pool to an earlier state "
"should correct the problem.\n\t")); "should correct the problem.\n\t"), size);
} }
if (loss > 120) { if (loss > 120) {
(void) printf(dgettext(TEXT_DOMAIN, (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
"Approximately %lld minutes of data\n" "Approximately %lld minutes of data\n"
"\tmust be discarded, irreversibly. "), "\tmust be discarded, irreversibly. "),
((longlong_t)loss + 30) / 60); ((longlong_t)loss + 30) / 60);
(void) strlcat(buf, temp, size);
} else if (loss > 0) { } else if (loss > 0) {
(void) printf(dgettext(TEXT_DOMAIN, (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
"Approximately %lld seconds of data\n" "Approximately %lld seconds of data\n"
"\tmust be discarded, irreversibly. "), "\tmust be discarded, irreversibly. "),
(longlong_t)loss); (longlong_t)loss);
(void) strlcat(buf, temp, size);
} }
if (edata != 0 && edata != UINT64_MAX) { if (edata != 0 && edata != UINT64_MAX) {
if (edata == 1) { if (edata == 1) {
(void) printf(dgettext(TEXT_DOMAIN, (void) strlcat(buf, dgettext(TEXT_DOMAIN,
"After rewind, at least\n" "After rewind, at least\n"
"\tone persistent user-data error will remain. ")); "\tone persistent user-data error will remain. "),
size);
} else { } else {
(void) printf(dgettext(TEXT_DOMAIN, (void) strlcat(buf, dgettext(TEXT_DOMAIN,
"After rewind, several\n" "After rewind, several\n"
"\tpersistent user-data errors will remain. ")); "\tpersistent user-data errors will remain. "),
size);
} }
} }
(void) printf(dgettext(TEXT_DOMAIN, (void) snprintf(temp, 1024, dgettext(TEXT_DOMAIN,
"Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "), "Recovery can be attempted\n\tby executing 'zpool %s -F %s'. "),
reason >= 0 ? "clear" : "import", name); reason >= 0 ? "clear" : "import", name);
(void) strlcat(buf, temp, size);
(void) printf(dgettext(TEXT_DOMAIN, (void) strlcat(buf, dgettext(TEXT_DOMAIN,
"A scrub of the pool\n" "A scrub of the pool\n"
"\tis strongly recommended after recovery.\n")); "\tis strongly recommended after recovery.\n"), size);
return; return;
no_info: no_info:
(void) printf(dgettext(TEXT_DOMAIN, (void) strlcat(buf, dgettext(TEXT_DOMAIN,
"Destroy and re-create the pool from\n\ta backup source.\n")); "Destroy and re-create the pool from\n\ta backup source.\n"), size);
} }
/* /*
@ -2135,9 +2135,10 @@ print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
} }
void void
zpool_print_unsup_feat(nvlist_t *config) zpool_collect_unsup_feat(nvlist_t *config, char *buf, size_t size)
{ {
nvlist_t *nvinfo, *unsup_feat; nvlist_t *nvinfo, *unsup_feat;
char temp[512];
nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO); nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
unsup_feat = fnvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT); unsup_feat = fnvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT);
@ -2145,10 +2146,14 @@ zpool_print_unsup_feat(nvlist_t *config)
for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL); for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL);
nvp != NULL; nvp = nvlist_next_nvpair(unsup_feat, nvp)) { nvp != NULL; nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
const char *desc = fnvpair_value_string(nvp); const char *desc = fnvpair_value_string(nvp);
if (strlen(desc) > 0) if (strlen(desc) > 0) {
(void) printf("\t%s (%s)\n", nvpair_name(nvp), desc); (void) snprintf(temp, 512, "\t%s (%s)\n",
else nvpair_name(nvp), desc);
(void) printf("\t%s\n", nvpair_name(nvp)); (void) strlcat(buf, temp, size);
} else {
(void) snprintf(temp, 512, "\t%s\n", nvpair_name(nvp));
(void) strlcat(buf, temp, size);
}
} }
} }
@ -2171,6 +2176,7 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
const char *origname; const char *origname;
int ret; int ret;
int error = 0; int error = 0;
char buf[2048];
char errbuf[ERRBUFLEN]; char errbuf[ERRBUFLEN];
origname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME); origname = fnvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME);
@ -2253,7 +2259,9 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
(void) printf(dgettext(TEXT_DOMAIN, "This " (void) printf(dgettext(TEXT_DOMAIN, "This "
"pool uses the following feature(s) not " "pool uses the following feature(s) not "
"supported by this system:\n")); "supported by this system:\n"));
zpool_print_unsup_feat(nv); memset(buf, 0, 2048);
zpool_collect_unsup_feat(nv, buf, 2048);
(void) printf("%s", buf);
if (nvlist_exists(nvinfo, if (nvlist_exists(nvinfo,
ZPOOL_CONFIG_CAN_RDONLY)) { ZPOOL_CONFIG_CAN_RDONLY)) {
(void) printf(dgettext(TEXT_DOMAIN, (void) printf(dgettext(TEXT_DOMAIN,
@ -2352,8 +2360,11 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
break; break;
default: default:
(void) zpool_standard_error(hdl, error, desc); (void) zpool_standard_error(hdl, error, desc);
memset(buf, 0, 2048);
zpool_explain_recover(hdl, zpool_explain_recover(hdl,
newname ? origname : thename, -error, nv); newname ? origname : thename, -error, nv,
buf, 2048);
(void) printf("\t%s", buf);
break; break;
} }

View File

@ -126,7 +126,9 @@
<elf-symbol name='atomic_swap_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_swap_uint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='atomic_swap_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_swap_ulong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='atomic_swap_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='atomic_swap_ushort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='format_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='get_system_hostid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='get_timestamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getexecname' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getextmntent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='getmntany' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -1110,6 +1112,18 @@
<parameter type-id='3502e3ff' name='timestamp_fmt'/> <parameter type-id='3502e3ff' name='timestamp_fmt'/>
<return type-id='48b5725f'/> <return type-id='48b5725f'/>
</function-decl> </function-decl>
<function-decl name='get_timestamp' mangled-name='get_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='get_timestamp'>
<parameter type-id='3502e3ff' name='timestamp_fmt'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='95e97e5e' name='len'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='format_timestamp' mangled-name='format_timestamp' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='format_timestamp'>
<parameter type-id='c9d12d66' name='t'/>
<parameter type-id='26a90f95' name='buf'/>
<parameter type-id='95e97e5e' name='len'/>
<return type-id='48b5725f'/>
</function-decl>
</abi-instr> </abi-instr>
<abi-instr address-size='64' path='lib/libzfs_core/libzfs_core.c' language='LANG_C99'> <abi-instr address-size='64' path='lib/libzfs_core/libzfs_core.c' language='LANG_C99'>
<array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'> <array-type-def dimensions='1' type-id='03085adc' size-in-bits='192' id='083f8d58'>

View File

@ -41,6 +41,7 @@
.Op Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns .Op Fl c Op Ar SCRIPT1 Ns Oo , Ns Ar SCRIPT2 Oc Ns
.Oo Ar pool Oc Ns .Oo Ar pool Oc Ns
.Op Ar interval Op Ar count .Op Ar interval Op Ar count
.Op Fl j Op Ar --json-int, --json-flat-vdevs, --json-pool-key-guid
. .
.Sh DESCRIPTION .Sh DESCRIPTION
Displays the detailed health status for the given pools. Displays the detailed health status for the given pools.
@ -69,6 +70,17 @@ See the
option of option of
.Nm zpool Cm iostat .Nm zpool Cm iostat
for complete details. for complete details.
.It Fl j Op Ar --json-int, --json-flat-vdevs, --json-pool-key-guid
Display the status for ZFS pools in JSON format.
Specify
.Sy --json-int
to display numbers in integer format instead of strings.
Specify
.Sy --json-flat-vdevs
to display vdevs in flat hierarchy instead of nested vdev objects.
Specify
.Sy --json-pool-key-guid
to set pool GUID as key for pool objects instead of pool names.
.It Fl D .It Fl D
Display a histogram of deduplication statistics, showing the allocated Display a histogram of deduplication statistics, showing the allocated
.Pq physically present on disk .Pq physically present on disk
@ -161,6 +173,175 @@ rpool 14.6G 54.9G 4 55 250K 2.69M
---------- ----- ----- ----- ----- ----- ----- ---- ---------- ----- ----- ----- ----- ----- ----- ----
.Ed .Ed
. .
.Ss Example 2 : No Display the status output in JSON format
.Nm zpool Cm status No can output in JSON format if
.Fl j
is specified.
.Fl c
can be used to run a script on each VDEV.
.Bd -literal -compact -offset Ds
.No # Nm zpool Cm status Fl j Fl c Pa vendor , Ns Pa model , Ns Pa size | Nm jq
{
"output_version": {
"command": "zpool status",
"vers_major": 0,
"vers_minor": 1
},
"pools": {
"tank": {
"name": "tank",
"state": "ONLINE",
"guid": "3920273586464696295",
"txg": "16597",
"spa_version": "5000",
"zpl_version": "5",
"status": "OK",
"vdevs": {
"tank": {
"name": "tank",
"alloc_space": "62.6G",
"total_space": "15.0T",
"def_space": "11.3T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vdevs": {
"raidz1-0": {
"name": "raidz1-0",
"vdev_type": "raidz",
"guid": "763132626387621737",
"state": "HEALTHY",
"alloc_space": "62.5G",
"total_space": "10.9T",
"def_space": "7.26T",
"rep_dev_size": "10.9T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vdevs": {
"ca1eb824-c371-491d-ac13-37637e35c683": {
"name": "ca1eb824-c371-491d-ac13-37637e35c683",
"vdev_type": "disk",
"guid": "12841765308123764671",
"path": "/dev/disk/by-partuuid/ca1eb824-c371-491d-ac13-37637e35c683",
"state": "HEALTHY",
"rep_dev_size": "3.64T",
"phys_space": "3.64T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vendor": "ATA",
"model": "WDC WD40EFZX-68AWUN0",
"size": "3.6T"
},
"97cd98fb-8fb8-4ac4-bc84-bd8950a7ace7": {
"name": "97cd98fb-8fb8-4ac4-bc84-bd8950a7ace7",
"vdev_type": "disk",
"guid": "1527839927278881561",
"path": "/dev/disk/by-partuuid/97cd98fb-8fb8-4ac4-bc84-bd8950a7ace7",
"state": "HEALTHY",
"rep_dev_size": "3.64T",
"phys_space": "3.64T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vendor": "ATA",
"model": "WDC WD40EFZX-68AWUN0",
"size": "3.6T"
},
"e9ddba5f-f948-4734-a472-cb8aa5f0ff65": {
"name": "e9ddba5f-f948-4734-a472-cb8aa5f0ff65",
"vdev_type": "disk",
"guid": "6982750226085199860",
"path": "/dev/disk/by-partuuid/e9ddba5f-f948-4734-a472-cb8aa5f0ff65",
"state": "HEALTHY",
"rep_dev_size": "3.64T",
"phys_space": "3.64T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vendor": "ATA",
"model": "WDC WD40EFZX-68AWUN0",
"size": "3.6T"
}
}
}
}
}
},
"dedup": {
"mirror-2": {
"name": "mirror-2",
"vdev_type": "mirror",
"guid": "2227766268377771003",
"state": "HEALTHY",
"alloc_space": "89.1M",
"total_space": "3.62T",
"def_space": "3.62T",
"rep_dev_size": "3.62T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vdevs": {
"db017360-d8e9-4163-961b-144ca75293a3": {
"name": "db017360-d8e9-4163-961b-144ca75293a3",
"vdev_type": "disk",
"guid": "17880913061695450307",
"path": "/dev/disk/by-partuuid/db017360-d8e9-4163-961b-144ca75293a3",
"state": "HEALTHY",
"rep_dev_size": "3.63T",
"phys_space": "3.64T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vendor": "ATA",
"model": "WDC WD40EFZX-68AWUN0",
"size": "3.6T"
},
"952c3baf-b08a-4a8c-b7fa-33a07af5fe6f": {
"name": "952c3baf-b08a-4a8c-b7fa-33a07af5fe6f",
"vdev_type": "disk",
"guid": "10276374011610020557",
"path": "/dev/disk/by-partuuid/952c3baf-b08a-4a8c-b7fa-33a07af5fe6f",
"state": "HEALTHY",
"rep_dev_size": "3.63T",
"phys_space": "3.64T",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vendor": "ATA",
"model": "WDC WD40EFZX-68AWUN0",
"size": "3.6T"
}
}
}
},
"special": {
"25d418f8-92bd-4327-b59f-7ef5d5f50d81": {
"name": "25d418f8-92bd-4327-b59f-7ef5d5f50d81",
"vdev_type": "disk",
"guid": "3935742873387713123",
"path": "/dev/disk/by-partuuid/25d418f8-92bd-4327-b59f-7ef5d5f50d81",
"state": "HEALTHY",
"alloc_space": "37.4M",
"total_space": "444G",
"def_space": "444G",
"rep_dev_size": "444G",
"phys_space": "447G",
"read_errors": "0",
"write_errors": "0",
"checksum_errors": "0",
"vendor": "ATA",
"model": "Micron_5300_MTFDDAK480TDS",
"size": "447.1G"
}
},
"error_count": "0"
}
}
}
.Ed
.
.Sh SEE ALSO .Sh SEE ALSO
.Xr zpool-events 8 , .Xr zpool-events 8 ,
.Xr zpool-history 8 , .Xr zpool-history 8 ,