1#!/bin/ksh 2# SPDX-License-Identifier: CDDL-1.0 3# 4# This file and its contents are supplied under the terms of the 5# Common Development and Distribution License ("CDDL"), version 1.0. 6# You may only use this file in accordance with the terms of version 7# 1.0 of the CDDL. 8# 9# A full copy of the text of the CDDL should have accompanied this 10# source. A copy of the CDDL is also available via the Internet at 11# http://www.illumos.org/license/CDDL. 12# 13 14# 15# Copyright (c) 2018 by Delphix. All rights reserved. 16# 17 18typeset -a disk_array=($(find_disks $DISKS)) 19 20typeset -r DISK1=${disk_array[0]} 21typeset -r DISK2=${disk_array[1]} 22typeset -r DISK3=${disk_array[2]} 23 24# 25# When the condition it is waiting for becomes true, 'zpool wait' should return 26# promptly. We want to enforce this, but any check will be racey because it will 27# take some small but indeterminate amount of time for the waiting thread to be 28# woken up and for the process to exit. 29# 30# To deal with this, we provide a grace period after the condition becomes true 31# during which 'zpool wait' can exit. If it hasn't exited by the time the grace 32# period expires we assume something is wrong and fail the test. While there is 33# no value that can really be correct, the idea is we choose something large 34# enough that it shouldn't cause issues in practice. 35# 36typeset -r WAIT_EXIT_GRACE=2.0 37 38function add_io_delay # pool 39{ 40 for disk in $(get_disklist $1); do 41 log_must zinject -d $disk -D20:1 $1 42 done 43} 44 45function remove_io_delay 46{ 47 log_must zinject -c all 48} 49 50function proc_exists # pid 51{ 52 ps -p $1 >/dev/null 53} 54 55function proc_must_exist # pid 56{ 57 proc_exists $1 || log_fail "zpool process exited too soon" 58} 59 60function proc_must_not_exist # pid 61{ 62 proc_exists $1 && log_fail "zpool process took too long to exit" 63} 64 65function get_time 66{ 67 date +'%H:%M:%S' 68} 69 70function kill_if_running 71{ 72 typeset pid=$1 73 [[ $pid ]] && proc_exists $pid && log_must kill -s TERM $pid 74} 75 76# Log a command and then start it running in the background 77function log_bkgrnd 78{ 79 log_note "$(get_time) Starting cmd in background '$@'" 80 "$@" & 81} 82 83# Check that a background process has completed and exited with a status of 0 84function bkgrnd_proc_succeeded 85{ 86 typeset pid=$1 87 88 log_must sleep $WAIT_EXIT_GRACE 89 90 proc_must_not_exist $pid 91 wait $pid || log_fail "zpool process exited with status $?" 92 log_note "$(get_time) wait completed successfully" 93} 94 95# 96# Check that 'zpool wait' returns reasonably promptly after the condition 97# waited for becomes true, and not before. 98# 99function check_while_waiting 100{ 101 # The pid of the waiting process 102 typeset wait_proc_pid=$1 103 # A check that should be true while the activity is in progress 104 typeset activity_check=$2 105 106 log_note "$(get_time) waiting for process $wait_proc_pid using" \ 107 "activity check '$activity_check'" 108 while proc_exists $wait_proc_pid && eval "$activity_check"; do 109 log_must sleep .5 110 done 111 112 # 113 # If the activity being waited on is still in progress, then zpool wait 114 # exited too soon. 115 # 116 log_mustnot eval "$activity_check" 117 118 bkgrnd_proc_succeeded $wait_proc_pid 119} 120 121# Whether any vdev in the given pool is initializing 122function is_vdev_initializing # pool 123{ 124 zpool status -i "$1" | grep -q 'initialized, started' 125} 126