xref: /freebsd/sys/contrib/openzfs/cmd/zpool/zpool.d/iostat (revision d5b0e70f7e04d971691517ce1304d86a1e367e2e)
1#!/bin/sh
2#
3# Display most relevant iostat bandwidth/latency numbers.  The output is
4# dependent on the name of the script/symlink used to call it.
5#
6
7helpstr="
8iostat:		Show iostat values since boot (summary page).
9iostat-1s:	Do a single 1-second iostat sample and show values.
10iostat-10s:	Do a single 10-second iostat sample and show values."
11
12script="${0##*/}"
13if [ "$1" = "-h" ] ; then
14	echo "$helpstr" | grep "$script:" | tr -s '\t' | cut -f 2-
15	exit
16fi
17
18# Sometimes, UPATH ends up /dev/(null).
19# That should be corrected, but for now...
20# shellcheck disable=SC2154
21if [ ! -b "$VDEV_UPATH" ]; then
22	somepath="${VDEV_PATH}"
23else
24	somepath="${VDEV_UPATH}"
25fi
26
27if [ "$script" = "iostat-1s" ] ; then
28	# Do a single one-second sample
29	interval=1
30	# Don't show summary stats
31	brief="yes"
32elif [ "$script" = "iostat-10s" ] ; then
33	# Do a single ten-second sample
34	interval=10
35	# Don't show summary stats
36	brief="yes"
37fi
38
39if [ -f "$somepath" ] ; then
40	# We're a file-based vdev, iostat doesn't work on us.  Do nothing.
41	exit
42fi
43
44if [ "$(uname)" = "FreeBSD" ]; then
45	out=$(iostat -dKx \
46		${interval:+"-w $interval"} \
47		${interval:+"-c 1"} \
48		"$somepath" | tail -n 2)
49else
50	out=$(iostat -kx \
51		${brief:+"-y"} \
52		${interval:+"$interval"} \
53		${interval:+"1"} \
54		"$somepath" | grep -v '^$' | tail -n 2)
55fi
56
57
58# Sample output (we want the last two lines):
59#
60# Linux 2.6.32-642.13.1.el6.x86_64 (centos68) 	03/09/2017 	_x86_64_	(6 CPU)
61#
62# avg-cpu:  %user   %nice %system %iowait  %steal   %idle
63#           0.00    0.00    0.00    0.00    0.00  100.00
64#
65# Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
66# sdb               0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
67#
68
69# Get the column names
70cols=$(echo "$out" | head -n 1)
71
72# Get the values and tab separate them to make them cut-able.
73vals=$(echo "$out" | tail -n 1 | tr -s '[:space:]' '\t')
74
75i=0
76for col in $cols ; do
77	i=$((i+1))
78	# Skip the first column since it's just the device name
79	if [ "$i" -eq 1 ]; then
80		continue
81	fi
82
83	# Get i'th value
84	val=$(echo "$vals" | cut -f "$i")
85	echo "$col=$val"
86done
87