diff --git a/nagios/check_btrfs_quota.sh b/nagios/check_btrfs_quota.sh new file mode 100755 index 0000000..e4ede15 --- /dev/null +++ b/nagios/check_btrfs_quota.sh @@ -0,0 +1,244 @@ +#!/bin/sh + +# Little check for quota usage on Btrfs subvolumes +# GPL v3+ (copyright chl-dev@bugness.org) + +PROGPATH=$( echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,' ) +REVISION="0.1" + +# Stop at the first non-catched error +set -e + +# Include check_range() +# Not needed at the moment +#. $PROGPATH/utils.sh +STATE_OK=0 +STATE_WARNING=1 +STATE_CRITICAL=2 +STATE_UNKNOWN=3 +STATE_DEPENDENT=4 + +# Default values +RANGE_WARNING="20%" +RANGE_CRITICAL="10%" + +# Output +OUTPUT_EXIT_STATUS=$STATE_OK +OUTPUT_DETAIL_OK="" +OUTPUT_DETAIL_WARNING="" +OUTPUT_DETAIL_CRITICAL="" +OUTPUT_PERFDATA="" + +# +# Help function +# +usage() { + cat </dev/null 2>&1 +# if [ "$?" -eq "2" ]; then +# return 1 +# fi +# return 0 +#} + +# +# Remove the '%' suffix (or error if no '%') +# +get_percent() { + if [ "$( echo -n "$1" | tail -c 1 )" = "%" ]; then + echo -n "$1" | head -c -1 + return 0 + fi + return 1 +} + +# +# Returns 0 if freespace is above threshold, 1 if not +# +# args: +# - "free" space value +# - quota (aka. maximum space possible) +# - threshold (in percent with a '%' suffix, or plain unit) +# +check_freespace_is_above_threshold() { + local VALUE="$1" + local MAXVALUE="$2" + local THRESHOLD="$3" + + if get_percent "$THRESHOLD" >/dev/null; then + VALUE="$(( $VALUE * 100 / $MAXVALUE ))" + THRESHOLD="$( get_percent "$THRESHOLD" )" + fi + + if [ "$VALUE" -le "$THRESHOLD" ]; then + return 1 + fi + return 0 +} + +# +# Factorize output in the form of: +# /home:0/260 (refr:10M(50%) excl:5M(20%) +# args: +# 1: VOLUME +# 2: QGROUPID +# 3: REFR +# 4: EXCL +# 5: MAXRFER +# 6: MAXEXCL +format_output_item() { + local LOCAL_OUTPUT="" + if [ "$5" != "none" ]; then + LOCAL_OUTPUT="$( printf "rfer:%s(%d%%)" \ + "$( numfmt --to=iec $(( $5 - $3 )) )" \ + "$(( 100 * ($5 - $3) / $5 ))" \ + )" + fi + if [ "$6" != "none" ]; then + [ -n "$LOCAL_OUTPUT" ] && LOCAL_OUTPUT="$LOCAL_OUTPUT " + LOCAL_OUTPUT="$( printf "excl:%s(%d%%)" \ + "$( numfmt --to=iec $(( $6 - $4 )) )" \ + "$(( 100 * ($6 - $4) / $6 ))" \ + )" + fi + if [ -n "$LOCAL_OUTPUT" ]; then + printf "%s:%s (%s)" "$1" "$2" "$LOCAL_OUTPUT" + fi +} + +# Some early checks +if ! which btrfs 2>&1 >/dev/null; then + echo "UNKNOWN 'btrfs' command not found." + exit $STATE_UNKNOWN +fi + +# +# Loop on parameters + tests +# +while getopts hw:c:V: f; do + case "$f" in + 'h') + usage + exit + ;; + + 'w') + if check_range_syntax "$OPTARG" >/dev/null; then + RANGE_WARNING="$OPTARG" + else + echo "UNKNOWN: invalid range." + exit 3 + fi + ;; + + 'c') + if check_range_syntax "$OPTARG" >/dev/null; then + RANGE_CRITICAL="$OPTARG" + else + echo "UNKNOWN: invalid range." + exit 3 + fi + ;; + + 'V') + VOLUME="$OPTARG" + + # Quickly check if we have enough permission to launch btrfs commands + if ! btrfs qgroup show "$VOLUME" >/dev/null 2>&1 ; then + echo "UNKNOWN: unable to launch 'btrfs qgroup show $VOLUME' command." + exit $STATE_UNKNOWN + fi + + # Loop on each qgroup + # (the kinda weird <