Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am using nagios3 and want to collect some information from nrpe_server.

Next script is at nrpe_server:

#!/bin/sh
#set -x
# script for checking disk usage on ZFS
# requires min zpool version 13 or zfs version 4
# example, it's posible to have zfs ver 1 on zpool ver 15 (script support this)
# http://www.googlux.com/nagios.plugin.zfs.usage.html
# ------------ Variables
PROGNAME=`/usr/bin/basename $0`

# ------ Nagios plugin return values
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
STATE_DEPENDENT=4

# ------------ Subroutines

# Program usage
usage() {
echo " \
Usage
        ${PROGNAME} /zfs warn crit

Note:
1. ZFS filesystem must start with /
2. warn is warning free space in %
3. crit is critical free space in %
example: /tank 20 10
"
}

# End script with output, with performance data for NagiosGraph
endscript () {
        echo "${RESULT}"
        exit ${EXIT_STATUS}
}

# ------------ check if there are 3 arguments
if [ $# != 3 ]; then
        usage
        exit 3
fi

# --------- check if warning is bigger than critical size
if [ $3 -ge $2 ]; then
        echo "Warning[%] must be bigger than Critical[%]"
        exit 3
fi

# ----------- check if first argument is a filesystem
FS=`df -T $1 | tail -n 1`
if [ $? != 0 ]; then
        echo "The $1 is not valid filesystem"
        exit 3
fi

# ----------- check if filesystem is ZFS
# /var : zfs
# /export/atlant-dbbackup: zfs
# note - comment out: ZFS=`echo ${FS} | awk '{print $3}'`
ZFS=`echo ${FS} | awk '{print $2}'`

if [ "${ZFS}" != "zfs" ]; then
        echo "The $1 is not ZFS"
        exit 3
fi

# -------- get dataset of filesystem
DATASET=`df -h $1 | grep -v Filesystem | awk '{print $1}'`

# ----------- check if ZFS is min required version 4 or ZPOOL min required ver 13
ZFSVER=`zfs get -H version ${DATASET} | awk '{print $3}'`
if [ $? -ne 0 ]; then
        echo "The ZFS version can't be determined, it's probably less then 4"
        exit 3
fi
if [ ${ZFSVER} -lt 4 ]; then
        #echo "The $1 is indeed ZFS, but version ${ZFSVER} which is less than 4 and not supported by this script"
        #exit 3
        # ---------- check if ZPOOL is min required version 13, or higher
        ZPOOLVER=`zpool upgrade | head -1 | awk '{print $NF}' | awk -F. '{print $1}'`
        if [ ${ZPOOLVER} -lt 13 ]; then
                echo "The script can't support zpool ver ${ZPOOLVER} (<13) and ZFS ver ${ZFSVER} (<4)"
                exit 3
        fi
fi


# size in bytes
QUOTA=`zfs get -Hp quota ${DATASET} | awk '{print $3}'`
DIV=1024/1024
# --- check if there is quota at all
if [ ${QUOTA} -eq 0 ]; then
#        echo "There is no quota on zfs dataset ${DATASET}"
    QUOTA=`df $1 | tail -n 1 | awk '{print $4}'`
    DIV=1024
#        exit 3
fi

# --- check if zfs properties can be determined
# --- sometimes even zfs ver =4 this is not posible
for i in usedbydataset usedbychildren usedbysnapshots
do
        if [ "`zfs get -Hp ${i} ${DATASET} | awk '{print $3}'`" = "-" ]; then
                echo "Somehow zfs property ${i} cannot be determined"
                exit 3
        fi
done

# --- check if usedbydataset is not 0
# --- can happens with export/import zpools
if [ `zfs get -Hp usedbydataset ${DATASET} | awk '{print $3}'` -eq 0 ]; then
        echo "Somehow zfs property usedbydataset=0, probably zpool exported/imported and script can't support it"
        exit 3
fi

CHILDRENUSE=`zfs get -Hp usedbychildren ${DATASET} | awk '{print $3}'`
DATA=`zfs get -Hp usedbydataset ${DATASET} | awk '{print $3}'`
SNAPSHOT=`zfs get -Hp usedbysnapshots ${DATASET} | awk '{print $3}'`
#echo QUOTA=${QUOTA}
# size in Mbytes
QUOTA=`(echo "scale=2; ${QUOTA}/${DIV}" | bc -l)`
CHILDRENUSE=`(echo "scale=2; ${CHILDRENUSE}/1024/1024" | bc -l)`
DATA=`(echo "scale=2; ${DATA}/1024/1024" | bc -l)`
SNAPSHOT=`(echo "scale=2; ${SNAPSHOT}/1024/1024" | bc -l)`
#echo QUOTA=${QUOTA}
# real quota is actually quota-usedbychildren
QUOTA=`(echo "scale=2; ${QUOTA}-${CHILDRENUSE}" | bc -l)`

FREE=`(echo "${QUOTA}-${DATA}-${SNAPSHOT}" | bc -l)`

#echo "FREE=${QUOTA}-${DATA}-${SNAPSHOT}"

FREEPERC=`bc -l << E
scale=0
${FREE}*100/${QUOTA}
E`

WARNING=$2
CRITICAL=$3

if [ ${FREEPERC} -gt ${WARNING} ]
then
        RESULT="ZFS ver${ZFSVER} $1 OK Free space ${FREE}MB ${FREEPERC}% : ${QUOTA}, ${SNAPSHOT}, ${DATA}, ${FREE}"
        EXIT_STATUS=${STATE_OK}
elif [ ${FREEPERC} -le ${WARNING} ] && [ ${FREEPERC} -gt ${CRITICAL} ]
then
        RESULT="ZFS ver${ZFSVER} $1 WARNING Free space ${FREE}MB ${FREEPERC}% : ${QUOTA}, ${SNAPSHOT}, ${DATA}, ${FREE}"
        EXIT_STATUS=${STATE_WARNING}
else
        RESULT="ZFS ver${ZFSVER} $1 CRITICAL Free space ${FREE}MB ${FREEPERC}% : ${QUOTA}, ${SNAPSHOT}, ${DATA}, ${FREE}"
        EXIT_STATUS=${STATE_CRITICAL}
fi

# ------- provide output and nagios return value
endscript

It receives thee argument from nagios3 correctly. When I running this script manually at nrpe_server from command line it returns correct information, for example:

# /usr/lib/nagios/plugins/check_zfs_usage.sh /tank/share 20 10
ZFS ver5 /tank/share OK Free space 2175113.43MB 73% : 2954615.25, 1053.55, 778448.27, 2175113.43

But when nagios3 running this script remotely through nrpe_server with the same arguments it receives back incorrect information:

ZFS ver /tank/share CRITICAL Free space MB % : , , ,

So what is wrong with the script, how to fix it?

share|improve this question
1  
Enable logging on server-side of nrpe and show the entries of the script execution. Have you run the manual test as root or as the user as which your nrpe-server runs? –  ByteNudger Feb 27 '12 at 22:08
    
Thanks ByteNudger for pushing me to find the solution. Yes The problem hiding in permissions, not in script's permissions but zfs's. –  BBK Feb 28 '12 at 18:14
add comment

2 Answers

Maybe it would be a good idea to replace:

# -------- get dataset of filesystem
DATASET=`df -h $1 | grep -v Filesystem | awk '{print $1}'`

with the following:

# -------- get dataset of filesystem
DATASET=`df -h $1 | awk '{print $1}' | tail -n 1`

Because of localization issues on some installations, some distros think it's a good idea to replace such things as "Filesystem" with the localized pendant for example "Dateisystem".

share|improve this answer
add comment
up vote 0 down vote accepted

Problem was in /dev/zfs's permissions. I just did next:

cat <<EOM>/etc/udev/rules.d/91-zfs-permissions.rules
#Use this to add a group and more permissive permissions for zfs
#so that you don't always need run it as root.  beware, users not root
#can do nearly EVERYTHING, including, but not limited to destroying
#volumes and deleting datasets.  they CANNOT mount datasets or create new
#volumes, export datasets via NFS, or other things that require root
#permissions outside of ZFS.
ACTION=="add", KERNEL=="zfs", MODE="0660", GROUP="zfs"
EOM

groupadd zfs
gpasswd -a nagios zfs

reboot

Now all works fine.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.