Import megaide-status

This commit is contained in:
Adam Cécile (Le_Vert) 2013-08-14 23:12:07 +02:00
parent becaddbd9d
commit 1b8bf4a486
11 changed files with 453 additions and 0 deletions

View File

@ -0,0 +1,41 @@
README.Debian for megaide-status package
----------------------------------------
Required configuration:
-----------------------
This software uses informations from /proc/megaide/.
However the megaide kernel module report all disk controller ports, even if
there are not used.
So there is now way to figure out if a disk is not used or if it's offline.
That's why I added /etc/megaide-status.conf configuration file which should
be filled with "in-use" disks ids.
The syntaxe is 'c<controlleride>u<logicalvolid>p<physicaldiskid>'.
In exemple, first disk on second logicial volume and third controller is:
c2u1p0
The default configuration file is suitable for regular SATA systems with
only one RAID array.
Possible configuration:
-----------------------
If you want to change the default configuration of the init script you
can create the file /etc/default/megaide-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, 04 Feb 2008 17:28:20 +0100

View File

@ -0,0 +1,11 @@
megaide-status (0.2) unstable; urgency=low
* Packaging cleanup.
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Thu, 21 Aug 2008 15:14:04 +0200
megaide-status (0.1) unstable; urgency=low
* Initial release.
-- Adam Cécile (Le_Vert) <gandalf@le-vert.net> Mon, 04 Feb 2008 17:28:20 +0100

View File

@ -0,0 +1 @@
4

View File

@ -0,0 +1,13 @@
Source: megaide-status
Section: admin
Priority: optional
Maintainer: Adam Cécile (Le_Vert) <gandalf@le-vert.net>
Build-Depends: debhelper (>= 4)
Standards-Version: 3.8.0
Package: megaide-status
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, python, lsb-base, daemon, mailx
Description: get RAID status out of LSI MegaIDE Software RAID controllers
The megaide-status software is a query tool to access the running
configuration and status of LSI MegaIDE HBAs.

View File

@ -0,0 +1,24 @@
This package was debianized by Adam Cécile (Le_Vert) <gandalf@le-vert.net> on
Mon, 04 Feb 2008 17:28:20 +0100.
It was downloaded from http://hwraid.le-vert.net
Copyright Holder: Copyright (C) 2008 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, version 2
as published by the Free Software Foundation.
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,2 @@
usr/sbin
etc

View File

@ -0,0 +1,2 @@
megaide-status usr/sbin
megaide-status.conf etc

View File

