mirror of https://github.com/eLvErDe/hwraid.git
Import megaide-status
This commit is contained in:
parent
becaddbd9d
commit
1b8bf4a486
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
4
|
|
@ -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.
|
|
@ -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!
|
|
@ -0,0 +1,2 @@
|
|||
usr/sbin
|
||||
etc
|
|
@ -0,0 +1,2 @@
|
|||
megaide-status usr/sbin
|
||||
megaide-status.conf etc
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
Loading…
Reference in New Issue