From 90cc8c3c50acda34dc6fa05dee475f443e71996a Mon Sep 17 00:00:00 2001 From: HTJ Date: Mon, 19 Dec 2016 18:41:17 +0100 Subject: [PATCH] zpool iostat -k shows kind of vdevs: ssd, hdd, file or mixed. --- cmd/zpool/zpool_main.c | 54 +++++++++++++++++++++++++++++++++++++----- man/man8/zpool.8 | 13 ++++++++-- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index a96c3c6e2667..66d744ae32a1 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -152,8 +152,9 @@ enum iostat_type { IOS_DEFAULT = 0, IOS_LATENCY = 1, IOS_QUEUES = 2, - IOS_L_HISTO = 3, - IOS_RQ_HISTO = 4, + IOS_KIND = 3, + IOS_L_HISTO = 4, + IOS_RQ_HISTO = 5, IOS_COUNT, /* always last element */ }; @@ -161,6 +162,7 @@ enum iostat_type { #define IOS_DEFAULT_M (1ULL << IOS_DEFAULT) #define IOS_LATENCY_M (1ULL << IOS_LATENCY) #define IOS_QUEUES_M (1ULL << IOS_QUEUES) +#define IOS_KIND_M (1ULL << IOS_KIND) #define IOS_L_HISTO_M (1ULL << IOS_L_HISTO) #define IOS_RQ_HISTO_M (1ULL << IOS_RQ_HISTO) @@ -197,6 +199,9 @@ static const char *vsx_type_to_nvlist[IOS_COUNT][11] = { ZPOOL_CONFIG_VDEV_ASYNC_W_ACTIVE_QUEUE, ZPOOL_CONFIG_VDEV_SCRUB_ACTIVE_QUEUE, NULL}, + [IOS_KIND] = { + ZPOOL_CONFIG_VDEV_KIND, + NULL}, [IOS_RQ_HISTO] = { ZPOOL_CONFIG_VDEV_SYNC_IND_R_HISTO, ZPOOL_CONFIG_VDEV_SYNC_AGG_R_HISTO, @@ -313,7 +318,7 @@ get_usage(zpool_help_t idx) "[-R root] [-F [-n]]\n" "\t [newpool]\n")); case HELP_IOSTAT: - return (gettext("\tiostat [-c CMD] [-T d | u] [-ghHLpPvy] " + return (gettext("\tiostat [-c CMD] [-T d | u] [-ghHkLpPvy] " "[[-lq]|[-r|-w]]\n" "\t [[pool ...]|[pool vdev ...]|[vdev ...]] " "[interval [count]]\n")); @@ -1456,6 +1461,30 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max, return (max); } +static const char * +kind_mark(nvlist_t *nv) +{ + nvlist_t *nvx; + uint64_t kind = VDEV_KIND_UNKNOWN; + + if (nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_VDEV_STATS_EX, &nvx) == 0) + nvlist_lookup_uint64(nvx, ZPOOL_CONFIG_VDEV_KIND, + &kind); + + switch (kind) { + case VDEV_KIND_SSD: + return ("ssd"); + case VDEV_KIND_FILE: + return ("file"); + case VDEV_KIND_MIXED: + return ("mix"); + case VDEV_KIND_HDD: + return ("hdd"); + default: + return ("-"); + } +} + typedef struct spare_cbdata { uint64_t cb_guid; zpool_handle_t *cb_zhp; @@ -2629,6 +2658,7 @@ static const name_and_columns_t iostat_top_labels[][IOSTAT_MAX_LABELS] = [IOS_QUEUES] = {{"syncq_read", 2}, {"syncq_write", 2}, {"asyncq_read", 2}, {"asyncq_write", 2}, {"scrubq_read", 2}, {NULL}}, + [IOS_KIND] = {{"", 1}, {NULL}}, [IOS_L_HISTO] = {{"total_wait", 2}, {"disk_wait", 2}, {"sync_queue", 2}, {"async_queue", 2}, {NULL}}, [IOS_RQ_HISTO] = {{"sync_read", 2}, {"sync_write", 2}, @@ -2645,6 +2675,7 @@ static const name_and_columns_t iostat_bottom_labels[][IOSTAT_MAX_LABELS] = {"write"}, {"read"}, {"write"}, {"wait"}, {NULL}}, [IOS_QUEUES] = {{"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"}, {"pend"}, {"activ"}, {NULL}}, + [IOS_KIND] = {{"kind"}, {NULL}}, [IOS_L_HISTO] = {{"read"}, {"write"}, {"read"}, {"write"}, {"read"}, {"write"}, {"read"}, {"write"}, {"scrub"}, {NULL}}, [IOS_RQ_HISTO] = {{"ind"}, {"agg"}, {"ind"}, {"agg"}, {"ind"}, {"agg"}, @@ -2707,9 +2738,10 @@ default_column_width(iostat_cbdata_t *cb, enum iostat_type type) [IOS_DEFAULT] = 15, /* 1PB capacity */ [IOS_LATENCY] = 10, /* 1B ns = 10sec */ [IOS_QUEUES] = 6, /* 1M queue entries */ + [IOS_KIND] = 4, /* kind/file/ssd/hdd/mix */ }; - if (cb->cb_literal) + if (cb->cb_literal || type == IOS_KIND) column_width = widths[type]; return (column_width); @@ -3412,6 +3444,9 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv, print_iostat_latency(cb, oldnv, newnv, scale); if (cb->cb_flags & IOS_QUEUES_M) print_iostat_queues(cb, oldnv, newnv, scale); + if (cb->cb_flags & IOS_KIND_M) + printf("%s%4s", cb->cb_scripted ? "\t" : " ", + kind_mark(newnv)); if (cb->cb_flags & IOS_ANYHISTO_M) { printf("\n"); print_iostat_histos(cb, oldnv, newnv, scale, name); @@ -3960,7 +3995,7 @@ fsleep(float sec) { /* - * zpool iostat [-c CMD] [-ghHLpPvy] [[-lq]|[-r|-w]] [-n name] [-T d|u] + * zpool iostat [-c CMD] [-ghHkLpPvy] [[-lq]|[-r|-w]] [-n name] [-T d|u] * [[ pool ...]|[pool vdev ...]|[vdev ...]] * [interval [count]] * @@ -3973,6 +4008,7 @@ fsleep(float sec) { * -p Display values in parsable (exact) format. * -H Scripted mode. Don't display headers, and separate properties * by a single tab. + * -k Display kind of device, e.g. solid-state or mixed. * -l Display average latency * -q Display queue depths * -w Display latency histograms @@ -4001,6 +4037,7 @@ zpool_do_iostat(int argc, char **argv) boolean_t guid = B_FALSE; boolean_t follow_links = B_FALSE; boolean_t full_name = B_FALSE; + boolean_t kind = B_FALSE; iostat_cbdata_t cb = { 0 }; char *cmd = NULL; @@ -4011,7 +4048,7 @@ zpool_do_iostat(int argc, char **argv) uint64_t unsupported_flags; /* check options */ - while ((c = getopt(argc, argv, "c:gLPT:vyhplqrwH")) != -1) { + while ((c = getopt(argc, argv, "c:gLPT:vyhpklqrwH")) != -1) { switch (c) { case 'c': cmd = optarg; @@ -4034,6 +4071,9 @@ zpool_do_iostat(int argc, char **argv) case 'p': parsable = B_TRUE; break; + case 'k': + kind = B_TRUE; + break; case 'l': latency = B_TRUE; break; @@ -4189,6 +4229,8 @@ zpool_do_iostat(int argc, char **argv) cb.cb_flags |= IOS_LATENCY_M; if (queues) cb.cb_flags |= IOS_QUEUES_M; + if (kind) + cb.cb_flags |= IOS_KIND_M; } /* diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 index 883d1173973f..10e08121badd 100644 --- a/man/man8/zpool.8 +++ b/man/man8/zpool.8 @@ -96,7 +96,7 @@ zpool \- configures ZFS storage pools .LP .nf -\fB\fBzpool iostat\fR [\fB-c\fR \fBCMD\fR] [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-ghHLpPvy\fR] [\fB-lq\fR]|[\fB-r\fR|-\fBw\fR]] +\fB\fBzpool iostat\fR [\fB-c\fR \fBCMD\fR] [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-ghHkLpPvy\fR] [\fB-lq\fR]|[\fB-r\fR|-\fBw\fR]] [[\fIpool\fR ...]|[\fIpool vdev\fR ...]|[\fIvdev\fR ...]] [\fIinterval\fR[\fIcount\fR]]\fR .fi @@ -1523,7 +1523,7 @@ Scan using the default search path, the libblkid cache will not be consulted. A .sp .ne 2 .na -\fB\fBzpool iostat\fR [\fB-c\fR \fBCMD\fR] [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-ghHLpPvy\fR] [[\fB-lq\fR]|[\fB-r\fR|\fB-w\fR]] [[\fIpool\fR ...]|[\fIpool vdev\fR ...]|[\fIvdev\fR ...]] [\fIinterval\fR[\fIcount\fR]]\fR +\fB\fBzpool iostat\fR [\fB-c\fR \fBCMD\fR] [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-ghHkLpPvy\fR] [[\fB-lq\fR]|[\fB-r\fR|\fB-w\fR]] [[\fIpool\fR ...]|[\fIpool vdev\fR ...]|[\fIvdev\fR ...]] [\fIinterval\fR[\fIcount\fR]]\fR .ad .sp .6 @@ -1585,6 +1585,15 @@ Display vdev GUIDs instead of the normal device names. These GUIDs can be used i Scripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space. .RE +.sp +.ne 2 +.na +\fB\fB-k\fR\fR +.ad +.RS 12n +Display the kind of device a pool or vdev is based on: ssd, hdd or file. Mixed mirror vdevs that have both ssd (or file) and hdd members are marked "mix". A pool is considered mixed if all members are at least mixed, i.e. no pure hdd. +.RE + .sp .ne 2 .na