#!/bin/sh
#
# lvm_resize 1.1 (c) 2006 Richard Taylor
#
# Event handler script for Nagios for resizing LVM logical volumes
#
# Usage:
# lvm_resize $SERVICESTATE$ $STATETYPE$ $SERVICEATTEMPT$ resize_percent $OUTPUT$
#
# NOTE: resize_percent is an integer greater than zero (without a '%' character)
#       This script currently only works with ext2/3 and reiserfs!
# 

#exit codes
STATE_OK=0
STATE_WARNING=1
STATE_UNKNOWN=3

#defaults
exit_state=$STATE_OK

#go ahead and grab the state
service_state="$1"

do_params() {
    #check for number of args
    if [ $# -lt 5 ]; then
        echo "Wrong number of command line arguments"
        exit $STATE_UNKNOWN
    fi
    
    state_type=$2
    service_attempt=$3
    resize_percent=$4
    output=`echo "$*" | sed -e "s/$1[[:space:]]$2[[:space:]]$3[[:space:]]$4[[:space:]]//g"`
    
    #error check parameters
    if [[ -z $state_type || -z $service_attempt || -z $resize_percent || -z $output ]]; then
        echo "See the program usage."
        exit $STATE_UNKNOWN
    fi
    if [[ `expr match "$service_attempt" '\([0-9]*\)'` != $service_attempt ]]; then
        echo "Service attempt must be a number greater than zero"
        exit $STATE_UNKNOWN
    fi
    if [[ `expr match "$resize_percent" '\([0-9]*\)'` != $resize_percent ]]; then
        echo "Resize percentage must be a number greater than zero"
        exit $STATE_UNKNOWN
    fi
}

resize_lvs() {
    for item in `echo $output`; do
        if [[ -n `expr match "$item" '\(\(WARNING\)\|\(CRITICAL\)\|\(OK\)\|\(-\)\)'` ]]; then
            continue
        fi
        vg=`echo $item | awk -F "/" '{print $1}'`
        lv=`echo $item | awk -F "/" '{print $2}'`
        size=`lvs --noheadings --nosuffix --units m -o lv_name,lv_size $vg | grep $lv | awk '{print $2}'`
        addition=`echo "$size * $resize_percent / 100" | bc`
        result=`lvextend --resizefs --size +$addition\M $vg/$lv 2>&1 1> /dev/null`
        if [ $? -ne 0 ]; then
            result=`lvextend --size +$addition\M $vg/$lv 2>&1 1> /dev/null`
            if [ $? -ne 0 ]; then
                mesgs="$mesgs Resize failed for $vg/$lv: $result "
                exit_state=$STATE_WARNING
                continue
            fi
            lvdev=`lvscan | grep $vg | grep $lv | awk '{print $2}' | sed -e "s/'//g"`
            result=`resize_reiserfs $lvdev 2>&1 1> /dev/null`
            if [ $? -ne 0 ]; then
                mesgs="$mesgs Resize failed for $vg/$lv: $result "
                exit_state=$STATE_WARNING
                continue
            fi
        fi
        mesgs="$mesgs Resize suceeded for $vg/$lv."
    done
}

case "$service_state" in
UNKNOWN)
    # no prob
    ;;
OK)
    # no prob
    ;;
WARNING|CRITICAL)
    # let's go ahead and do a resize
    do_params "$@"
    case "$state_type" in
    SOFT)
        case "$service_attempt" in
        2)
            resize_lvs
            ;;
        esac
        ;;
    HARD)
        # this should've been done in the soft, but oh well...
        resize_lvs
        ;;
    esac
    ;;
*)
    echo "Incorrect arguments--see usage."
    exit $STATE_UNKNOWN
    ;;
esac

if [[ -n $mesgs ]]; then
    echo $mesgs
fi
exit $exit_state