Import sas2ircu-status

This commit is contained in:
Adam Cécile (Le_Vert) 2013-08-14 23:16:47 +02:00
parent 0c5906c391
commit 98672a7cc9
10 changed files with 510 additions and 0 deletions

View File

@ -0,0 +1,23 @@
README.Debian for sas2ircu-status package
----------------------------------------
Possible configuration:
----------------------
If you want to change the default configuration of the init script you
can create the file /etc/default/sas2ircu-statusd and specify the following
values.
MAILTO=
PERIOD=
REMIND=
Use MAILTO to specify which user shall get the status mails
(default is root).
With PERIOD you can fix the seconds between each check.
And REMIND specifies the seconds between each reminder.
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Mon, 24 Sep 2007 15:55:09 +0200

View File

@ -0,0 +1,36 @@
sas2ircu-status (0.5) unstable; urgency=low
* Use full sas2ircu path to avoid issues if PATH is not set (Closes: #75).
* Don't treat inactive arrays as failed ones (Closes: #219).
* Ignore non-RAID controllers (Closes: #240).
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Fri, 26 Jul 2013 15:17:06 +0200
sas2ircu-status (0.4) unstable; urgency=low
* Fix a stupid mistake breaking multi-array support (Closes: #214).
Thanks to <oosterhout@fox-it.com> for his patch.
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Tue, 17 Jul 2012 21:38:42 +0200
sas2ircu-status (0.3) unstable; urgency=low
* One disk may not appear if sas2ircu return an enclosure element after
disks list (Closes: http://hwraid.le-vert.net/ticket/65).
* Import init script changes from mpt-status-1.2.0-7 package:
- Script won't stop anymore because of set -e
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Mon, 18 Jul 2011 17:38:39 +0200
sas2ircu-status (0.2) unstable; urgency=low
* Add --nagios so the script can be called through NRPE.
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Thu, 09 Dec 2010 11:25:54 +0100
sas2ircu-status (0.1) unstable; urgency=low
* Initial release.
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Wed, 08 Dec 2010 19:04:52 +0100

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1,14 @@
Source: sas2ircu-status
Section: admin
Priority: extra
Maintainer: Adam Cécile (Le_Vert) <gandalf@le-vert.net>
Build-Depends: debhelper (>= 5)
Standards-Version: 3.9.4
Package: sas2ircu-status
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, python, lsb-base, daemon, bsd-mailx | mailx, sas2ircu
Description: get RAID status out of LSI Fusion MPT SAS2 HW RAID controllers
The sas2ircu-status software is a query tool to access the running
configuration and status of LSI Fusion MPT SAS2 HBAs. sas2ircu-status allows
you to monitor the health and status of your RAID setup.

View File

@ -0,0 +1,26 @@
This package was debianized by Adam Cécile (Le_Vert) <gandalf@le-vert.net> on
Wed, 08 Dec 2010 19:04:52 +0100.
It was downloaded from http://hwraid.le-vert.net
Copyright Holder:
Copyright (C) 2010 Adam Cécile (Le_Vert) <gandalf@le-vert.net>
License:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANDABILITY of FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for details.
On Debian GNU/Linux systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.
This package is highly based on Steffen Joeris <white@debian.org> works done
for the mpt-status package.
Thanks a lot Steffen!

View File

@ -0,0 +1 @@
usr/sbin

View File

@ -0,0 +1 @@
sas2ircu-status usr/sbin

View File

@ -0,0 +1,42 @@
#!/usr/bin/make -f
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
build:
build-arch:
build-indep:
clean:
dh_testdir
dh_testroot
dh_clean
install:
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
binary-arch: install
binary-indep: install
dh_testdir
dh_testroot
dh_installchangelogs
dh_installdocs
dh_install
# Must be run after afacli-makedev
dh_installinit --name sas2ircu-statusd \
--update-rcd-params="start 21 2 3 4 5 . stop 19 0 1 6 ."
dh_link
dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

View File

@ -0,0 +1,199 @@
#! /bin/sh
# Author: Petter Reinholdtsen <pere@hungry.com>
# License: GNU General Public License v2 or later
#
### BEGIN INIT INFO
# Provides: sas2ircu-statusd
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Check sas2ircu-status values in the background.
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DESC="sas2ircu-status monitor"
NAME=sas2ircu-statusd
PIDFILE=/var/run/$NAME.pid
STATUSFILE=/var/run/$NAME.status
SCRIPTNAME=/etc/init.d/$NAME
# Do not touch you can configure this in /etc/default/sas2ircu-statusd
MAILTO=root # Where to report problems
PERIOD=600 # Seconds between each check (default 10 minutes)
REMIND=7200 # Seconds between each reminder (default 2 hours)
RUN_DAEMON=yes
[ -e /etc/default/sas2ircu-statusd ] && . /etc/default/sas2ircu-statusd
# Gracefully exit if the package has been removed.
test -x /usr/sbin/sas2ircu-status || exit 0
. /lib/lsb/init-functions
[ -e /etc/default/rcS ] && . /etc/default/rcS
if [ $RUN_DAEMON = "no" ] ; then
log_begin_msg "sas2ircu-statusd is disabled in /etc/default/sas2ircu-statusd, not starting."
log_end_msg 0
exit 0
fi
check_sas2ircu() {
echo $$ > $PIDFILE.new && mv $PIDFILE.new $PIDFILE
while true ; do
# Check ever $PERIOD seconds, send email on every status
# change and repeat ever $REMIND seconds if the raid is still
# bad.
if (sas2ircu-status) |grep -q 'NOT OPTIMAL' ; then
BADRAID=true
logger -t sas2ircu-statusd "detected non-optimal RAID status"
else
BADRAID=false
fi
STATUSCHANGE=false
if [ true = "$BADRAID" ] ; then
# RAID not OK
(sas2ircu-status) > $STATUSFILE.new
if [ ! -f $STATUSFILE ] ; then # RAID just became broken
STATUSCHANGE=true
mv $STATUSFILE.new $STATUSFILE
elif cmp -s $STATUSFILE $STATUSFILE.new ; then
# No change. Should we send reminder?
LASTTIME="`stat -c '%Z' $STATUSFILE`"
NOW="`date +%s`"
SINCELAST="`expr $NOW - $LASTTIME`"
if [ $REMIND -le "$SINCELAST" ]; then
# Time to send reminder
STATUSCHANGE=true
mv $STATUSFILE.new $STATUSFILE
else
rm $STATUSFILE.new
fi
else
STATUSCHANGE=true
mv $STATUSFILE.new $STATUSFILE
fi
else
# RAID OK
if [ -f $STATUSFILE ] ; then
rm $STATUSFILE
STATUSCHANGE=true
fi
fi
if [ true = "$STATUSCHANGE" ]; then
hostname="`uname -n`"
(
cat <<EOF
This is a RAID status update from sas2ircu-statusd.
The sas2ircu-status program reports that one of the RAIDs changed state:
EOF
if [ -f $STATUSFILE ] ; then
cat $STATUSFILE
else
(sas2ircu-status)
fi
echo
echo "Report from $0 on $hostname"
) | mail -s "info: SAS2IRCU raid status change on $hostname" $MAILTO
fi
sleep $PERIOD
done
}
check_daemon() {
# Let's check if there is a daemon which is really running and not timing out
DAEMON_RUN=`ps aux | grep "/etc/init.d/sas2ircu-statusd check_sas2ircu" | grep -v grep | grep -v daemon`
if [ -n "$DAEMON_RUN" ] ; then
return 1;
else
return 0;
fi
}
#
# Function that starts the daemon/service.
#
d_start() {
[ -f $PIDFILE ] && PID="`cat $PIDFILE`"
if [ "$PID" ] ; then
log_progress_msg "Daemon already running. Refusing to start another"
return 0
elif check_daemon ; then
# Use the daemon package to turn this script into a daemon
start-stop-daemon --start --quiet --pidfile $PIDFILE \
--oknodo --exec /usr/bin/daemon /usr/bin/daemon $SCRIPTNAME check_sas2ircu
return 0
else
log_progress_msg "Daemon is already running. Refusing to start another"
return 0
fi
}
#
# Function that stops the daemon/service.
#
d_stop() {
if [ -f $PIDFILE ] ; then
# Doesn't work (kill init script instance, but not daemon...)
#start-stop-daemon --stop --oknodo --quiet --pidfile $PIDFILE > /dev/null 2>&1
DAEMONPID=`ps aux | grep '/usr/bin/daemon /etc/init.d/sas2ircu-statusd check_sas2ircu' | grep -v 'grep' | awk '{ print $2 }'`
SCRIPTPID=`cat $PIDFILE`
kill -9 $DAEMONPID $SCRIPTPID || true
rm -f $PIDFILE
else
log_progress_msg "Daemon is already stopped."
return 0
fi
}
# This is a workaround function which does not directly exit and
# therefore can be used by a restart
d_stop_by_restart() {
if [ -f $PIDFILE ] ; then
# Doesn't work (kill init script instance, but not daemon...)
#start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE
DAEMONPID=`ps aux | grep '/usr/bin/daemon /etc/init.d/sas2ircu-statusd check_sas2ircu' | grep -v 'grep' | awk '{ print $2 }'`
SCRIPTPID=`cat $PIDFILE`
kill -9 $DAEMONPID $SCRIPTPID || true
rm -f $PIDFILE
log_end_msg 0
else
log_progress_msg "Daemon is already stopped."
log_end_msg 0
fi
}
case "$1" in
start)
echo -n ""
log_begin_msg "Starting $DESC: $NAME"
d_start ; CODE=$?
log_end_msg $CODE
;;
stop)
log_begin_msg "Stopping $DESC: $NAME"
d_stop ; CODE=$?
log_end_msg $CODE
;;
check_sas2ircu)
check_sas2ircu
;;
restart|force-reload)
log_begin_msg "Restarting $DESC: $NAME"
d_stop_by_restart
sleep 1
d_start || CODE=$?
log_end_msg $CODE
;;
*)
# echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

