From d7d5381863b1509b585929e8181acab61e7181ff Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Thu, 26 Jan 2012 12:19:47 -0700 Subject: [PATCH] Make check_disk_space() use bytes (given new size type options with are converted to bytes, 1k=>1024). --- lib/bash/safeguards.sh | 57 ++++++++++++++++++++++------------------ t/lib/bash/safeguards.sh | 35 +++++++++++++++++------- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/lib/bash/safeguards.sh b/lib/bash/safeguards.sh index 97db3842..91402bb6 100644 --- a/lib/bash/safeguards.sh +++ b/lib/bash/safeguards.sh @@ -1,4 +1,4 @@ -# This program is copyright 2011 Percona Inc. +# This program is copyright 2011-2012 Percona Inc. # Feedback and improvements are welcome. # # THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED @@ -33,46 +33,53 @@ disk_space() { # Sub: check_disk_space # Check if there is or will be enough disk space. Input is a file # with output from , i.e. `df -P -k`. The df output -# must use 1k blocks, but the mb arg from the user is in MB. +# must use 1k blocks, which should be POSIX standard. # # Arguments: -# file - File with output from . -# mb - Minimum MB free. -# pc - Minimum percent free. -# mb_margin - Add this many MB to the real MB used. +# file - File with output from . +# min_free_bytes - Minimum free bytes. +# min_free_pct - Minimum free percentage. +# bytes_margin - Add this many bytes to the real bytes used. # # Returns: # 0 if there is/will be enough disk space, else 1. check_disk_space() { local file="$1" - local mb="${2:-0}" - local pc="${3:-0}" - local mb_margin="${4:-0}" + local min_free_bytes="${2:-0}" + local min_free_pct="${3:-0}" + local bytes_margin="${4:-0}" - # Convert MB to KB because the df output should be in 1k blocks. - local kb=$(($mb * 1024)) - local kb_margin=$(($mb_margin * 1024)) + # Real/actual bytes used and bytes free. + local used_bytes=$(cat "$file" | awk '/^\//{print $3 * 1024}'); + local free_bytes=$(cat "$file" | awk '/^\//{print $4 * 1024}'); + local pct_used=$(cat "$file" | awk '/^\//{print $5}' | sed -e 's/%//g'); + local pct_free=$((100 - $pct_used)) - local kb_used=$(cat "$file" | awk '/^\//{print $3}'); - local kb_free=$(cat "$file" | awk '/^\//{print $4}'); - local pc_used=$(cat "$file" | awk '/^\//{print $5}' | sed -e 's/%//g'); + # Report the real values to the user. + local real_free_bytes=$free_bytes + local real_pct_free=$pct_free - if [ "$kb_margin" -gt "0" ]; then - local kb_total=$(($kb_used + $kb_free)) + # If there's a margin, we need to adjust the real values. + if [ $bytes_margin -gt 0 ]; then + used_bytes=$(($used_bytes + $bytes_margin)) + free_bytes=$(($free_bytes - $bytes_margin)) + pct_used=$(awk "BEGIN { printf(\"%d\", ($used_bytes/($used_bytes + $free_bytes)) * 100) }") - kb_used=$(($kb_used + $kb_margin)) - kb_free=$(($kb_free - $kb_margin)) - pc_used=$(awk "BEGIN { printf(\"%d\", $kb_used/$kb_total * 100) }") + pct_free=$((100 - $pct_used)) fi - local pc_free=$((100 - $pc_used)) + if [ $free_bytes -lt $min_free_bytes -o $pct_free -lt $min_free_pct ]; then + warn "Not enough free disk space: + Limit: ${min_free_pct}% free, ${min_free_bytes} bytes free + Actual: ${real_pct_free}% free, ${real_free_bytes} bytes free (- $bytes_margin bytes margin) +" + # Print the df that we used. + cat "$file" >&2 - if [ "$kb_free" -le "$kb" -o "$pc_free" -le "$pc" ]; then - warn "Not enough free disk space: ${pc_free}% free, ${kb_free} KB free; wanted more than ${pc}% free or ${kb} KB free" - return 1 + return 1 # not enough disk space fi - return 0 + return 0 # disk space is OK } # ########################################################################### diff --git a/t/lib/bash/safeguards.sh b/t/lib/bash/safeguards.sh index c874498f..cf678d90 100644 --- a/t/lib/bash/safeguards.sh +++ b/t/lib/bash/safeguards.sh @@ -18,36 +18,51 @@ is \ "2" \ "2-line df output" -check_disk_space "$SAMPLE/diskspace001.txt" 22000 18 >$TMPDIR/out 2>&1 +# Filesystem 1024-blocks Used Available Capacity Mounted on +# /dev/disk0s2 118153176 94409664 23487512 81% / +# +# Those values are in Kb, so: +# used = 94409664 (94.4G) = 96_675_495_936 bytes +# free = 23487512 (23.4G) = 24_051_212_288 bytes +# pct free = 100 - 81 = 19 % + +# want free - 100, 18 < 19, so this should be ok. +check_disk_space "$SAMPLE/diskspace001.txt" 24051212188 18 >$TMPDIR/out 2>&1 is "$?" "0" "Enough disk space" is \ "`cat $TMPDIR/out`" \ "" \ "No output if enough disk space" -check_disk_space "$SAMPLE/diskspace001.txt" 24000 18 >$TMPDIR/out 2>&1 +# want free - 100 is ok, but 20 < 19 is not. +check_disk_space "$SAMPLE/diskspace001.txt" 24051212188 20 >$TMPDIR/out 2>&1 +is "$?" "1" "Not enough % free" + +# want free + 100, so this should fail +# (real free is 100 bytes under what we want) +check_disk_space "$SAMPLE/diskspace001.txt" 24051212388 18 >$TMPDIR/out 2>&1 is "$?" "1" "Not enough MB free" cmd_ok \ - "grep -q '19% free, 23487512 KB free; wanted more than 18% free or 24576000 KB free' $TMPDIR/out" \ + "grep -q 'Actual: 19% free, 24051212288 bytes free (- 0 bytes margin)' $TMPDIR/out" \ "Warning if not enough disk space" -check_disk_space "$SAMPLE/diskspace001.txt" 22000 19 >$TMPDIR/out 2>&1 -is "$?" "1" "Not enough % free" - # ########################################################################### # Check with a margin (amount we plan to use in the future). # ########################################################################### -check_disk_space "$SAMPLE/diskspace001.txt" 22000 18 100 +# want free - 100 + 50 margin, so effectively want free - 50 is ok. +check_disk_space "$SAMPLE/diskspace001.txt" 24051212188 18 50 is "$?" "0" "Enough disk space with margin" -check_disk_space "$SAMPLE/diskspace001.txt" 23000 18 100 >$TMPDIR/out 2>&1 +# want free - 100 + 101 margin, so real free is 1 byte under what we want. +check_disk_space "$SAMPLE/diskspace001.txt" 24051212188 18 101 >$TMPDIR/out 2>&1 is "$?" "1" "Not enough MB free with margin" -check_disk_space "$SAMPLE/diskspace001.txt" 100 5 20000 >$TMPDIR/out 2>&1 +# want free - 100 + 50 margin ok but %free will be 19 which is < 25. +check_disk_space "$SAMPLE/diskspace001.txt" 24051212188 25 50 >$TMPDIR/out 2>&1 is "$?" "1" "Not enough % free with margin" cmd_ok \ - "grep -q '3% free,' $TMPDIR/out" \ + "grep -q 'Actual:[ ]*19% free,' $TMPDIR/out" \ "Calculates % free with margin" # ###########################################################################