@ -0,0 +1,202 @@
#! /bin/sh
# Author: Petter Reinholdtsen <pere@hungry.com>
# License: GNU General Public License v2 or later
#
### BEGIN INIT INFO
# Provides: megaide-statusd
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 1 0 6
# Short-Description: Check megaide-status values in the background.
### END INIT INFO
set -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DESC="megaide-status monitor"
NAME=megaide-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/megaide-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/megaide-statusd ] && . /etc/default/megaide-statusd
# Gracefully exit if the package has been removed.
test -x /usr/sbin/megaide-status || exit 0
. /lib/lsb/init-functions
. /etc/default/rcS
if [ $RUN_DAEMON = "no" ] ; then
log_begin_msg "megaide-statusd is disabled in /etc/default/megaide-statusd, not starting."
log_end_msg 0
exit 0
fi
check_megaide() {
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 (megaide-status) |grep -q 'NOT OPTIMAL' ; then
BADRAID=true
logger -t megaide-statusd "detected non-optimal RAID status"
else
BADRAID=false
fi
STATUSCHANGE=false
if [ true = "$BADRAID" ] ; then
# RAID not OK
(megaide-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 megaide-statusd.
The megaide-status program reports that one of the RAIDs changed state:
EOF
if [ -f $STATUSFILE ] ; then
cat $STATUSFILE
else
(megaide-status)
fi
echo
echo "Report from $0 on $hostname"
) | mail -s "info: MegaRAID 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/megaide-statusd check_megaide" | 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 $SCRIPTNAME check_megaide
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 --oknodo --stop --quiet --pidfile $PIDFILE
DAEMONPID=`ps aux | grep '/usr/bin/daemon /etc/init.d/megaide-statusd check_megaide' | grep -v 'grep' | awk '{ print $2 }'`
SCRIPTPID=`cat $PIDFILE`
kill -9 $DAEMONPID $SCRIPTPID || true
rm -f $PIDFILE
return 0
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/megaide-statusd check_megaide' | 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_megaide)
check_megaide
;;
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

View File

@ -0,0 +1,38 @@
#!/usr/bin/make -f
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
build:
clean:
dh_testdir
dh_testroot
dh_clean
install:
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
binary-arch: build install
binary-indep: build install
dh_testdir -i
dh_testroot -i
dh_installchangelogs -i
dh_installdocs -i
dh_install -i
dh_installinit -i --name megaide-statusd
dh_link -i
dh_strip -i
dh_compress -i
dh_fixperms -i
dh_installdeb -i
dh_shlibdeps -i
dh_gencontrol -i
dh_md5sums -i
dh_builddeb -i
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

114
wrapper-scripts/megaide-status Executable file
View File

@ -0,0 +1,114 @@
#!/usr/bin/python
import os
import re
import sys
if len(sys.argv) > 2:
print 'Usage: megaide-status [-d]'
sys.exit(1)
printarray = True
printcontroller = True
if len(sys.argv) > 1:
if sys.argv[1] == '-d':
printarray = False
printcontroller = False
else:
print 'Usage: megaide-status [-d]'
sys.exit(1)
def returnControllerNumber():
for dir in os.listdir('/proc/megaide/'):
# We don't really care about how many entries are
# First is 0, last one is number
number=dir
return int(number)
def returnArrayNumber(controllerid):
list()
for array in os.listdir('/proc/megaide/'+str(controllerid)+'/logicaldrives/'):
absopath='/proc/megaide/'+str(controllerid)+'/logicaldrives/'+array
if os.system('grep -q "This logical drive is not present" '+absopath):
return int(array.strip('_info').strip('log_drv_'))
def returnArrayInfo(controllerid,arrayid):
id = 'c'+str(controllerid)+'u'+str(arrayid)
f = open('/proc/megaide/'+str(controllerid)+'/logicaldrives/'+'log_drv_'+str(arrayid)+'_info')
for line in f:
if re.match(r'^RAID Level :.*$',line.strip()):
type = 'RAID'+line.split('Status')[0].strip().split()[4]
if re.match(r'^Sectors :.*$',line.strip()):
size = line.split('Stripe Size')[0].split(':')[1].strip()
size = str(int(round(float(size) * 512 / 1000 / 1000 / 1000)))+'G'
if re.match(r'^.*Status :.*$',line.strip()):
state = line.split('Status')[1].split(':')[1].strip()
f.close()
return [id,type,size,state]
def returnDiskInfo():
# Megaide module report all available port, even there's no disk on it
# The problem is that an used offline disk will be reported as NOT PRESET
# So we can't know if it's not used or failed
# Let's use a conf file for this
# Conf file should looks like:
# c0u0d0
# c0u0d2
# If logical drive 0 uses disk 0 and disk 2 (chan0 disk0, chan1 disk 0)
f = open('/etc/megaide-status.conf')
table = []
for line in f:
if re.match('^c[0-9]+u[0-9]+p[0-9]+$',line.strip()):
# Valid disk entry
controllerid=line.split('u')[0].strip().strip('c')
diskid=line.split('p')[1].strip()
id=line.strip()
f2 = open('/proc/megaide/'+controllerid+'/physicaldrives/phy_drv_'+diskid+'_info')
for line in f2:
if re.match('^Model No :.*$',line.strip()):
model=line.split(':')[1].strip()
if re.match('^Status :.*$',line.strip()):
state=line.split()[2].strip()
if re.match('^Drive is Not Present.*$',line.strip()):
model='Unknown'
state='OFFLINE'
f2.close()
table.append([id, state, model])
f.close()
return table
controllernumber = returnControllerNumber()
bad = False
if printarray:
controllerid = 0
print '-- Arrays informations --'
print '-- ID | Type | Size | Status'
while controllerid <= controllernumber:
arrayid = 0
arraynumber = returnArrayNumber(controllerid)
while arrayid <= arraynumber:
arrayinfo = returnArrayInfo(controllerid,arrayid)
print arrayinfo[0]+' | '+arrayinfo[1]+' | '+arrayinfo[2]+' | '+arrayinfo[3]
arrayid += 1
if not arrayinfo[3] == 'ONLINE':
bad=True
controllerid += 1
print ''
print '-- Disks informations'
print '-- ID | Model | Status'
controllerid = 0
while controllerid <= controllernumber:
diskinfo = returnDiskInfo()
for disk in diskinfo:
print disk[0]+' | '+disk[2]+' | '+disk[1]
if not disk[1] == 'ONLINE':
bad=True
controllerid += 1
if bad:
print '\nThere is at least one disk/array in a NOT OPTIMAL state.'
sys.exit(1)

View File

@ -0,0 +1,5 @@
# First and third disk on first controller first raid array
# That should be okay if you're using regular RAID array with two SATA disks
# Tested on Nec 110R 1U rack server
c0u0p0
c0u0p2