167
wrapper-scripts/sas2ircu-status Executable file
View File

@ -0,0 +1,167 @@
#!/usr/bin/python
import os
import re
import sys
binarypath = "/usr/sbin/sas2ircu"
if len(sys.argv) > 2:
print 'Usage: sas2ircu-status [--nagios]'
sys.exit(1)
nagiosmode=False
nagiosoutput=''
nagiosgoodarray=0
nagiosbadarray=0
nagiosgooddisk=0
nagiosbaddisk=0
if len(sys.argv) > 1:
if sys.argv[1] == '--nagios':
nagiosmode=True
else:
print 'Usage: sas2ircu-status [--nagios]'
sys.exit(1)
bad=False
# Get command output
def getOutput(cmd):
output=os.popen(cmd+' 2>/dev/null')
lines=[]
for line in output:
if not re.match(r'^$',line.strip()):
lines.append(line.strip())
return lines
def getCtrlList():
cmd=binarypath+' LIST'
res=getOutput(cmd)
list = []
for line in res:
if re.match('^[0-9]+.*$',line):
ctrlnmbr,ctrlname=int(line.split()[0]),line.split()[1]
# Check if it's a RAID controller
cmd=binarypath+' '+str(ctrlnmbr)+' DISPLAY'
res=getOutput(cmd)
for line in res:
if re.match('^RAID Support\s+:\s+Yes$',line):
list.append([ctrlnmbr,ctrlname])
# ie: [['0', 'SAS2008']]
return list
def getArrayList(ctrlnmbr):
cmd=binarypath+' '+str(ctrlnmbr)+' DISPLAY'
res=getOutput(cmd)
list=[]
disklist=[]
arrayid=-1
arraystatus=''
raidlevel=''
size=''
for line in res:
if re.match('^IR volume [0-9]+.*$',line):
if arrayid == -1:
arrayid=arrayid+1
else:
list.append([arrayid,raidlevel,size,arraystatus,disklist])
arrayid=arrayid+1
if re.match('Status of volume.*$',line):
arraystatus=line.split(':')[1].strip()
if re.match('RAID level.*$',line):
raidlevel=line.split(':')[1].strip()
if re.match('Size \(in MB\)\s+.*$',line):
size=line.split(':')[1].strip()
size=str(int(round((float(size) / 1000))))+'G'
if re.match('^PHY\[[0-9]+\] Enclosure#/Slot#.*$',line):
disksid=':'.join(line.split(':')[1:]).strip()
disksid=disksid.split(':')
disklist.append(disksid)
list.append([arrayid,raidlevel,size,arraystatus,disklist])
# ie: [0, 'Okay (OKY)', 'RAID1', '1800G', [['1', '0'], ['1', '1']]]
return list
def getDiskList(ctrlnmbr):
cmd=binarypath+' '+str(ctrlnmbr)+' DISPLAY'
res=getOutput(cmd)
list=[]
diskid=-1
diskstatus=''
diskmodel=''
diskserial=''
enclid=''
slotid=''
realid=['','']
for line in res:
if re.match('^Device is a Hard disk.*$',line) or re.match('^Device is a Enclosure services device.*$',line):
if diskid == -1:
diskid=diskid+1
else:
list.append([diskid,diskstatus,diskmodel,diskserial,realid])
diskid=diskid+1
if re.match('Enclosure #.*$',line):
enclid=line.split(':')[1].strip()
if re.match('Slot #.*$',line):
slotid=line.split(':')[1].strip()
realid=[enclid,slotid]
if re.match('^State.*$',line):
diskstatus=line.split(':')[1].strip()
if re.match('^Model Number.*$',line):
diskmodel=line.split(':')[1].strip()
if re.match('^Serial No.*$',line):
diskserial=line.split(':')[1].strip()
# ie: [[0, 'Optimal (OPT)', 'Hitachi HUA72202', 'JK1151YAHUYAZZ', ['1', '0']], [1, 'Optimal (OPT)', 'Hitachi HUA72202', 'JK1151YAHUW1DZ', ['1', '1']]]
list.append([diskid,diskstatus,diskmodel,diskserial,realid])
return list
if not nagiosmode:
print '-- Controller informations --'
print '-- ID | Model'
for ctrl in getCtrlList():
print 'c'+str(ctrl[0])+' | '+ctrl[1]
print ''
if not nagiosmode:
print '-- Arrays informations --'
print '-- ID | Type | Size | Status'
for ctrl in getCtrlList():
for array in getArrayList(ctrl[0]):
if not array[3] in ['Okay (OKY)', 'Inactive, Okay (OKY)']:
bad=True
nagiosbadarray=nagiosbadarray+1
else:
nagiosgoodarray=nagiosgoodarray+1
if not nagiosmode:
print 'c'+str(ctrl[0])+'u'+str(array[0])+' | '+array[1]+' | '+array[2]+' | '+array[3]
if not nagiosmode:
print ''
if not nagiosmode:
print '-- Disks informations'
print '-- ID | Model | Status'
for ctrl in getCtrlList():
for disk in getDiskList(ctrl[0]):
# Compare disk enc/slot to array's ones
for array in getArrayList(ctrl[0]):
for arraydisk in array[4]:
if arraydisk == disk[4]:
if not disk[1] == 'Optimal (OPT)':
bad=True
nagiosbaddisk=nagiosbaddisk+1
else:
nagiosgooddisk=nagiosgooddisk+1
if not nagiosmode:
print 'c'+str(ctrl[0])+'u'+str(array[0])+'p'+str(disk[0])+' | '+disk[2]+' ('+disk[3]+') | '+disk[1]
if nagiosmode:
if bad:
print 'RAID ERROR - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk)
sys.exit(2)
else:
print 'RAID OK - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk)
else:
if bad:
print '\nThere is at least one disk/array in a NOT OPTIMAL state.'
sys.exit(1)