1dcbf3bd6SGeorge Wilson#
2dcbf3bd6SGeorge Wilson# This file and its contents are supplied under the terms of the
3dcbf3bd6SGeorge Wilson# Common Development and Distribution License ("CDDL"), version 1.0.
4dcbf3bd6SGeorge Wilson# You may only use this file in accordance with the terms of version
5dcbf3bd6SGeorge Wilson# 1.0 of the CDDL.
6dcbf3bd6SGeorge Wilson#
7dcbf3bd6SGeorge Wilson# A full copy of the text of the CDDL should have accompanied this
8dcbf3bd6SGeorge Wilson# source.  A copy of the CDDL is also available via the Internet at
9dcbf3bd6SGeorge Wilson# http://www.illumos.org/license/CDDL.
10dcbf3bd6SGeorge Wilson#
11dcbf3bd6SGeorge Wilson
12dcbf3bd6SGeorge Wilson#
131d32ba66SJohn Wren Kennedy# Copyright (c) 2015, 2016 by Delphix. All rights reserved.
14dcbf3bd6SGeorge Wilson#
15dcbf3bd6SGeorge Wilson
16dcbf3bd6SGeorge Wilson. $STF_SUITE/include/libtest.shlib
17dcbf3bd6SGeorge Wilson
18dcbf3bd6SGeorge Wilson# If neither is specified, do a nightly run.
19dcbf3bd6SGeorge Wilson[[ -z $PERF_REGRESSION_WEEKLY ]] && export PERF_REGRESSION_NIGHTLY=1
20dcbf3bd6SGeorge Wilson
21dcbf3bd6SGeorge Wilson# Default runtime for each type of test run.
22dcbf3bd6SGeorge Wilsonexport PERF_RUNTIME_WEEKLY=$((30 * 60))
23dcbf3bd6SGeorge Wilsonexport PERF_RUNTIME_NIGHTLY=$((10 * 60))
24dcbf3bd6SGeorge Wilson
25dcbf3bd6SGeorge Wilson# Default fs creation options
26dcbf3bd6SGeorge Wilsonexport PERF_FS_OPTS=${PERF_FS_OPTS:-'-o recsize=8k -o compress=lz4' \
27dcbf3bd6SGeorge Wilson    ' -o checksum=sha256 -o redundant_metadata=most'}
28dcbf3bd6SGeorge Wilson
29dcbf3bd6SGeorge Wilsonfunction get_sync_str
30dcbf3bd6SGeorge Wilson{
31dcbf3bd6SGeorge Wilson	typeset sync=$1
32dcbf3bd6SGeorge Wilson	typeset sync_str=''
33dcbf3bd6SGeorge Wilson
34dcbf3bd6SGeorge Wilson	[[ $sync -eq 0 ]] && sync_str='async'
35dcbf3bd6SGeorge Wilson	[[ $sync -eq 1 ]] && sync_str='sync'
36dcbf3bd6SGeorge Wilson	echo $sync_str
37dcbf3bd6SGeorge Wilson}
38dcbf3bd6SGeorge Wilson
39*c373aa8bSJohn Wren Kennedyfunction get_suffix
40*c373aa8bSJohn Wren Kennedy{
41*c373aa8bSJohn Wren Kennedy	typeset threads=$1
42*c373aa8bSJohn Wren Kennedy	typeset sync=$2
43*c373aa8bSJohn Wren Kennedy	typeset iosize=$3
44*c373aa8bSJohn Wren Kennedy
45*c373aa8bSJohn Wren Kennedy	typeset sync_str=$(get_sync_str $sync)
46*c373aa8bSJohn Wren Kennedy	typeset filesystems=$(get_nfilesystems)
47*c373aa8bSJohn Wren Kennedy
48*c373aa8bSJohn Wren Kennedy	typeset suffix="$sync_str.$iosize-ios"
49*c373aa8bSJohn Wren Kennedy	suffix="$suffix.$threads-threads.$filesystems-filesystems"
50*c373aa8bSJohn Wren Kennedy	echo $suffix
51*c373aa8bSJohn Wren Kennedy}
52*c373aa8bSJohn Wren Kennedy
53*c373aa8bSJohn Wren Kennedyfunction do_fio_run_impl
54*c373aa8bSJohn Wren Kennedy{
55*c373aa8bSJohn Wren Kennedy	typeset script=$1
56*c373aa8bSJohn Wren Kennedy	typeset do_recreate=$2
57*c373aa8bSJohn Wren Kennedy	typeset clear_cache=$3
58*c373aa8bSJohn Wren Kennedy
59*c373aa8bSJohn Wren Kennedy	typeset threads=$4
60*c373aa8bSJohn Wren Kennedy	typeset threads_per_fs=$5
61*c373aa8bSJohn Wren Kennedy	typeset sync=$6
62*c373aa8bSJohn Wren Kennedy	typeset iosize=$7
63*c373aa8bSJohn Wren Kennedy
64*c373aa8bSJohn Wren Kennedy	typeset sync_str=$(get_sync_str $sync)
65*c373aa8bSJohn Wren Kennedy	log_note "Running with $threads $sync_str threads, $iosize ios"
66*c373aa8bSJohn Wren Kennedy
67*c373aa8bSJohn Wren Kennedy	if [[ -n $threads_per_fs && $threads_per_fs -ne 0 ]]; then
68*c373aa8bSJohn Wren Kennedy		log_must test $do_recreate
69*c373aa8bSJohn Wren Kennedy		verify_threads_per_fs $threads $threads_per_fs
70*c373aa8bSJohn Wren Kennedy	fi
71*c373aa8bSJohn Wren Kennedy
72*c373aa8bSJohn Wren Kennedy	if $do_recreate; then
73*c373aa8bSJohn Wren Kennedy		recreate_perf_pool
74*c373aa8bSJohn Wren Kennedy
75*c373aa8bSJohn Wren Kennedy		#
76*c373aa8bSJohn Wren Kennedy		# A value of zero for "threads_per_fs" is "special", and
77*c373aa8bSJohn Wren Kennedy		# means a single filesystem should be used, regardless
78*c373aa8bSJohn Wren Kennedy		# of the number of threads.
79*c373aa8bSJohn Wren Kennedy		#
80*c373aa8bSJohn Wren Kennedy		if [[ -n $threads_per_fs && $threads_per_fs -ne 0 ]]; then
81*c373aa8bSJohn Wren Kennedy			populate_perf_filesystems $((threads / threads_per_fs))
82*c373aa8bSJohn Wren Kennedy		else
83*c373aa8bSJohn Wren Kennedy			populate_perf_filesystems 1
84*c373aa8bSJohn Wren Kennedy		fi
85*c373aa8bSJohn Wren Kennedy	fi
86*c373aa8bSJohn Wren Kennedy
87*c373aa8bSJohn Wren Kennedy	if $clear_cache; then
88*c373aa8bSJohn Wren Kennedy		# Clear the ARC
89*c373aa8bSJohn Wren Kennedy		zpool export $PERFPOOL
90*c373aa8bSJohn Wren Kennedy		zpool import $PERFPOOL
91*c373aa8bSJohn Wren Kennedy	fi
92*c373aa8bSJohn Wren Kennedy
93*c373aa8bSJohn Wren Kennedy	if [[ -n $ZINJECT_DELAYS ]]; then
94*c373aa8bSJohn Wren Kennedy		apply_zinject_delays
95*c373aa8bSJohn Wren Kennedy	else
96*c373aa8bSJohn Wren Kennedy		log_note "No per-device commands to execute."
97*c373aa8bSJohn Wren Kennedy	fi
98*c373aa8bSJohn Wren Kennedy
99*c373aa8bSJohn Wren Kennedy	#
100*c373aa8bSJohn Wren Kennedy	# Allow this to be overridden by the individual test case. This
101*c373aa8bSJohn Wren Kennedy	# can be used to run the FIO job against something other than
102*c373aa8bSJohn Wren Kennedy	# the default filesystem (e.g. against a clone).
103*c373aa8bSJohn Wren Kennedy	#
104*c373aa8bSJohn Wren Kennedy	export DIRECTORY=$(get_directory)
105*c373aa8bSJohn Wren Kennedy	log_note "DIRECTORY: " $DIRECTORY
106*c373aa8bSJohn Wren Kennedy
107*c373aa8bSJohn Wren Kennedy	export RUNTIME=$PERF_RUNTIME
108*c373aa8bSJohn Wren Kennedy	export FILESIZE=$((TOTAL_SIZE / threads))
109*c373aa8bSJohn Wren Kennedy	export NUMJOBS=$threads
110*c373aa8bSJohn Wren Kennedy	export SYNC_TYPE=$sync
111*c373aa8bSJohn Wren Kennedy	export BLOCKSIZE=$iosize
112*c373aa8bSJohn Wren Kennedy	sync
113*c373aa8bSJohn Wren Kennedy
114*c373aa8bSJohn Wren Kennedy	# This will be part of the output filename.
115*c373aa8bSJohn Wren Kennedy	typeset suffix=$(get_suffix $threads $sync $iosize)
116*c373aa8bSJohn Wren Kennedy
117*c373aa8bSJohn Wren Kennedy	# Start the data collection
118*c373aa8bSJohn Wren Kennedy	do_collect_scripts $suffix
119*c373aa8bSJohn Wren Kennedy
120*c373aa8bSJohn Wren Kennedy	# Define output file
121*c373aa8bSJohn Wren Kennedy	typeset logbase="$(get_perf_output_dir)/$(basename \
122*c373aa8bSJohn Wren Kennedy	    $SUDO_COMMAND)"
123*c373aa8bSJohn Wren Kennedy	typeset outfile="$logbase.fio.$suffix"
124*c373aa8bSJohn Wren Kennedy
125*c373aa8bSJohn Wren Kennedy	# Start the load
126*c373aa8bSJohn Wren Kennedy	log_must fio --output $outfile $FIO_SCRIPTS/$script
127*c373aa8bSJohn Wren Kennedy}
128*c373aa8bSJohn Wren Kennedy
129dcbf3bd6SGeorge Wilson#
130dcbf3bd6SGeorge Wilson# This function will run fio in a loop, according to the .fio file passed
131dcbf3bd6SGeorge Wilson# in and a number of environment variables. The following variables can be
132dcbf3bd6SGeorge Wilson# set before launching zfstest to override the defaults.
133dcbf3bd6SGeorge Wilson#
134dcbf3bd6SGeorge Wilson# PERF_RUNTIME: The time in seconds each fio invocation should run.
135dcbf3bd6SGeorge Wilson# PERF_RUNTYPE: A human readable tag that appears in logs. The defaults are
136dcbf3bd6SGeorge Wilson#    nightly and weekly.
137dcbf3bd6SGeorge Wilson# PERF_NTHREADS: A list of how many threads each fio invocation will use.
138dcbf3bd6SGeorge Wilson# PERF_SYNC_TYPES: Whether to use (O_SYNC) or not. 1 is sync IO, 0 is async IO.
139dcbf3bd6SGeorge Wilson# PERF_IOSIZES: A list of blocksizes in which each fio invocation will do IO.
140dcbf3bd6SGeorge Wilson# PERF_COLLECT_SCRIPTS: A comma delimited list of 'command args, logfile_tag'
141dcbf3bd6SGeorge Wilson#    pairs that will be added to the scripts specified in each test.
142dcbf3bd6SGeorge Wilson#
143dcbf3bd6SGeorge Wilsonfunction do_fio_run
144dcbf3bd6SGeorge Wilson{
145dcbf3bd6SGeorge Wilson	typeset script=$1
146dcbf3bd6SGeorge Wilson	typeset do_recreate=$2
147dcbf3bd6SGeorge Wilson	typeset clear_cache=$3
148*c373aa8bSJohn Wren Kennedy	typeset threads threads_per_fs sync iosize
149dcbf3bd6SGeorge Wilson
150dcbf3bd6SGeorge Wilson	for threads in $PERF_NTHREADS; do
151*c373aa8bSJohn Wren Kennedy		for threads_per_fs in $PERF_NTHREADS_PER_FS; do
152*c373aa8bSJohn Wren Kennedy			for sync in $PERF_SYNC_TYPES; do
153*c373aa8bSJohn Wren Kennedy				for iosize in $PERF_IOSIZES; do
154*c373aa8bSJohn Wren Kennedy					do_fio_run_impl \
155*c373aa8bSJohn Wren Kennedy					    $script \
156*c373aa8bSJohn Wren Kennedy					    $do_recreate \
157*c373aa8bSJohn Wren Kennedy					    $clear_cache \
158*c373aa8bSJohn Wren Kennedy					    $threads \
159*c373aa8bSJohn Wren Kennedy					    $threads_per_fs \
160*c373aa8bSJohn Wren Kennedy					    $sync \
161*c373aa8bSJohn Wren Kennedy					    $iosize
162*c373aa8bSJohn Wren Kennedy				done
163dcbf3bd6SGeorge Wilson			done
164dcbf3bd6SGeorge Wilson		done
165dcbf3bd6SGeorge Wilson	done
166dcbf3bd6SGeorge Wilson}
167dcbf3bd6SGeorge Wilson
168dcbf3bd6SGeorge Wilson#
169dcbf3bd6SGeorge Wilson# This function iterates through the value pairs in $PERF_COLLECT_SCRIPTS.
170dcbf3bd6SGeorge Wilson# The script at index N is launched in the background, with its output
171dcbf3bd6SGeorge Wilson# redirected to a logfile containing the tag specified at index N + 1.
172dcbf3bd6SGeorge Wilson#
173dcbf3bd6SGeorge Wilsonfunction do_collect_scripts
174dcbf3bd6SGeorge Wilson{
175*c373aa8bSJohn Wren Kennedy	typeset suffix=$1
176dcbf3bd6SGeorge Wilson
177dcbf3bd6SGeorge Wilson	[[ -n $collect_scripts ]] || log_fail "No data collection scripts."
178dcbf3bd6SGeorge Wilson	[[ -n $PERF_RUNTIME ]] || log_fail "No runtime specified."
179dcbf3bd6SGeorge Wilson
180dcbf3bd6SGeorge Wilson	# Add in user supplied scripts and logfiles, if any.
181dcbf3bd6SGeorge Wilson	typeset oIFS=$IFS
182dcbf3bd6SGeorge Wilson	IFS=','
183dcbf3bd6SGeorge Wilson	for item in $PERF_COLLECT_SCRIPTS; do
1841d32ba66SJohn Wren Kennedy		collect_scripts+=($(echo $item | sed 's/^ *//g'))
185dcbf3bd6SGeorge Wilson	done
186dcbf3bd6SGeorge Wilson	IFS=$oIFS
187dcbf3bd6SGeorge Wilson
188dcbf3bd6SGeorge Wilson	typeset idx=0
189dcbf3bd6SGeorge Wilson	while [[ $idx -lt "${#collect_scripts[@]}" ]]; do
1901d32ba66SJohn Wren Kennedy		typeset logbase="$(get_perf_output_dir)/$(basename \
191dcbf3bd6SGeorge Wilson		    $SUDO_COMMAND)"
192dcbf3bd6SGeorge Wilson		typeset outfile="$logbase.${collect_scripts[$idx + 1]}.$suffix"
193dcbf3bd6SGeorge Wilson
1941d32ba66SJohn Wren Kennedy		timeout $PERF_RUNTIME ${collect_scripts[$idx]} >$outfile 2>&1 &
195dcbf3bd6SGeorge Wilson		((idx += 2))
196dcbf3bd6SGeorge Wilson	done
197dcbf3bd6SGeorge Wilson
198dcbf3bd6SGeorge Wilson	# Need to explicitly return 0 because timeout(1) will kill
199dcbf3bd6SGeorge Wilson	# a child process and cause us to return non-zero.
200dcbf3bd6SGeorge Wilson	return 0
201dcbf3bd6SGeorge Wilson}
202dcbf3bd6SGeorge Wilson
203dcbf3bd6SGeorge Wilson# Find a place to deposit performance data collected while under load.
204dcbf3bd6SGeorge Wilsonfunction get_perf_output_dir
205dcbf3bd6SGeorge Wilson{
206dcbf3bd6SGeorge Wilson	typeset dir="$(pwd)/perf_data"
2071d32ba66SJohn Wren Kennedy	[[ -d $dir ]] || mkdir -p $dir
208dcbf3bd6SGeorge Wilson
2091d32ba66SJohn Wren Kennedy	echo $dir
210dcbf3bd6SGeorge Wilson}
211dcbf3bd6SGeorge Wilson
212*c373aa8bSJohn Wren Kennedyfunction apply_zinject_delays
213*c373aa8bSJohn Wren Kennedy{
214*c373aa8bSJohn Wren Kennedy	typeset idx=0
215*c373aa8bSJohn Wren Kennedy	while [[ $idx -lt "${#ZINJECT_DELAYS[@]}" ]]; do
216*c373aa8bSJohn Wren Kennedy		[[ -n ${ZINJECT_DELAYS[$idx]} ]] || \
217*c373aa8bSJohn Wren Kennedy		    log_must "No zinject delay found at index: $idx"
218*c373aa8bSJohn Wren Kennedy
219*c373aa8bSJohn Wren Kennedy		for disk in $DISKS; do
220*c373aa8bSJohn Wren Kennedy			log_must zinject \
221*c373aa8bSJohn Wren Kennedy			    -d $disk -D ${ZINJECT_DELAYS[$idx]} $PERFPOOL
222*c373aa8bSJohn Wren Kennedy		done
223*c373aa8bSJohn Wren Kennedy
224*c373aa8bSJohn Wren Kennedy		((idx += 1))
225*c373aa8bSJohn Wren Kennedy	done
226*c373aa8bSJohn Wren Kennedy}
227*c373aa8bSJohn Wren Kennedy
228*c373aa8bSJohn Wren Kennedyfunction clear_zinject_delays
229*c373aa8bSJohn Wren Kennedy{
230*c373aa8bSJohn Wren Kennedy	log_must zinject -c all
231*c373aa8bSJohn Wren Kennedy}
232*c373aa8bSJohn Wren Kennedy
233dcbf3bd6SGeorge Wilson#
234*c373aa8bSJohn Wren Kennedy# Destroy and create the pool used for performance tests.
235dcbf3bd6SGeorge Wilson#
236*c373aa8bSJohn Wren Kennedyfunction recreate_perf_pool
237dcbf3bd6SGeorge Wilson{
238dcbf3bd6SGeorge Wilson	[[ -n $PERFPOOL ]] || log_fail "The \$PERFPOOL variable isn't set."
239dcbf3bd6SGeorge Wilson
240*c373aa8bSJohn Wren Kennedy	#
241*c373aa8bSJohn Wren Kennedy	# In case there's been some "leaked" zinject delays, or if the
242*c373aa8bSJohn Wren Kennedy	# performance test injected some delays itself, we clear all
243*c373aa8bSJohn Wren Kennedy	# delays before attempting to destroy the pool. Each delay
244*c373aa8bSJohn Wren Kennedy	# places a hold on the pool, so the destroy will fail if there
245*c373aa8bSJohn Wren Kennedy	# are any outstanding delays.
246*c373aa8bSJohn Wren Kennedy	#
247*c373aa8bSJohn Wren Kennedy	clear_zinject_delays
248*c373aa8bSJohn Wren Kennedy
249*c373aa8bSJohn Wren Kennedy	#
250*c373aa8bSJohn Wren Kennedy	# This function handles the case where the pool already exists,
251*c373aa8bSJohn Wren Kennedy	# and will destroy the previous pool and recreate a new pool.
252*c373aa8bSJohn Wren Kennedy	#
253*c373aa8bSJohn Wren Kennedy	create_pool $PERFPOOL $DISKS
254*c373aa8bSJohn Wren Kennedy}
255dcbf3bd6SGeorge Wilson
256*c373aa8bSJohn Wren Kennedyfunction verify_threads_per_fs
257*c373aa8bSJohn Wren Kennedy{
258*c373aa8bSJohn Wren Kennedy	typeset threads=$1
259*c373aa8bSJohn Wren Kennedy	typeset threads_per_fs=$2
260*c373aa8bSJohn Wren Kennedy
261*c373aa8bSJohn Wren Kennedy	log_must test -n $threads
262*c373aa8bSJohn Wren Kennedy	log_must test -n $threads_per_fs
263*c373aa8bSJohn Wren Kennedy
264*c373aa8bSJohn Wren Kennedy	#
265*c373aa8bSJohn Wren Kennedy	# A value of "0" is treated as a "special value", and it is
266*c373aa8bSJohn Wren Kennedy	# interpreted to mean all threads will run using a single
267*c373aa8bSJohn Wren Kennedy	# filesystem.
268*c373aa8bSJohn Wren Kennedy	#
269*c373aa8bSJohn Wren Kennedy	[[ $threads_per_fs -eq 0 ]] && return
270*c373aa8bSJohn Wren Kennedy
271*c373aa8bSJohn Wren Kennedy	#
272*c373aa8bSJohn Wren Kennedy	# The number of threads per filesystem must be a value greater
273*c373aa8bSJohn Wren Kennedy	# than or equal to zero; since we just verified the value isn't
274*c373aa8bSJohn Wren Kennedy	# 0 above, then it must be greater than zero here.
275*c373aa8bSJohn Wren Kennedy	#
276*c373aa8bSJohn Wren Kennedy	log_must test $threads_per_fs -ge 0
277*c373aa8bSJohn Wren Kennedy
278*c373aa8bSJohn Wren Kennedy	#
279*c373aa8bSJohn Wren Kennedy	# This restriction can be lifted later if needed, but for now,
280*c373aa8bSJohn Wren Kennedy	# we restrict the number of threads per filesystem to a value
281*c373aa8bSJohn Wren Kennedy	# that evenly divides the thread count. This way, the threads
282*c373aa8bSJohn Wren Kennedy	# will be evenly distributed over all the filesystems.
283*c373aa8bSJohn Wren Kennedy	#
284*c373aa8bSJohn Wren Kennedy	log_must test $((threads % threads_per_fs)) -eq 0
285*c373aa8bSJohn Wren Kennedy}
286*c373aa8bSJohn Wren Kennedy
287*c373aa8bSJohn Wren Kennedyfunction populate_perf_filesystems
288*c373aa8bSJohn Wren Kennedy{
289*c373aa8bSJohn Wren Kennedy	typeset nfilesystems=${1:-1}
290*c373aa8bSJohn Wren Kennedy
291*c373aa8bSJohn Wren Kennedy	export TESTFS=""
292*c373aa8bSJohn Wren Kennedy	for i in $(seq 1 $nfilesystems); do
293*c373aa8bSJohn Wren Kennedy		typeset dataset="$PERFPOOL/fs$i"
294*c373aa8bSJohn Wren Kennedy		create_dataset $dataset $PERF_FS_OPTS
295*c373aa8bSJohn Wren Kennedy		if [[ -z "$TESTFS" ]]; then
296*c373aa8bSJohn Wren Kennedy			TESTFS="$dataset"
297*c373aa8bSJohn Wren Kennedy		else
298*c373aa8bSJohn Wren Kennedy			TESTFS="$TESTFS $dataset"
299*c373aa8bSJohn Wren Kennedy		fi
300*c373aa8bSJohn Wren Kennedy	done
301*c373aa8bSJohn Wren Kennedy}
302*c373aa8bSJohn Wren Kennedy
303*c373aa8bSJohn Wren Kennedyfunction get_nfilesystems
304*c373aa8bSJohn Wren Kennedy{
305*c373aa8bSJohn Wren Kennedy	typeset filesystems=( $TESTFS )
306*c373aa8bSJohn Wren Kennedy	echo ${#filesystems[@]}
307*c373aa8bSJohn Wren Kennedy}
308*c373aa8bSJohn Wren Kennedy
309*c373aa8bSJohn Wren Kennedyfunction get_directory
310*c373aa8bSJohn Wren Kennedy{
311*c373aa8bSJohn Wren Kennedy	typeset filesystems=( $TESTFS )
312*c373aa8bSJohn Wren Kennedy	typeset directory=
313*c373aa8bSJohn Wren Kennedy
314*c373aa8bSJohn Wren Kennedy	typeset idx=0
315*c373aa8bSJohn Wren Kennedy	while [[ $idx -lt "${#filesystems[@]}" ]]; do
316*c373aa8bSJohn Wren Kennedy		mountpoint=$(get_prop mountpoint "${filesystems[$idx]}")
317*c373aa8bSJohn Wren Kennedy
318*c373aa8bSJohn Wren Kennedy		if [[ -n $directory ]]; then
319*c373aa8bSJohn Wren Kennedy			directory=$directory:$mountpoint
320*c373aa8bSJohn Wren Kennedy		else
321*c373aa8bSJohn Wren Kennedy			directory=$mountpoint
322*c373aa8bSJohn Wren Kennedy		fi
323*c373aa8bSJohn Wren Kennedy
324*c373aa8bSJohn Wren Kennedy		((idx += 1))
325*c373aa8bSJohn Wren Kennedy	done
326*c373aa8bSJohn Wren Kennedy
327*c373aa8bSJohn Wren Kennedy	echo $directory
328dcbf3bd6SGeorge Wilson}
329dcbf3bd6SGeorge Wilson
330dcbf3bd6SGeorge Wilsonfunction get_max_arc_size
331dcbf3bd6SGeorge Wilson{
332dcbf3bd6SGeorge Wilson	typeset -l max_arc_size=$(dtrace -qn 'BEGIN {
333dcbf3bd6SGeorge Wilson	    printf("%u\n", `arc_stats.arcstat_c_max.value.ui64);
334dcbf3bd6SGeorge Wilson	    exit(0);
335dcbf3bd6SGeorge Wilson	}')
336dcbf3bd6SGeorge Wilson
337dcbf3bd6SGeorge Wilson	[[ $? -eq 0 ]] || log_fail "get_max_arc_size failed"
338dcbf3bd6SGeorge Wilson
339dcbf3bd6SGeorge Wilson	echo $max_arc_size
340dcbf3bd6SGeorge Wilson}
341dcbf3bd6SGeorge Wilson
342770499e1SDan Kimmelfunction get_max_dbuf_cache_size
343770499e1SDan Kimmel{
344770499e1SDan Kimmel	typeset -l max_dbuf_cache_size=$(dtrace -qn 'BEGIN {
345770499e1SDan Kimmel	    printf("%u\n", `dbuf_cache_max_bytes);
346770499e1SDan Kimmel	    exit(0);
347770499e1SDan Kimmel	}')
348770499e1SDan Kimmel
349770499e1SDan Kimmel	[[ $? -eq 0 ]] || log_fail "get_max_dbuf_cache_size failed"
350770499e1SDan Kimmel
351770499e1SDan Kimmel	echo $max_dbuf_cache_size
352770499e1SDan Kimmel}
353770499e1SDan Kimmel
354dcbf3bd6SGeorge Wilson# Create a file with some information about how this system is configured.
355dcbf3bd6SGeorge Wilsonfunction get_system_config
356dcbf3bd6SGeorge Wilson{
357dcbf3bd6SGeorge Wilson	typeset config=$PERF_DATA_DIR/$1
358dcbf3bd6SGeorge Wilson
359dcbf3bd6SGeorge Wilson	echo "{" >>$config
3601d32ba66SJohn Wren Kennedy	dtrace -qn 'BEGIN{
361dcbf3bd6SGeorge Wilson	    printf("  \"ncpus\": %d,\n", `ncpus);
362dcbf3bd6SGeorge Wilson	    printf("  \"physmem\": %u,\n", `physmem * `_pagesize);
363dcbf3bd6SGeorge Wilson	    printf("  \"c_max\": %u,\n", `arc_stats.arcstat_c_max.value.ui64);
364dcbf3bd6SGeorge Wilson	    printf("  \"kmem_flags\": \"0x%x\",", `kmem_flags);
365dcbf3bd6SGeorge Wilson	    exit(0)}' >>$config
3661d32ba66SJohn Wren Kennedy	echo "  \"hostname\": \"$(uname -n)\"," >>$config
3671d32ba66SJohn Wren Kennedy	echo "  \"kernel version\": \"$(uname -v)\"," >>$config
3681d32ba66SJohn Wren Kennedy	iostat -En | awk 'BEGIN {
369dcbf3bd6SGeorge Wilson	    printf("  \"disks\": {\n"); first = 1}
370dcbf3bd6SGeorge Wilson	    /^c/ {disk = $1}
371dcbf3bd6SGeorge Wilson	    /^Size: [^0]/ {size = $2;
372dcbf3bd6SGeorge Wilson	    if (first != 1) {printf(",\n")} else {first = 0}
373dcbf3bd6SGeorge Wilson	    printf("    \"%s\": \"%s\"", disk, size)}
374dcbf3bd6SGeorge Wilson	    END {printf("\n  },\n")}' >>$config
3751d32ba66SJohn Wren Kennedy	sed -n 's/^set \(.*\)[ ]=[ ]\(.*\)/\1=\2/p' /etc/system | \
3761d32ba66SJohn Wren Kennedy	    awk -F= 'BEGIN {printf("  \"system\": {\n"); first = 1}
377dcbf3bd6SGeorge Wilson	    {if (first != 1) {printf(",\n")} else {first = 0};
378dcbf3bd6SGeorge Wilson	    printf("    \"%s\": %s", $1, $2)}
379dcbf3bd6SGeorge Wilson	    END {printf("\n  }\n")}' >>$config
380dcbf3bd6SGeorge Wilson	echo "}" >>$config
381dcbf3bd6SGeorge Wilson}
382dcbf3bd6SGeorge Wilson
383dcbf3bd6SGeorge Wilsonfunction num_jobs_by_cpu
384dcbf3bd6SGeorge Wilson{
3851d32ba66SJohn Wren Kennedy	typeset ncpu=$(psrinfo | wc -l)
386dcbf3bd6SGeorge Wilson	typeset num_jobs=$ncpu
387dcbf3bd6SGeorge Wilson
3881d32ba66SJohn Wren Kennedy	[[ $ncpu -gt 8 ]] && num_jobs=$(echo "$ncpu * 3 / 4" | bc)
389dcbf3bd6SGeorge Wilson
3901d32ba66SJohn Wren Kennedy	echo $num_jobs
391dcbf3bd6SGeorge Wilson}
392dcbf3bd6SGeorge Wilson
393dcbf3bd6SGeorge Wilsonfunction pool_to_lun_list
394dcbf3bd6SGeorge Wilson{
395dcbf3bd6SGeorge Wilson	typeset pool=$1
396dcbf3bd6SGeorge Wilson	typeset ctd ctds devname lun
397dcbf3bd6SGeorge Wilson	typeset lun_list=':'
398dcbf3bd6SGeorge Wilson
3991d32ba66SJohn Wren Kennedy	ctds=$(zpool list -v $pool | awk '/c[0-9]*t[0-9a-fA-F]*d[0-9]*/ \
400dcbf3bd6SGeorge Wilson	    {print $1}')
401dcbf3bd6SGeorge Wilson
402dcbf3bd6SGeorge Wilson	for ctd in $ctds; do
403dcbf3bd6SGeorge Wilson		# Get the device name as it appears in /etc/path_to_inst
4041d32ba66SJohn Wren Kennedy		devname=$(readlink -f /dev/dsk/${ctd}s0 | sed -n \
405dcbf3bd6SGeorge Wilson		    's/\/devices\([^:]*\):.*/\1/p')
406dcbf3bd6SGeorge Wilson		# Add a string composed of the driver name and instance
407dcbf3bd6SGeorge Wilson		# number to the list for comparison with dev_statname.
4081d32ba66SJohn Wren Kennedy		lun=$(sed 's/"//g' /etc/path_to_inst | grep $devname | awk \
409dcbf3bd6SGeorge Wilson		    '{print $3$2}')
410dcbf3bd6SGeorge Wilson		lun_list="$lun_list$lun:"
411dcbf3bd6SGeorge Wilson	done
412dcbf3bd6SGeorge Wilson	echo $lun_list
413dcbf3bd6SGeorge Wilson}
414dcbf3bd6SGeorge Wilson
415dcbf3bd6SGeorge Wilson# Create a perf_data directory to hold performance statistics and
416dcbf3bd6SGeorge Wilson# configuration information.
417dcbf3bd6SGeorge Wilsonexport PERF_DATA_DIR=$(get_perf_output_dir)
418dcbf3bd6SGeorge Wilson[[ -f $PERF_DATA_DIR/config.json ]] || get_system_config config.json
419