#!/bin/bash
# Kategorie: portal
# Kleines Tool zur Ueberwachung aller Festplatten und SW-RAID Verbuende
# diskcheker V. 1.2
# (C) 2009 Stefan Schaefer -- invis-server.org
# Qustions: stefan@invis-server.org

# License: GPLv3
# Dieses Programm ist freie Software. Sie können es unter den Bedingungen der 
# GNU General Public License, wie von der Free Software Foundation veröffentlicht,
# weitergeben und/oder modifizieren, entweder gemäß Version 3 der Lizenz oder
# (nach Ihrer Option) jeder späteren Version.

# Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen
# von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite 
# Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. 
# Details finden Sie in der GNU General Public License.

# Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem 
# Programm erhalten haben. Falls nicht, siehe <http://www.gnu.org/licenses/>. 

#Konfigurationsdaten
conffile="/etc/invis/invis.conf"
#passfile="/etc/invis/invis-pws.conf"

# Funktionen
# Werte aus Konfigurationsdatendatei extrahieren
# $1 = Konfigurationsdatei, $2 = Parameter, $3 Wert (Feld)
getconfdata() {
    cat $1 |grep "$2" | cut -d ":" -f $3
}

# Konfigurationsparameter tauschen
changevalues() {
    # Arg1 = Pfad, Arg2 = Datei, Arg3 = sed String
    cat $1/$2|sed "s%$3%g" > $1/$2.new
    mv $1/$2.new $1/$2
}

# Verzeichnis für Testergebnisse
directory="/var/spool/results/diskchecker"

# Spooldirectory anlegen
if [[ ! -d $directory ]]; then
    mkdir -p $directory
    chown -R .www /var/spool/results
fi

# Alte Status- und Alarmmeldung löschen
rm -f $directory/alarm

# Servernamen ermitteln
server=`hostname -f`

# aktuelles Datum ermitteln
datum=`date +%d.%m.%Y" "%R`

#echo "Letzter Prüflauf: $datum Uhr" > $directory/status
echo "$datum" > $directory/status

# No SMART Support
nosmart=`getconfdata $conffile "noSMART" "2"`

# Alle Festplatten finden
for x in /sys/block/*; do
	smartpossible=`udevadm info --query=all --path=$x|grep "$nosmart"`
	#echo $x:$smartpossible
	x=`basename $x`
	if [[ -n $smartpossible ]]; then
	    #echo $x
	    # Festplatten testen
	    if [[ `echo $x|cut -c1,2` == "sd" ]]; then
		selftest=`smartctl -H /dev/$x|cut -d " " -f6|tail -n 2|head -n 1`
		#echo $selftest
		if [[ $selftest == "PASSED" ]]; then
		    temp=`smartctl -A /dev/$x|grep 194|tr -s " "|cut -d " " -f 10`
		    #echo "Festplatte \"$x\" ist OK - Aktuelle Festplattentemperatur ist $temp °C" >> $directory/status
		    echo "$x OK $temp" >> $directory/status
		else
		    #echo "Festplatte \"$x\" ist Fehlerhaft - bitte sofort Ihrem Administrator melden!" >> $directory/status
		    temp=`smartctl -A /dev/$x|grep 194|tr -s " "|cut -d " " -f 10`
		    echo "$x nOK $temp" >> $directory/status
		    echo "Festplatte $x auf Server $server meldet Fehler: $selftest" >> $directory/alarm 
		fi
	    fi
	fi
	# RAID Verbuende testen
	if [[ `echo $x|cut -c1,2` == "md" ]]; then
	    status=`mdadm -D /dev/$x|grep "State :"|tr -d " "|cut -d ":" -f 2`
	    if [[ $status == "active" || $status == "clean" ]]; then
		#echo "RAID Verbund \"$x\" ist OK" >> $directory/status
		echo "$x OK" >> $directory/status
	    else 
		#echo "RAID Verbund \"$x\" ist Fehlerhaft - Bitte melden Sie den Status: \"$status\" Ihrem Administrator" >> $directory/status
		echo "$x nOK $status" >> $directory/status
		echo -e "RAID Verbund \"$x\" auf Server $server ist ausgefallen. \n mdadm-Ausgabe:" >> $directory/alarm
		mdadm -D /dev/$x >> $directory/alarm
	    fi
	fi
done 

# Bei Bedarf Alarm per email versenden
if [[ -f $directory/alarm ]]; then
	emergmailer $directory
fi

# Freien Platz auf evtl. vorhandenen PVs finden

if [[ ! `pvscan -v 2>&1 |grep "No matching physical volumes found"` ]]; then
    # Von mehreren physical divices ausgehen
    IFS=$'\n'
    freespace=(`pvscan -v 2>&1 |grep PV|tr -s " "|cut -d "[" -f2 | cut -d "/" -f2|cut -d " " -f2-3`)
    totalfreespace=0
    # Ausgabezelen bearbeiten
    for zeile in ${freespace[@]}; do
	# voll ausgeschoepfte pvs ignorieren 
	if [[ ${zeile%" "*} != 0 ]]; then
	    # Einheit separieren
	    einheit=${zeile#*" "}
	    # Dezimaltrenner von , auf . aendern -> bc braucht das
	    space=`echo ${zeile%" "*} | tr "," "."`
	    # In Terrabyte (Tebibyte)  umrechnen, wenn Gigabyte (Gibibyte)
	    if [[ $einheit =~ '^G' ]]; then
		space=`echo "scale=3 ; $space/1000" | bc`
	    fi
	    # Summe bilden
	    totalfreespace=`echo "scale=3 ; $totalfreespace+$space" |bc`
        fi
    done
    # Ausgabe erzeugen
    echo "pvfree $totalfreespace $einheit" >> $directory/status
fi
