1#!/bin/ksh -p 2# 3# This file and its contents are supplied under the terms of the 4# Common Development and Distribution License ("CDDL"), version 1.0. 5# You may only use this file in accordance with the terms of version 6# 1.0 of the CDDL. 7# 8# A full copy of the text of the CDDL should have accompanied this 9# source. A copy of the CDDL is also available via the Internet at 10# http://www.illumos.org/license/CDDL. 11# 12 13# 14# Copyright (c) 2019 by Tim Chase. All rights reserved. 15# Copyright (c) 2019 Lawrence Livermore National Security, LLC. 16# Copyright 2019 Joyent, Inc. 17# 18 19. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib 20 21# 22# Get the actual on disk disk for the provided file. 23# 24function get_size_mb 25{ 26 typeset rval=$(du -s "$1" | awk '{print $1}') 27 rval=$((rval * 2048)) 28 echo -n "$rval" 29} 30 31# 32# Use mdb to get the approximate number of trim IOs issued for the pool. 33# This really is just used to ensure that trim IO has occured and is a 34# temporary solution until illumos supports zpool iostat histograms. 35# 36function get_illumos_trim_io 37{ 38 typeset pool="${1-:$TESTPOOL}" 39 typeset spa 40 typeset vdevs 41 typeset total_trim 42 typeset v 43 typeset trimmed 44 typeset b 45 46 # Get vdevs for the pool 47 spa=$(mdb -ke '::spa' | awk -v pool=$pool '{if ($3 == pool) print $1}') 48 vdevs=$(mdb -ke "$spa::spa -v" | awk '{ 49 if ($4 == "DESCRIPTION") {st=1; next} 50 if (st == 1) print $1 51 }') 52 53 # Get trim counts for each vdev 54 total_trim=0 55 for v in $vdevs 56 do 57 b=$(mdb -ke "$v::print vdev_t vdev_trim_bytes_done" | \ 58 awk '{print $3}') 59 trimmed=$(mdb -e "$b=E") 60 trimmed=$((trimmed / 4096)) 61 total_trim=$((total_trim + trimmed)) 62 63 b=$(mdb -ke "$v::print vdev_t vdev_autotrim_bytes_done" | \ 64 awk '{print $3}') 65 trimmed=$(mdb -e "$b=E") 66 trimmed=$((trimmed / 4096)) 67 total_trim=$((total_trim + trimmed)) 68 done 69 echo -n "$total_trim" 70} 71 72# 73# Get the number of trim IOs issued for the pool (ind or agg). 74# 75function get_trim_io 76{ 77 typeset pool="${1-:$TESTPOOL}" 78 typeset type="${2-:ind}" 79 typeset rval 80 81 # Sum the ind or agg columns of the trim request size histogram. 82 case "$type" in 83 "ind") 84 rval=$(zpool iostat -pr $pool | awk \ 85 '$1 ~ /[0-9].*/ { sum += $12 } END { print sum }') 86 echo -n "$rval" 87 ;; 88 "agg") 89 rval=$(zpool iostat -pr $pool | awk \ 90 '$1 ~ /[0-9].*/ { sum += $13 } END { print sum }') 91 echo -n "$rval" 92 ;; 93 *) 94 log_fail "Type must be 'ind' or 'agg'" 95 ;; 96 esac 97} 98 99# 100# Verify that trim IOs were send to devices in the pool. 101# 102function verify_trim_io 103{ 104 typeset pool="${1:-$TESTPOOL}" 105 typeset type="${2:-ind}" 106 typeset min_trim_ios=${3:-100} 107 typeset ios 108 109 if is_linux; then 110 ios=$(get_trim_io $pool $type) 111 else 112 ios=$(get_illumos_trim_io $pool $type) 113 fi 114 115 if [[ $ios -ge $min_trim_ios ]]; then 116 log_note "Issued $ios $type trim IOs for pool $pool" 117 else 118 log_fail "Too few trim IOs issued $ios/$min_trim_ios" 119 fi 120} 121 122# 123# Run N txgs which should be enough to trim the entire pool. 124# 125function wait_trim_io # pool type txgs 126{ 127 typeset pool="${1-:$TESTPOOL}" 128 typeset type="${2-:ind}" 129 typeset txgs=${3:-10} 130 typeset timeout=120 131 typeset stop_time=$(( $(date +%s) + $timeout )) 132 133 typeset -i i=0 134 while [[ $i -lt $txgs ]]; do 135 if [ "$(date +%s)" -ge $stop_time ]; then 136 log_fail "Exceeded trim time limit of ${timeout}s" 137 return 138 fi 139 140 zpool sync -f 141 ((i = i + 1)) 142 done 143 144 typeset ios=$(get_trim_io $pool $type) 145 log_note "Waited for $txgs txgs, $ios $type TRIM IOs" 146} 147 148# 149# Verify that file vdevs against a target value. 150# 151function verify_vdevs # op size vdevs 152{ 153 typeset tgt_op=$1 154 typeset tgt_size=$2 155 shift 2 156 typeset vdevs=$@ 157 158 for vdev in $vdevs; do 159 typeset size=$(get_size_mb $vdev) 160 if test $size $tgt_op $tgt_size; then 161 log_note "Success $vdev is $size MB which is $tgt_op" \ 162 "than $tgt_size MB" 163 else 164 log_fail "Failure $vdev is $size MB which is not" \ 165 "$tgt_op than $tgt_size MB" 166 fi 167 done 168} 169 170# 171# Wait for up to 120 seconds for trimming of the listed vdevs to complete. 172# 173function wait_trim # pool vdevs 174{ 175 typeset stop_time=$(( $(date +%s) + 120 )) 176 typeset pool="$1" 177 shift 178 typeset vdevs=$@ 179 typeset complete 180 181 while [[ $complete -eq 0 ]]; do 182 complete=1 183 184 for vdev in $vdevs; do 185 if [[ "$(trim_progress $pool $vdev)" -lt "100" ]]; then 186 complete=0 187 break 188 else 189 log_must eval "trim_prog_line $pool $vdev | \ 190 grep complete" 191 fi 192 done 193 194 if [ "$(date +%s)" -ge $stop_time ]; then 195 log_fail "Exceeded trim time limit of 120s" 196 fi 197 198 sleep 0.5 199 done 200 201 log_note "Pool completed trim successfully." 202} 203