From 5e69b389122b674d762a1502980aff7fed8a70f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20C=C3=A9cile=20=28Le=5FVert=29?= Date: Wed, 14 Aug 2013 22:49:55 +0200 Subject: [PATCH] Import 3ware-status --- .../3ware-status.3ware-statusd.init | 191 ++++++++++++++++++ packaging/debian/3ware-status/README.Debian | 23 +++ packaging/debian/3ware-status/changelog | 26 +++ packaging/debian/3ware-status/compat | 1 + packaging/debian/3ware-status/control | 14 ++ packaging/debian/3ware-status/copyright | 26 +++ packaging/debian/3ware-status/dirs | 1 + packaging/debian/3ware-status/install | 1 + packaging/debian/3ware-status/rules | 42 ++++ wrapper-scripts/3ware-status | 153 ++++++++++++++ 10 files changed, 478 insertions(+) create mode 100644 packaging/debian/3ware-status/3ware-status.3ware-statusd.init create mode 100644 packaging/debian/3ware-status/README.Debian create mode 100644 packaging/debian/3ware-status/changelog create mode 100644 packaging/debian/3ware-status/compat create mode 100644 packaging/debian/3ware-status/control create mode 100644 packaging/debian/3ware-status/copyright create mode 100644 packaging/debian/3ware-status/dirs create mode 100644 packaging/debian/3ware-status/install create mode 100755 packaging/debian/3ware-status/rules create mode 100755 wrapper-scripts/3ware-status diff --git a/packaging/debian/3ware-status/3ware-status.3ware-statusd.init b/packaging/debian/3ware-status/3ware-status.3ware-statusd.init new file mode 100644 index 0000000..b4f06cf --- /dev/null +++ b/packaging/debian/3ware-status/3ware-status.3ware-statusd.init @@ -0,0 +1,191 @@ +#! /bin/sh + +# Author: Petter Reinholdtsen +# License: GNU General Public License v2 or later +# +### BEGIN INIT INFO +# Provides: 3ware-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 3ware-status values in the background. +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DESC="3ware-status monitor" +NAME=3ware-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/3ware-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/3ware-statusd ] && . /etc/default/3ware-statusd + +# Gracefully exit if the package has been removed. +test -x /usr/sbin/3ware-status || exit 0 + +. /lib/lsb/init-functions +[ -e /etc/default/rcS ] && . /etc/default/rcS + +if [ $RUN_DAEMON = "no" ] ; then + log_begin_msg "3ware-statusd is disabled in /etc/default/3ware-statusd, not starting." + log_end_msg 0 + exit 0 +fi + +check_3ware() { + 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 (3ware-status) |grep -q 'NOT OPTIMAL' ; then + BADRAID=true + logger -t 3ware-statusd "detected non-optimal RAID status" + else + BADRAID=false + fi + STATUSCHANGE=false + if [ true = "$BADRAID" ] ; then + # RAID not OK + (3ware-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 < /dev/null 2>&1 + 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 + start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE + 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_3ware) + check_3ware + ;; + 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 diff --git a/packaging/debian/3ware-status/README.Debian b/packaging/debian/3ware-status/README.Debian new file mode 100644 index 0000000..2e31313 --- /dev/null +++ b/packaging/debian/3ware-status/README.Debian @@ -0,0 +1,23 @@ +README.Debian for 3ware-status package +-------------------------------------- + +Possible configuration: +----------------------- + +If you want to change the default configuration of the init script you +can create the file /etc/default/3ware-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) Wed, 10 Oct 2007 10:19:28 +0200 diff --git a/packaging/debian/3ware-status/changelog b/packaging/debian/3ware-status/changelog new file mode 100644 index 0000000..f265a10 --- /dev/null +++ b/packaging/debian/3ware-status/changelog @@ -0,0 +1,26 @@ +3ware-status (0.4) unstable; urgency=low + + * Now handle different tw-cli output for 9000 series cards. + * Will now fail if tw-cli binary cannot be found. + * Add --nagios parameter (run through nrpe). + * Import initscript changes from mpt-status 1.2.0-7 package. + + -- Adam Cécile (Le_Vert) Thu, 02 Feb 2012 11:31:45 +0100 + +3ware-status (0.3) unstable; urgency=low + + * Do not fail with empty ports. + + -- Adam Cécile (Le_Vert) Mon, 16 Aug 2010 09:27:55 +0200 + +3ware-status (0.2) unstable; urgency=low + + * Switch logical disk id and disk id. + + -- Adam Cécile (Le_Vert) Wed, 10 Oct 2007 10:55:57 +0200 + +3ware-status (0.1) unstable; urgency=low + + * Intial release. + + -- Adam Cécile (Le_Vert) Wed, 10 Oct 2007 10:19:28 +0200 diff --git a/packaging/debian/3ware-status/compat b/packaging/debian/3ware-status/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/packaging/debian/3ware-status/compat @@ -0,0 +1 @@ +5 diff --git a/packaging/debian/3ware-status/control b/packaging/debian/3ware-status/control new file mode 100644 index 0000000..ca93ca0 --- /dev/null +++ b/packaging/debian/3ware-status/control @@ -0,0 +1,14 @@ +Source: 3ware-status +Section: admin +Priority: extra +Maintainer: Adam Cécile (Le_Vert) +Build-Depends: debhelper (>= 5) +Standards-Version: 3.9.2 + +Package: 3ware-status +Architecture: all +Depends: ${shlibs:Depends}, ${misc:Depends}, python, lsb-base, daemon, bsd-mailx | mailx, tw-cli (>= 9.5.0) +Description: get RAID status out of 3ware Eskalad HW RAID controllers + The 3ware-status software is a query tool to access the running + configuration and status of 3Ware HBAs. 3ware-status allows you to + monitor the health and status of your RAID setup. diff --git a/packaging/debian/3ware-status/copyright b/packaging/debian/3ware-status/copyright new file mode 100644 index 0000000..8a7c85b --- /dev/null +++ b/packaging/debian/3ware-status/copyright @@ -0,0 +1,26 @@ +This package was debianized by Adam Cécile (Le_Vert) on +Wed, 10 Oct 2007 10:19:28 +0200. + +It was downloaded from http://hwraid.le-vert.net + +Copyright Holder: + Copyright (C) 2007-2012 Adam Cécile (Le_Vert) + +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 version 2 (or later) see `/usr/share/common-licenses/GPL-2'. + +This package is highly based on Steffen Joeris works done +for the mpt-status package. +Thanks a lot Steffen! diff --git a/packaging/debian/3ware-status/dirs b/packaging/debian/3ware-status/dirs new file mode 100644 index 0000000..236670a --- /dev/null +++ b/packaging/debian/3ware-status/dirs @@ -0,0 +1 @@ +usr/sbin diff --git a/packaging/debian/3ware-status/install b/packaging/debian/3ware-status/install new file mode 100644 index 0000000..f4dc159 --- /dev/null +++ b/packaging/debian/3ware-status/install @@ -0,0 +1 @@ +3ware-status usr/sbin diff --git a/packaging/debian/3ware-status/rules b/packaging/debian/3ware-status/rules new file mode 100755 index 0000000..9be7a26 --- /dev/null +++ b/packaging/debian/3ware-status/rules @@ -0,0 +1,42 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +build: build-arch build-indep +build-arch: +build-indep: + +clean: + dh_testdir + dh_testroot + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + +binary-arch: build install +binary-indep: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_install + dh_installinit --name 3ware-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 diff --git a/wrapper-scripts/3ware-status b/wrapper-scripts/3ware-status new file mode 100755 index 0000000..dd20d73 --- /dev/null +++ b/wrapper-scripts/3ware-status @@ -0,0 +1,153 @@ +#!/usr/bin/python + +import os +import re +import sys + +binarypath = "/usr/sbin/tw-cli" + +if len(sys.argv) > 2: + print 'Usage: 3ware-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: 3ware-status [--nagios]' + sys.exit(1) + +# Check binary exists (and +x), if not print an error message +# or return UNKNOWN nagios error code +if os.path.exists(binarypath) and os.access(binarypath, os.X_OK): + pass +else: + if nagiosmode: + print 'UNKNOWN - Cannot find '+binarypath + else: + print 'Cannot find '+binarypath+'. Please install it.' + sys.exit(3) + + +# Get command output +def getOutput(cmd): + output = os.popen(cmd) + lines = [] + for line in output: + if not re.match(r'^$',line.strip()): + lines.append(line.strip()) + return lines + +def returnControllerList(output): + lines = [] + for line in output: + if re.match(r'^c[0-9]+\s.*$',line.strip()): + lines.append(line.split()[0]) + return lines + +def returnDiskList(output): + lines = [] + for line in output: + if re.match(r'^[p][0-9]+\s.*$',line.strip()): + # Shoudl contain something like 'u0' + # '-' means the drive doesn't belong to any array + # If is NOT PRESENT too, it just means this is an empty port + if not line.split()[2].strip() == '-' and not line.split()[1].strip() == 'NOT-PRESENT': + lines.append(line.split()) + if fake_failure: + lines[0][1] = 'NOT PRESENT' + return lines + +def returnArrayList(output): + lines = [] + for line in output: + if re.match(r'^[u][0-9]+\s.*$',line.strip()): + lines.append(line.split()) + if fake_failure: + lines[0][2] = 'DEGRADED' + return lines + +# A way to force a fake failure +fake_failure = False +if os.path.exists('/root/fake_3ware_failure'): + fake_failure = True + +cmd = binarypath+' info' +output = getOutput(cmd) +controllerlist = returnControllerList(output) + +bad = False + + +# List available controller +if not nagiosmode: + print '-- Controller informations --' + print '-- ID | Model' + for controller in controllerlist: + cmd = binarypath+' info '+controller+' model' + model = getOutput(cmd)[0].split(' = ')[1].strip() + print controller+' | '+model + print '' + +# List arrays +if not nagiosmode: + print '-- Arrays informations --' + print '-- ID\tType\tSize\tStatus' +for controller in controllerlist: + cmd = binarypath+' info '+controller + output = getOutput(cmd) + arraylist = returnArrayList(output) + for array in arraylist: + type = array[1].replace('-','') + id = controller+array[0] + size = array[6].split('.')[0]+'G' + status = array[2] + if not status == 'OK': + bad = True + nagiosbadarray=nagiosbadarray+1 + else: + nagiosgoodarray=nagiosgoodarray+1 + if not nagiosmode: + print id+'\t'+type+'\t'+size+'\t'+status +if not nagiosmode: + print '' + +# List disks +if not nagiosmode: + print '-- Disks informations' + print '-- ID\tModel\t\t\tStatus' +for controller in controllerlist: + cmd = binarypath+' info '+controller + output = getOutput(cmd) + disklist = returnDiskList(output) + for disk in disklist: + id = controller+disk[2]+disk[0] + cmd = binarypath+' info '+controller+' '+disk[0]+' model' + model = getOutput(cmd)[0].split(' = ')[1].strip() + cmd = binarypath+' info '+controller+' '+disk[0]+' status' + status = getOutput(cmd)[0].split(' = ')[1].strip() + if not status == 'OK': + bad = Truei + nagiosbaddisk=nagiosbaddisk+1 + else: + nagiosgooddisk=nagiosgooddisk+1 + if not nagiosmode: + print id+'\t'+model+'\t'+status + +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)