diff --git a/wrapper-scripts/3ware-status b/wrapper-scripts/3ware-status index 19c59b6..d099ab0 100755 --- a/wrapper-scripts/3ware-status +++ b/wrapper-scripts/3ware-status @@ -7,33 +7,33 @@ import sys binarypath = "/usr/sbin/tw-cli" if len(sys.argv) > 2: - print 'Usage: 3ware-status [--nagios]' + print "Usage: 3ware-status [--nagios]" sys.exit(1) -nagiosmode=False -nagiosoutput='' -nagiosgoodarray=0 -nagiosbadarray=0 -nagiosgooddisk=0 -nagiosbaddisk=0 +nagiosmode = False +nagiosoutput = "" +nagiosgoodarray = 0 +nagiosbadarray = 0 +nagiosgooddisk = 0 +nagiosbaddisk = 0 if len(sys.argv) > 1: - if sys.argv[1] == '--nagios': - nagiosmode=True + if sys.argv[1] == "--nagios": + nagiosmode = True else: - print 'Usage: 3ware-status [--nagios]' + 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 + pass else: - if nagiosmode: - print 'UNKNOWN - Cannot find '+binarypath - else: - print 'Cannot find '+binarypath+'. Please install it.' - sys.exit(3) + if nagiosmode: + print "UNKNOWN - Cannot find " + binarypath + else: + print "Cannot find " + binarypath + ". Please install it." + sys.exit(3) # Get command output @@ -41,45 +41,49 @@ def getOutput(cmd): output = os.popen(cmd) lines = [] for line in output: - if not re.match(r'^$',line.strip()): + 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]) + 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()): + 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': + 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' + 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()): + if re.match(r"^[u][0-9]+\s.*$", line.strip()): lines.append(line.split()) if fake_failure: - lines[0][2] = 'DEGRADED' + lines[0][2] = "DEGRADED" return lines + # A way to force a fake failure fake_failure = False -if os.path.exists('/root/fake_3ware_failure'): +if os.path.exists("/root/fake_3ware_failure"): fake_failure = True -cmd = binarypath+' info' +cmd = binarypath + " info" output = getOutput(cmd) controllerlist = returnControllerList(output) @@ -88,70 +92,74 @@ bad = False # List available controller if not nagiosmode: - print '-- Controller informations --' - print '-- ID | Model' + print "-- Controller informations --" + print "-- ID | Model" for controller in controllerlist: - cmd = binarypath+' info '+controller+' model' + cmd = binarypath + " info " + controller + " model" # https://github.com/eLvErDe/hwraid/issues/69 try: - model = getOutput(cmd)[0].split(' = ')[1].strip() + model = getOutput(cmd)[0].split(" = ")[1].strip() except IndexError: - model = 'N/A' - print controller+' | '+model - print '' + model = "N/A" + print controller + " | " + model + print "" # List arrays if not nagiosmode: - print '-- Arrays informations --' - print '-- ID\tType\tSize\tStatus' + print "-- Arrays informations --" + print "-- ID\tType\tSize\tStatus" for controller in controllerlist: - cmd = binarypath+' info '+controller + 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' + type = array[1].replace("-", "") + id = controller + array[0] + size = array[6].split(".")[0] + "G" status = array[2] - if not status in ['OK','VERIFYING']: + if not status in ["OK", "VERIFYING"]: bad = True - nagiosbadarray=nagiosbadarray+1 + nagiosbadarray = nagiosbadarray + 1 else: - nagiosgoodarray=nagiosgoodarray+1 + nagiosgoodarray = nagiosgoodarray + 1 if not nagiosmode: - print id+'\t'+type+'\t'+size+'\t'+status + print id + "\t" + type + "\t" + size + "\t" + status if not nagiosmode: - print '' + print "" # List disks if not nagiosmode: - print '-- Disks informations' - print '-- ID\tModel\t\t\tStatus' + print "-- Disks informations" + print "-- ID\tModel\t\t\tStatus" for controller in controllerlist: - cmd = binarypath+' info '+controller + 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': + 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 = True - nagiosbaddisk=nagiosbaddisk+1 + nagiosbaddisk = nagiosbaddisk + 1 else: - nagiosgooddisk=nagiosgooddisk+1 + nagiosgooddisk = nagiosgooddisk + 1 if not nagiosmode: - print id+'\t'+model+'\t'+status + 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) + 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) + 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.' + print "\nThere is at least one disk/array in a NOT OPTIMAL state." sys.exit(1) diff --git a/wrapper-scripts/aacraid-status b/wrapper-scripts/aacraid-status index 06694da..1b99218 100644 --- a/wrapper-scripts/aacraid-status +++ b/wrapper-scripts/aacraid-status @@ -9,15 +9,17 @@ from argparse import ArgumentParser # My own ArgumentParser with single-line stdout output and unknown state Nagios retcode class NagiosArgumentParser(ArgumentParser): def error(self, message): - sys.stdout.write('UNKNOWN: Bad arguments (see --help): %s\n' % message) + sys.stdout.write("UNKNOWN: Bad arguments (see --help): %s\n" % message) sys.exit(3) + def parse_args(): - parser = NagiosArgumentParser(description='Adaptec AACRAID status script') - parser.add_argument('-d', '--disks-only', action="store_true", help='Only disply disk statuses') - parser.add_argument('-n', '--nagios', action="store_true", help='Use Nagios-like output and return code') + parser = NagiosArgumentParser(description="Adaptec AACRAID status script") + parser.add_argument("-d", "--disks-only", action="store_true", help="Only disply disk statuses") + parser.add_argument("-n", "--nagios", action="store_true", help="Use Nagios-like output and return code") return parser.parse_args() + def which(program): fpath, fname = os.path.split(program) if fpath: @@ -25,7 +27,7 @@ def which(program): return program else: # Add some defaults - os.environ["PATH"] += os.pathsep + '/usr/StorMan/arcconf' + os.environ["PATH"] += os.pathsep + "/usr/StorMan/arcconf" os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.realpath(sys.argv[0])) for path in os.environ["PATH"].split(os.pathsep): path = path.strip('"') @@ -34,58 +36,65 @@ def which(program): return exe_file return None + def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + # Get command output def getOutput(cmd): - output = os.popen('%s 2>%s' % (cmd, os.devnull)) + output = os.popen("%s 2>%s" % (cmd, os.devnull)) lines = [] for line in output: - if not re.match(r'^$',line.strip()): + if not re.match(r"^$", line.strip()): lines.append(line.strip()) return lines + def returnControllerNumber(output): for line in output: - if re.match(r'^Controllers found: [0-9]+$',line.strip()): - return int(line.split(':')[1].strip().strip('.')) + if re.match(r"^Controllers found: [0-9]+$", line.strip()): + return int(line.split(":")[1].strip().strip(".")) + def returnControllerModel(output): for line in output: - if re.match(r'^Controller Model.*$',line.strip()): - return line.split(':')[1].strip() + if re.match(r"^Controller Model.*$", line.strip()): + return line.split(":")[1].strip() + def returnControllerStatus(output): for line in output: - if re.match(r'^Controller Status.*$',line.strip()): - return line.split(':')[1].strip() + if re.match(r"^Controller Status.*$", line.strip()): + return line.split(":")[1].strip() + def returnArrayIds(output): ids = [] for line in output: - if re.match(r'^Logical [Dd]evice number [0-9]+$',line.strip()): - ids.append(re.sub(r'^Logical [Dd]evice number', '', line).strip()) + if re.match(r"^Logical [Dd]evice number [0-9]+$", line.strip()): + ids.append(re.sub(r"^Logical [Dd]evice number", "", line).strip()) return ids -def returnArrayInfo(output, ctrl_id='?'): + +def returnArrayInfo(output, ctrl_id="?"): # For testing purpose - #with open('/tmp/output') as f: + # with open('/tmp/output') as f: # output = f.read().splitlines() members = [] for line in output: # RAID level may be either N or Simple_Volume # (a disk connected to the card, not hotspare, not part of any array) - if re.match(r'^RAID level\s+: .+$',line.strip()): - type = line.split(':')[1].strip() - if re.match(r'^Status of [Ll]ogical [Dd]evice\s+: .*$',line.strip()): - status = line.split(':')[1].strip() - if re.match(r'^Size\s+: [0-9]+ MB$',line.strip()): - size = str(int(line.strip('MB').split(':')[1].strip()) / 1000) + if re.match(r"^RAID level\s+: .+$", line.strip()): + type = line.split(":")[1].strip() + if re.match(r"^Status of [Ll]ogical [Dd]evice\s+: .*$", line.strip()): + status = line.split(":")[1].strip() + if re.match(r"^Size\s+: [0-9]+ MB$", line.strip()): + size = str(int(line.strip("MB").split(":")[1].strip()) / 1000) - if re.match(r'^(Group\s[0-9]+,\s)?Segment\s[0-9]+\s+: .*$',line.strip()): + if re.match(r"^(Group\s[0-9]+,\s)?Segment\s[0-9]+\s+: .*$", line.strip()): # The line can be either (arcconf 1.x) # Group 0, Segment 0 : Present (Controller:1,Enclosure:0,Slot:0) JPW9J0N00RWMUV @@ -96,43 +105,44 @@ def returnArrayInfo(output, ctrl_id='?'): # Group 0, Segment 0 : Present (953869MB, SATA, HDD, Connector:1, Device:1) JPW9K0HZ216NJL' # Cut on : and re-join everything except first part - line = ':'.join(line.split(':')[1:]).strip() + line = ":".join(line.split(":")[1:]).strip() # Extract everything between () - device_state = re.search('\s+\((.*)\)\s+', line).group(1) + device_state = re.search("\s+\((.*)\)\s+", line).group(1) # Coma separated - device_attrs = device_state.split(',') - device_attrs = [ x.strip() for x in device_attrs ] + device_attrs = device_state.split(",") + device_attrs = [x.strip() for x in device_attrs] # Some magic here... # Strip out from the list element not matching Xyz:12 # Split on column: now we have and array of arrays like [['Controller', '1'], ['Connector', '1'], ['Device', '0']] # Casting to dict will turn Controller as key and 1 as value - device_attrs = dict([ x.split(':') for x in device_attrs if re.match('\w+:\d+', x) ]) + device_attrs = dict([x.split(":") for x in device_attrs if re.match("\w+:\d+", x)]) # Extract id for this device - if 'Controller' in device_attrs: - controller_id = device_attrs['Controller'] + if "Controller" in device_attrs: + controller_id = device_attrs["Controller"] else: controller_id = ctrl_id - if 'Channel' in device_attrs: - channel_id = device_attrs['Channel'] - elif 'Enclosure' in device_attrs: - channel_id = device_attrs['Enclosure'] - elif 'Connector' in device_attrs: - channel_id = device_attrs['Connector'] + if "Channel" in device_attrs: + channel_id = device_attrs["Channel"] + elif "Enclosure" in device_attrs: + channel_id = device_attrs["Enclosure"] + elif "Connector" in device_attrs: + channel_id = device_attrs["Connector"] else: - channel_id = '?' + channel_id = "?" - if 'Device' in device_attrs: - device_id = device_attrs['Device'] - elif 'Slot' in device_attrs: - device_id = device_attrs['Slot'] + if "Device" in device_attrs: + device_id = device_attrs["Device"] + elif "Slot" in device_attrs: + device_id = device_attrs["Slot"] else: - device_id = '?' + device_id = "?" - members.append('%s,%s,%s' % (controller_id, channel_id, device_id)) + members.append("%s,%s,%s" % (controller_id, channel_id, device_id)) + + return [type, status, size, members] - return [type,status,size,members] def returnControllerTasks(output): arrayid = False @@ -140,20 +150,21 @@ def returnControllerTasks(output): state = False tasks = [] for line in output: - if re.match(r'^Logical device\s+: [0-9]+$',line.strip()): - arrayid = line.split(':')[1].strip() - if re.match(r'^Current operation\s+: .*$',line.strip()): - type = line.split(':')[1].strip() - if re.match(r'^Percentage complete\s+: [0-9]+$',line.strip()): - state = line.split(':')[1].strip() + if re.match(r"^Logical device\s+: [0-9]+$", line.strip()): + arrayid = line.split(":")[1].strip() + if re.match(r"^Current operation\s+: .*$", line.strip()): + type = line.split(":")[1].strip() + if re.match(r"^Percentage complete\s+: [0-9]+$", line.strip()): + state = line.split(":")[1].strip() if arrayid != False and type != False and state != False: - tasks.append([arrayid,type,state]) + tasks.append([arrayid, type, state]) arrayid = False type = False state = False return tasks -def returnDisksInfo(output,controllerid): + +def returnDisksInfo(output, controllerid): diskid = False vendor = False model = False @@ -161,18 +172,18 @@ def returnDisksInfo(output,controllerid): serial = False disks = [] for line in output: - if re.match(r'^Reported Channel,Device(\(T:L\))?\s+: [0-9]+,[0-9]+(\([0-9]+:[0-9]+\))?$',line.strip()): - diskid = re.split('\s:\s',line)[1].strip() - diskid = re.sub('\(.*\)','',diskid) - diskid = str(controllerid)+','+diskid - if re.match(r'^State\s+:.*$',line.strip()): - state = line.split(':')[1].strip() - if re.match(r'^Vendor\s+:.*$',line.strip()): - vendor = line.split(':')[1].strip() - if re.match(r'^Model\s+:.*$',line.strip()): - model = line.split(':')[1].strip() - if re.match(r'^Serial number\s+:.*$',line.strip()): - serial = line.split(':')[1].strip() + if re.match(r"^Reported Channel,Device(\(T:L\))?\s+: [0-9]+,[0-9]+(\([0-9]+:[0-9]+\))?$", line.strip()): + diskid = re.split("\s:\s", line)[1].strip() + diskid = re.sub("\(.*\)", "", diskid) + diskid = str(controllerid) + "," + diskid + if re.match(r"^State\s+:.*$", line.strip()): + state = line.split(":")[1].strip() + if re.match(r"^Vendor\s+:.*$", line.strip()): + vendor = line.split(":")[1].strip() + if re.match(r"^Model\s+:.*$", line.strip()): + model = line.split(":")[1].strip() + if re.match(r"^Serial number\s+:.*$", line.strip()): + serial = line.split(":")[1].strip() if diskid != False and vendor != False and model != False and state != False and serial != False: disks.append([diskid, state, vendor, model, serial]) diskid = False @@ -182,6 +193,7 @@ def returnDisksInfo(output,controllerid): serial = False return disks + config = parse_args() if config.disks_only: printarray = False @@ -190,7 +202,7 @@ else: printarray = True printcontroller = True -nagiosoutput='' +nagiosoutput = "" nagiosgoodctrl = 0 nagiosbadctrl = 0 nagiosctrlbadarray = 0 @@ -202,20 +214,20 @@ nagiosbaddisk = 0 bad = False # Find arcconf -for arcconfbin in "arcconf","arcconf.exe": +for arcconfbin in "arcconf", "arcconf.exe": arcconfpath = which(arcconfbin) - if (arcconfpath != None): + if arcconfpath != None: break # Check binary exists (and +x), if not print an error message -if (arcconfpath != None): +if arcconfpath != None: if is_exe(arcconfpath): pass else: if config.nagios: - print 'UNKNOWN - Cannot find '+arcconfpath + print "UNKNOWN - Cannot find " + arcconfpath else: - print 'Cannot find ' + arcconfpath + 'in your PATH. Please install it.' + print "Cannot find " + arcconfpath + "in your PATH. Please install it." sys.exit(3) else: print 'Cannot find "arcconf, "arcconf.exe" in your PATH. Please install it.' @@ -232,31 +244,31 @@ if not controllernumber: # List controllers if printcontroller: if not config.nagios: - print '-- Controller informations --' - print '-- ID | Model | Status' + print "-- Controller informations --" + print "-- ID | Model | Status" controllerid = 1 while controllerid <= controllernumber: cmd = '"%s" GETCONFIG %d' % (arcconfpath, controllerid) output = getOutput(cmd) controllermodel = returnControllerModel(output) controllerstatus = returnControllerStatus(output) - if controllerstatus != 'Optimal': + if controllerstatus != "Optimal": bad = True nagiosbadctrl += 1 else: nagiosgoodctrl += 1 if not config.nagios: - print 'c'+str(controllerid-1)+' | '+controllermodel+' | '+controllerstatus + print "c" + str(controllerid - 1) + " | " + controllermodel + " | " + controllerstatus controllerid += 1 if not config.nagios: - print '' + print "" # List arrays if printarray: controllerid = 1 if not config.nagios: - print '-- Arrays informations --' - print '-- ID | Type | Size | Status | Task | Progress' + print "-- Arrays informations --" + print "-- ID | Type | Size | Status | Task | Progress" while controllerid <= controllernumber: arrayid = 0 cmd = '"%s" GETCONFIG %s' % (arcconfpath, controllerid) @@ -266,7 +278,7 @@ if printarray: cmd = '"%s" GETCONFIG %s LD %s' % (arcconfpath, controllerid, arrayid) output = getOutput(cmd) arrayinfo = returnArrayInfo(output, ctrl_id=controllerid) - if arrayinfo[1] != 'Optimal': + if arrayinfo[1] != "Optimal": nagiosbadarray += 1 bad = True else: @@ -278,43 +290,44 @@ if printarray: # Usually it should return either [0-9] or Simple_Volume but... # It can also return "6 Reed-Solomon" so we need to handle this too... # So let's match [0-9] followed by a space or EOL. - if re.match('^[0-9]+(\s|$)',arrayinfo[0]): - raidtype = re.sub('^','RAID',arrayinfo[0]) + if re.match("^[0-9]+(\s|$)", arrayinfo[0]): + raidtype = re.sub("^", "RAID", arrayinfo[0]) else: raidtype = arrayinfo[0] for tasks in tasksinfo: if int(tasks[0]) == int(arrayid): if not config.nagios: - print 'c'+str(controllerid-1)+'u'+str(arrayid)+' | '+raidtype+' | '+arrayinfo[2]+'G | '+arrayinfo[1]+' | '+tasks[1]+' | '+tasks[2]+'%' + print "c" + str(controllerid - 1) + "u" + str(arrayid) + " | " + raidtype + " | " + arrayinfo[2] + "G | " + arrayinfo[ + 1 + ] + " | " + tasks[1] + " | " + tasks[2] + "%" done = True break if done == False: if not config.nagios: - print 'c'+str(controllerid-1)+'u'+str(arrayid)+' | '+raidtype+' | '+arrayinfo[2]+'G | '+arrayinfo[1] + print "c" + str(controllerid - 1) + "u" + str(arrayid) + " | " + raidtype + " | " + arrayinfo[2] + "G | " + arrayinfo[1] controllerid += 1 if not config.nagios: - print '' + print "" # List disks controllerid = 1 if not config.nagios: - print '-- Disks informations' - print '-- ID | Model | Status' + print "-- Disks informations" + print "-- ID | Model | Status" while controllerid <= controllernumber: arrayid = 0 cmd = '"%s" GETCONFIG %s' % (arcconfpath, controllerid) output = getOutput(cmd) arrayids = returnArrayIds(output) - cmd = '"%s" GETCONFIG %d PD' % (arcconfpath, controllerid) output = getOutput(cmd) - diskinfo = returnDisksInfo(output,controllerid) + diskinfo = returnDisksInfo(output, controllerid) no_array_disk_id = 0 for disk in diskinfo: # Generic verification no matter is the disk is member of an array or not - if disk[1] not in [ 'Online', 'Online (JBOD)', 'Hot Spare', 'Ready', 'Global Hot-Spare', 'Dedicated Hot-Spare' ]: + if disk[1] not in ["Online", "Online (JBOD)", "Hot Spare", "Ready", "Global Hot-Spare", "Dedicated Hot-Spare"]: bad = True nagiosbaddisk += 1 else: @@ -333,26 +346,34 @@ while controllerid <= controllernumber: # Matched in members of this array if disk[0] == member: if not config.nagios: - print 'c'+str(controllerid-1)+'u'+str(arrayid)+'d'+str(memberid)+' | '+disk[2]+' '+disk[3]+' '+disk[4]+' | '+disk[1] + print "c" + str(controllerid - 1) + "u" + str(arrayid) + "d" + str(memberid) + " | " + disk[2] + " " + disk[3] + " " + disk[ + 4 + ] + " | " + disk[1] array_member = True memberid += 1 # Some disks may not be attached to any array (ie: global hot spare) if not array_member: if not config.nagios: - print 'c'+str(controllerid-1)+'uX'+'d'+str(no_array_disk_id)+' | '+disk[2]+' '+disk[3]+' '+disk[4]+' | '+disk[1] + print "c" + str(controllerid - 1) + "uX" + "d" + str(no_array_disk_id) + " | " + disk[2] + " " + disk[3] + " " + disk[4] + " | " + disk[1] no_array_disk_id += 1 controllerid += 1 if config.nagios: if bad: - print('RAID ERROR - Controllers OK:%d Bad:%d - Arrays OK:%d Bad:%d - Disks OK:%d Bad:%d' % (nagiosgoodctrl, nagiosbadctrl, nagiosgoodarray, nagiosbadarray, nagiosgooddisk, nagiosbaddisk)) + print ( + "RAID ERROR - Controllers OK:%d Bad:%d - Arrays OK:%d Bad:%d - Disks OK:%d Bad:%d" + % (nagiosgoodctrl, nagiosbadctrl, nagiosgoodarray, nagiosbadarray, nagiosgooddisk, nagiosbaddisk) + ) sys.exit(2) else: - print('RAID OK - Controllers OK:%d Bad:%d - Arrays OK:%d Bad:%d - Disks OK:%d Bad:%d' % (nagiosgoodctrl, nagiosbadctrl, nagiosgoodarray, nagiosbadarray, nagiosgooddisk, nagiosbaddisk)) + print ( + "RAID OK - Controllers OK:%d Bad:%d - Arrays OK:%d Bad:%d - Disks OK:%d Bad:%d" + % (nagiosgoodctrl, nagiosbadctrl, nagiosgoodarray, nagiosbadarray, nagiosgooddisk, nagiosbaddisk) + ) else: if bad: - print '\nThere is at least one disk/array in a NOT OPTIMAL state.' + print "\nThere is at least one disk/array in a NOT OPTIMAL state." print '\nUse "arcconf GETCONFIG [1-9]" to get details.' sys.exit(1) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 1b174e7..9314c61 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -11,14 +11,15 @@ import sys import pdb import inspect import argparse -if sys.platform == 'win32': - import ctypes + +if sys.platform == "win32": + import ctypes def_megaclipath = "/opt/MegaRAID/MegaCli/MegaCli64" # Non-Nagios Mode defaults nagiosmode = False -nagiosoutput='' +nagiosoutput = "" nagiosgoodarray = 0 nagiosbadarray = 0 nagiosgooddisk = 0 @@ -36,7 +37,7 @@ totalunconfdrivenumber = 0 # Hardcode a max of 16 HBA and 128 LDs for now. LDTable must be initialized to accept populating list of LD's into each ctlr's list. MaxNumHBA = 16 MaxNumLD = 128 -LDTable = [ [] * MaxNumHBA for i in range(MaxNumLD) ] +LDTable = [[] * MaxNumHBA for i in range(MaxNumLD)] NestedLDTable = [[False for i in range(MaxNumLD)] for j in range(MaxNumHBA)] # Outputs is a 'dict' of all MegaCLI outputs so we can re-use them during loops.. @@ -46,576 +47,599 @@ NagiosBadDisks = {} NagiosGoodDisks = {} # We need root access to query -if __name__ == '__main__': - # deal with command line options - parser = argparse.ArgumentParser() - parser.add_argument('--nagios', help='enable nagios support', action='store_true') - parser.add_argument('--debug', help='enable debugging output', action='store_true') - parser.add_argument('--notemp', help='disable temperature reporting', action='store_true') +if __name__ == "__main__": + # deal with command line options + parser = argparse.ArgumentParser() + parser.add_argument("--nagios", help="enable nagios support", action="store_true") + parser.add_argument("--debug", help="enable debugging output", action="store_true") + parser.add_argument("--notemp", help="disable temperature reporting", action="store_true") - args = parser.parse_args() - nagiosmode = args.nagios - debugmode = args.debug - notempmode = args.notemp + args = parser.parse_args() + nagiosmode = args.nagios + debugmode = args.debug + notempmode = args.notemp - try: - root_or_admin = os.geteuid() == 0 - except AttributeError: - root_or_admin = ctypes.windll.shell32.IsUserAnAdmin() !=0 - if not root_or_admin: - print '# This script requires Administrator privileges' - sys.exit(5) + try: + root_or_admin = os.geteuid() == 0 + except AttributeError: + root_or_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0 + if not root_or_admin: + print "# This script requires Administrator privileges" + sys.exit(5) # Functions def dbgprint(msg): - if (debugmode): - sys.stderr.write ( str('# DEBUG ('+str(inspect.currentframe().f_back.f_lineno)+') : '+msg+'\n')) + if debugmode: + sys.stderr.write(str("# DEBUG (" + str(inspect.currentframe().f_back.f_lineno) + ") : " + msg + "\n")) + def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + def which(program): - import os - fpath, fname = os.path.split(program) - if fpath: - if is_exe(program): - return program - else: - # Add some defaults - os.environ["PATH"] += os.pathsep + '/opt/MegaRAID/MegaCli' - os.environ["PATH"] += os.pathsep + '/ms/dist/hwmgmt/bin' - os.environ["PATH"] += os.pathsep + '/opt/MegaRAID/perccli' - os.environ["PATH"] += os.pathsep + '/opt/MegaRAID/storcli' - os.environ["PATH"] += os.pathsep + '/opt/lsi/storcli' - os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.realpath(sys.argv[0])) - for path in os.environ["PATH"].split(os.pathsep): - dbgprint ('Looking in PATH '+str(path)) - path = path.strip('"') - exe_file = os.path.join(path, program) - if is_exe(exe_file): - dbgprint ('Found "'+program+'" at '+exe_file) - return exe_file - return None + import os + + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + # Add some defaults + os.environ["PATH"] += os.pathsep + "/opt/MegaRAID/MegaCli" + os.environ["PATH"] += os.pathsep + "/ms/dist/hwmgmt/bin" + os.environ["PATH"] += os.pathsep + "/opt/MegaRAID/perccli" + os.environ["PATH"] += os.pathsep + "/opt/MegaRAID/storcli" + os.environ["PATH"] += os.pathsep + "/opt/lsi/storcli" + os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.realpath(sys.argv[0])) + for path in os.environ["PATH"].split(os.pathsep): + dbgprint("Looking in PATH " + str(path)) + path = path.strip('"') + exe_file = os.path.join(path, program) + if is_exe(exe_file): + dbgprint('Found "' + program + '" at ' + exe_file) + return exe_file + return None + # Find MegaCli -for megabin in "MegaCli64","MegaCli","megacli", "MegaCli.exe", "perccli64", "perccli", "storcli64", "storcli": - dbgprint ('Looking for '+str(megabin)+' in PATH...') - megaclipath = which(megabin) - if (megaclipath != None): - dbgprint ('Will use this executable: '+str(megaclipath)) - break - +for megabin in "MegaCli64", "MegaCli", "megacli", "MegaCli.exe", "perccli64", "perccli", "storcli64", "storcli": + dbgprint("Looking for " + str(megabin) + " in PATH...") + megaclipath = which(megabin) + if megaclipath != None: + dbgprint("Will use this executable: " + str(megaclipath)) + break + # Check binary exists (and +x), if not print an error message -if (megaclipath != None): - if os.path.exists(megaclipath) and os.access(megaclipath, os.X_OK): - pass - else: - if nagiosmode: - print 'UNKNOWN - Cannot find '+megaclipath - else: - print 'Cannot find ' + megaclipath + 'in your PATH. Please install it.' - sys.exit(3) +if megaclipath != None: + if os.path.exists(megaclipath) and os.access(megaclipath, os.X_OK): + pass + else: + if nagiosmode: + print "UNKNOWN - Cannot find " + megaclipath + else: + print "Cannot find " + megaclipath + "in your PATH. Please install it." + sys.exit(3) else: - print 'Cannot find "MegaCli{64,}", "megacli{64,}", "perccli{64,}" or "storcli{64,}" in your PATH. Please install one of them.' - sys.exit(3) + print 'Cannot find "MegaCli{64,}", "megacli{64,}", "perccli{64,}" or "storcli{64,}" in your PATH. Please install one of them.' + sys.exit(3) #### pdb.set_trace() -def returnWdthFromArrayCol(glarray,idx): - maxwdth = 0 - for glrow in glarray: - if ( len(glrow[idx]) > maxwdth): - maxwdth = len(glrow[idx]) - return maxwdth + +def returnWdthFromArrayCol(glarray, idx): + maxwdth = 0 + for glrow in glarray: + if len(glrow[idx]) > maxwdth: + maxwdth = len(glrow[idx]) + return maxwdth + # Get and cache command output def getOutput(cmd): - lines = [] - if ( Outputs.has_key(cmd) ): - dbgprint ("Got Cached value: "+str(cmd)) - lines = Outputs[cmd] - else: - dbgprint ("Not a Cached value: "+str(cmd)) - output = os.popen(cmd) - for line in output: - if not re.match(r'^$',line.strip()): - lines.append(line.strip()) - Outputs[cmd] = lines - return lines - + lines = [] + if Outputs.has_key(cmd): + dbgprint("Got Cached value: " + str(cmd)) + lines = Outputs[cmd] + else: + dbgprint("Not a Cached value: " + str(cmd)) + output = os.popen(cmd) + for line in output: + if not re.match(r"^$", line.strip()): + lines.append(line.strip()) + Outputs[cmd] = lines + return lines + + # Get and cache disks, make sure we don't count the same disk twice -def AddDisk(mytable,disk): - lines = [] - if ( mytable.has_key(disk) ): - dbgprint ("Disk: "+str(disk)+" Already present in Disk Table") - return False - else: - dbgprint ("Confed "+str(nagiosgooddisk)+'/'+str(nagiosbaddisk)+"Disk: "+str(disk)+" Not already present in Disk Table, adding") - mytable[disk] = True - return True +def AddDisk(mytable, disk): + lines = [] + if mytable.has_key(disk): + dbgprint("Disk: " + str(disk) + " Already present in Disk Table") + return False + else: + dbgprint("Confed " + str(nagiosgooddisk) + "/" + str(nagiosbaddisk) + "Disk: " + str(disk) + " Not already present in Disk Table, adding") + mytable[disk] = True + return True + def returnControllerNumber(output): - for line in output: - if re.match(r'^Controller Count.*$',line.strip()): - return int(line.split(':')[1].strip().strip('.')) + for line in output: + if re.match(r"^Controller Count.*$", line.strip()): + return int(line.split(":")[1].strip().strip(".")) + def returnTotalDriveNumber(output): - for line in output: - if re.match(r'Number of Physical Drives on Adapter.*$',line.strip()): - return int(line.split(':')[1].strip()) + for line in output: + if re.match(r"Number of Physical Drives on Adapter.*$", line.strip()): + return int(line.split(":")[1].strip()) + def returnRebuildProgress(output): - percent = 0 - tmpstr = '' - for line in output: - if re.match(r'^Rebuild Progress on Device at Enclosure.*, Slot .* Completed ',line.strip()): - tmpstr = line.split('Completed')[1].strip() - percent = int(tmpstr.split('%')[0].strip()) - return percent + percent = 0 + tmpstr = "" + for line in output: + if re.match(r"^Rebuild Progress on Device at Enclosure.*, Slot .* Completed ", line.strip()): + tmpstr = line.split("Completed")[1].strip() + percent = int(tmpstr.split("%")[0].strip()) + return percent -def returnConfDriveNumber(controllerid,output): - # Count the configured drives - confdrives = 0 ; enclid = 'N/A' ; slotid = 'N/A' - for line in output: - if re.match(r'Enclosure Device ID: .*$',line.strip()): - # We match here early in the analysis so reset the vars if this is a new disk we're reading.. - enclid = line.split(':')[1].strip() - elif re.match(r'Slot Number: .*$',line.strip()): - slotid = line.split(':')[1].strip() - if ( AddDisk(ConfDisks, str(controllerid) + enclid + slotid)): - confdrives += 1 - return int(confdrives) +def returnConfDriveNumber(controllerid, output): + # Count the configured drives + confdrives = 0 + enclid = "N/A" + slotid = "N/A" + for line in output: + + if re.match(r"Enclosure Device ID: .*$", line.strip()): + # We match here early in the analysis so reset the vars if this is a new disk we're reading.. + enclid = line.split(":")[1].strip() + elif re.match(r"Slot Number: .*$", line.strip()): + slotid = line.split(":")[1].strip() + if AddDisk(ConfDisks, str(controllerid) + enclid + slotid): + confdrives += 1 + return int(confdrives) + def returnUnConfDriveNumber(output): - # Count the un-configured/Hotspare drives - unconfdrives = 0 - for line in output: - if re.match(r'^Firmware state: Unconfigured.*$',line.strip()): - unconfdrives += 1 - elif re.match(r'^Firmware state: Hotspare.*$',line.strip()): - unconfdrives += 1 - return int(unconfdrives) + # Count the un-configured/Hotspare drives + unconfdrives = 0 + for line in output: + if re.match(r"^Firmware state: Unconfigured.*$", line.strip()): + unconfdrives += 1 + elif re.match(r"^Firmware state: Hotspare.*$", line.strip()): + unconfdrives += 1 + return int(unconfdrives) + def returnControllerModel(output): - for line in output: - if re.match(r'^Product Name.*$',line.strip()): - return line.split(':')[1].strip() + for line in output: + if re.match(r"^Product Name.*$", line.strip()): + return line.split(":")[1].strip() + def returnMemorySize(output): - for line in output: - if re.match(r'^Memory Size.*$',line.strip()): - return line.split(':')[1].strip() + for line in output: + if re.match(r"^Memory Size.*$", line.strip()): + return line.split(":")[1].strip() + def returnFirmwareVersion(output): - for line in output: - if re.match(r'^FW Package Build.*$',line.strip()): - return line.split(':')[1].strip() + for line in output: + if re.match(r"^FW Package Build.*$", line.strip()): + return line.split(":")[1].strip() + def returnROCTemp(output): - ROCtemp = '' - tmpstr = '' - if (notempmode): - return str('N/A') - else: - for line in output: - if re.match(r'^ROC temperature :.*$',line.strip()): - tmpstr = line.split(':')[1].strip() - ROCtemp = re.sub(' +.*$', '', tmpstr) - if ( ROCtemp != '' ): - return str(str(ROCtemp)+'C') - else: - return str('N/A') + ROCtemp = "" + tmpstr = "" + if notempmode: + return str("N/A") + else: + for line in output: + if re.match(r"^ROC temperature :.*$", line.strip()): + tmpstr = line.split(":")[1].strip() + ROCtemp = re.sub(" +.*$", "", tmpstr) + if ROCtemp != "": + return str(str(ROCtemp) + "C") + else: + return str("N/A") + def returnBBUPresence(output): - BBU = '' - tmpstr = '' - for line in output: - if re.match(r'^BBU +:.*$',line.strip()): - tmpstr = line.split(':')[1].strip() - BBU = re.sub(' +.*$', '', tmpstr) - break - if ( BBU != '' ): - return str(BBU) - else: - return str('N/A') + BBU = "" + tmpstr = "" + for line in output: + if re.match(r"^BBU +:.*$", line.strip()): + tmpstr = line.split(":")[1].strip() + BBU = re.sub(" +.*$", "", tmpstr) + break + if BBU != "": + return str(BBU) + else: + return str("N/A") + def returnBBUStatus(output): - BBUStatus = '' - tmpstr = '' - for line in output: - if re.match(r'^ *Battery Replacement required +:.*$',line.strip()): - tmpstr = line.split(':')[1].strip() - BBUStatus = re.sub(' +.*$', '', tmpstr) - break - if ( BBUStatus == 'Yes' ): - return str('REPL') - else: - return str('Good') + BBUStatus = "" + tmpstr = "" + for line in output: + if re.match(r"^ *Battery Replacement required +:.*$", line.strip()): + tmpstr = line.split(":")[1].strip() + BBUStatus = re.sub(" +.*$", "", tmpstr) + break + if BBUStatus == "Yes": + return str("REPL") + else: + return str("Good") + def returnArrayNumber(output): - i = 0 - for line in output: - if re.match(r'^(CacheCade )?Virtual Drive:.*$',line.strip()): - i += 1 - return i + i = 0 + for line in output: + if re.match(r"^(CacheCade )?Virtual Drive:.*$", line.strip()): + i += 1 + return i + def returnHBAPCIInfo(output): - busprefix = '0000' - busid = '' - devid = '' - functionid = '' - pcipath = '' - for line in output: - if re.match(r'^Bus Number.*:.*$',line.strip()): - busid = str(line.strip().split(':')[1].strip()).zfill(2) - if re.match(r'^Device Number.*:.*$',line.strip()): - devid = str(line.strip().split(':')[1].strip()).zfill(2) - if re.match(r'^Function Number.*:.*$',line.strip()): - functionid = str(line.strip().split(':')[1].strip()).zfill(1) - if busid: - pcipath = str(busprefix + ':' + busid + ':' + devid + '.' + functionid) - dbgprint("Array PCI path : "+pcipath) - return str(pcipath) - else: - return None - -def returnHBAInfo(table,output,controllerid): - controllermodel = 'Unknown' - controllerram = 'Unknown' - controllerrev = 'Unknown' - controllertemp = '' - controllermodel = returnControllerModel(output) - controllerram = returnMemorySize(output) - controllerrev = returnFirmwareVersion(output) - controllertemp = returnROCTemp(output) - controllerbbu = returnBBUPresence(output) - if controllerbbu == 'Present': - cmd = '%s -AdpBbuCmd -GetBbuStatus -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - controllerbbu = returnBBUStatus(output) - - if controllermodel != 'Unknown': - table.append([ 'c'+str(controllerid), controllermodel, controllerram, str(controllertemp), str(controllerbbu), str('FW: '+controllerrev) ]) - -def returnArrayInfo(output,controllerid,arrayid,arrayindex): - id = 'c'+str(controllerid)+'u'+str(arrayid) - operationlinennumber = False - linenumber = 0 - targetid = '' - raidtype = '' - raidlvl = '' - size = '' - state = 'N/A' - strpsz = '' - dskcache = 'N/A' - properties = '' - spandepth = 0 - diskperspan = 0 - cachecade_info = 'None' - - for line in output: - if re.match(r'^(CacheCade )?Virtual Drive:.*(Target Id: [0-9]+).*$',line.strip()): - # Extract the SCSI Target ID - targetid = line.strip().split(':')[2].split(')')[0].strip() - elif re.match(r'^RAID Level.*?:.*$',line.strip()): - # Extract the primary raid type, decide on X0 RAID level later when we hit Span Depth - raidlvl = int(line.strip().split(':')[1].split(',')[0].split('-')[1].strip()) - elif re.match(r'^Size.*?:.*$',line.strip()): - # Size reported in MB - if re.match(r'^.*MB$',line.strip().split(':')[1]): - size = line.strip().split(':')[1].strip('MB').strip() - if ( float(size) > 1000): - size = str(int(round((float(size) / 1000))))+'G' - else: - size = str(int(round(float(size))))+'M' - # Size reported in TB - elif re.match(r'^.*TB$',line.strip().split(':')[1]): - size = line.strip().split(':')[1].strip('TB').strip() - size = str(int(round((float(size) * 1000))))+'G' - # Size reported in GB (default) - else: - size = line.strip().split(':')[1].strip('GB').strip() - size = str(int(round((float(size)))))+'G' - elif re.match(r'^Span Depth.*?:.*$',line.strip()): - # If Span Depth is greater than 1 chances are we have a RAID 10, 50 or 60 - spandepth = line.strip().split(':')[1].strip() - elif re.match(r'^State.*?:.*$',line.strip()): - state = line.strip().split(':')[1].strip() - elif re.match(r'^Strip Size.*?:.*$',line.strip()): - strpsz = line.strip().split(':')[1].strip() - elif re.match(r'^Number Of Drives per span.*:.*$',line.strip()): - diskperspan = int(line.strip().split(':')[1].strip()) - elif re.match(r'^Current Cache Policy.*?:.*$',line.strip()): - props = line.strip().split(':')[1].strip() - if re.search('ReadAdaptive', props): - properties += 'ADRA' - if re.search('ReadAhead', props): - properties += 'RA' - if re.match('ReadAheadNone', props): - properties += 'NORA' - if re.search('WriteBack', props): - properties += ',WB' - if re.match('WriteThrough', props): - properties += ',WT' - elif re.match(r'^Disk Cache Policy.*?:.*$',line.strip()): - props = line.strip().split(':')[1].strip() - if re.search('Disabled', props): - dskcache = 'Disabled' - if re.search('Disk.s Default', props): - dskcache = 'Default' - if re.search('Enabled', props): - dskcache = 'Enabled' - elif re.match(r'^Ongoing Progresses.*?:.*$',line.strip()): - operationlinennumber = linenumber - elif re.match(r'Cache Cade Type\s*:.*$', line): - cachecade_info = "Type : " + line.strip().split(':')[1].strip() - elif re.match(r'^Target Id of the Associated LDs\s*:.*$', line): - associated=[] - for array in line.split(':')[1].strip().split(','): - if array.isdigit(): - associated.append('c%du%d' % (controllerid, int(array))) - if len(associated) >= 1: - cachecade_info = "Associated : %s" %(', '.join(associated)) - linenumber += 1 - - # If there was an ongoing operation, find the relevant line in the previous output - if operationlinennumber: - inprogress = str(output[operationlinennumber + 1]) - # some ugly output fix.. - str1 = inprogress.split(':')[0].strip() - str2 = inprogress.split(':')[1].strip() - inprogress = str1+" : "+str2 - else: - inprogress = 'None' - - # Compute the RAID level - NestedLDTable[int(controllerid)][int(arrayindex)] = False - if raidlvl == '': - raidtype = str('N/A') - else: - if (int(spandepth) >= 2): - raidtype = str('RAID-' + str(raidlvl) + '0') - NestedLDTable[controllerid][int(arrayindex)] = True - else: - if(raidlvl == 1): - if(diskperspan > 2): - raidtype = str('RAID-10') - NestedLDTable[controllerid][int(arrayindex)] = True - else: - raidtype = str('RAID-' + str(raidlvl)) - else: - raidtype = str('RAID-' + str(raidlvl)) - - dbgprint('RAID Level: ' + str(raidlvl) - + ' Span Depth: ' + str(spandepth) - + ' Disk Per Span: ' + str(diskperspan) - + ' Raid Type: ' + str(raidtype)) - return [id,raidtype,size,strpsz,properties,dskcache,state,targetid,cachecade_info,inprogress] - -def returnDiskInfo(output,controllerid): - arrayid = False - arrayindex = -1 - sarrayid = 'Unknown' - diskid = False - oldenclid = False - enclid = False - spanid = False - slotid = False - lsidid = 'Unknown' - table = [] - fstate = 'Offline' - substate = 'Unknown' - model = 'Unknown' - speed = 'Unknown' - dsize = 'Unknown' - temp = 'Unk0C' - percent = 0 - for line in output: - if re.match(r'^Span: [0-9]+ - Number of PDs:',line.strip()): - spanid = line.split(':')[1].strip() - spanid = re.sub(' - Number of PDs.*', '', spanid) - elif re.match(r'Enclosure Device ID: .*$',line.strip()): - # We match here early in the analysis so reset the vars if this is a new disk we're reading.. - oldenclid = enclid - enclid = line.split(':')[1].strip().replace("N/A","") - if oldenclid != False: - fstate = 'Offline' - model = 'Unknown' - speed = 'Unknown' - temp = 'Unk0C' - slotid = False - lsidid = 'Unknown' - elif re.match(r'^Coerced Size: ',line.strip()): - dsize = line.split(':')[1].strip() - dsize = re.sub(' \[.*\.*$', '', dsize) - dsize = re.sub('[0-9][0-9] GB', ' Gb', dsize) - elif re.match(r'^(CacheCade )?Virtual (Disk|Drive): [0-9]+.*$',line.strip()): - arrayindex += 1 - arrayid = line.split('(')[0].split(':')[1].strip() - elif re.match(r'^Drive.s posi*tion: DiskGroup: [0-9]+,.*$',line.strip()): - notarrayid = line.split(',')[1].split(':')[1].strip() - elif re.match(r'PD: [0-9]+ Information.*$',line.strip()): - diskid = line.split()[1].strip() - elif re.match(r'^Device Id: .*$',line.strip()): - lsidid = line.split(':')[1].strip() - elif re.match(r'Slot Number: .*$',line.strip()): - slotid = line.split(':')[1].strip() - elif re.match(r'Firmware state: .*$',line.strip()): - fstate = line.split(':')[1].strip() - subfstate = re.sub('\(.*', '', fstate) - dbgprint('Firmware State: '+str(fstate)+' '+str(subfstate)) - elif re.match(r'Inquiry Data: .*$',line.strip()): - model = line.split(':')[1].strip() - model = re.sub(' +', ' ', model) - - # re-define our "sub-code" - # our seagate drives have an ID string of - # 'Z1E19S2QST2000DM001-1CH164 CC43' - # or - # '6XW02738ST32000542AS CC32' - - m = re.match(r'(\w{8})(ST\w+)(?:-(\w{6}))?(?:\s+(\w+))', model) - if m: - if m.group(3): - model = '{0}-{1} {2} {3}'.format(m.group(2), m.group(3), m.group(4), m.group(1)) - else: - model = '{0} {1:>10} {2}'.format(m.group(2), m.group(4), m.group(1)) - continue - - # Sub code - manuf = re.sub(' .*', '', model) - dtype = re.sub(manuf+' ', '', model) - dtype = re.sub(' .*', '', dtype) - hwserial = re.sub('.*'+dtype+' *', '', model) - elif re.match(r'^Media Type: .*$',line.strip()): - mtype = line.split(':')[1].strip() - if mtype == 'Hard Disk Device': - mtype = 'HDD' - else: - if mtype == 'Solid State Device': - mtype = 'SSD' - else: - mtype = 'N/A' - elif re.match(r'Device Speed: .*$',line.strip()): - speed = line.split(':')[1].strip() - elif re.match(r'Drive Temperature :.*$',line.strip()): - if (notempmode): - temp = 'N/A' - else: - # Drive temp is amongst the last few lines matched, decide here if we add information to the table.. - temp = line.split(':')[1].strip() - temp = re.sub(' \(.*\)', '', temp) - if model != 'Unknown': - dbgprint('Disk Info: '+str(arrayid)+' '+str(diskid)+' '+str(oldenclid)) - if subfstate == 'Rebuild': - cmd = '%s pdrbld -showprog -physdrv\[%s:%s\] -a%d -NoLog' % (megaclipath, enclid, slotid, controllerid) - output = getOutput(cmd) - percent = returnRebuildProgress(output) - fstate = str('Rebuilding (%d%%)' % (percent)) - - if (( NestedLDTable[controllerid][int(arrayindex)] == True) and (spanid != False)): - sarrayid = str(arrayid)+"s"+spanid - else: - sarrayid = str(arrayid) - table.append([sarrayid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) - return table + busprefix = "0000" + busid = "" + devid = "" + functionid = "" + pcipath = "" + for line in output: + if re.match(r"^Bus Number.*:.*$", line.strip()): + busid = str(line.strip().split(":")[1].strip()).zfill(2) + if re.match(r"^Device Number.*:.*$", line.strip()): + devid = str(line.strip().split(":")[1].strip()).zfill(2) + if re.match(r"^Function Number.*:.*$", line.strip()): + functionid = str(line.strip().split(":")[1].strip()).zfill(1) + if busid: + pcipath = str(busprefix + ":" + busid + ":" + devid + "." + functionid) + dbgprint("Array PCI path : " + pcipath) + return str(pcipath) + else: + return None -def returnUnconfDiskInfo(output,controllerid): - arrayid = False - diskid = False - olddiskid = False - enclid = False - slotid = False - lsidid = 'Unknown' - table = [] - fstate = 'Offline' - substate = 'Unknown' - model = 'Unknown' - speed = 'Unknown' - mtype = 'Unknown' - dsize = 'Unknown' - temp = 'Unk0C' - ospath = 'N/A' - for line in output: - if re.match(r'Enclosure Device ID: .*$',line.strip()): - # We match here early in the analysis so reset the vars if this is a new disk we're reading.. - oldenclid = enclid - enclid = line.split(':')[1].strip().replace("N/A","") - if oldenclid != False: - arrayid = False - fstate = 'Offline' - model = 'Unknown' - speed = 'Unknown' - temp = 'Unk0C' - slotid = False - lsidid = 'Unknown' +def returnHBAInfo(table, output, controllerid): + controllermodel = "Unknown" + controllerram = "Unknown" + controllerrev = "Unknown" + controllertemp = "" + controllermodel = returnControllerModel(output) + controllerram = returnMemorySize(output) + controllerrev = returnFirmwareVersion(output) + controllertemp = returnROCTemp(output) + controllerbbu = returnBBUPresence(output) + if controllerbbu == "Present": + cmd = "%s -AdpBbuCmd -GetBbuStatus -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + controllerbbu = returnBBUStatus(output) - elif re.match(r'^Coerced Size: ',line.strip()): - dsize = line.split(':')[1].strip() - dsize = re.sub(' \[.*\.*$', '', dsize) - dsize = re.sub('[0-9][0-9] GB', ' Gb', dsize) - elif re.match(r'^Drive.s posi*tion: DiskGroup: [0-9]+,.*$',line.strip()): - arrayid = line.split(',')[1].split(':')[1].strip() - elif re.match(r'^Device Id: [0-9]+.*$',line.strip()): - diskid = line.split(':')[1].strip() - elif re.match(r'Slot Number: .*$',line.strip()): - slotid = line.split(':')[1].strip() - elif re.match(r'Firmware state: .*$',line.strip()): - fstate = line.split(':')[1].strip() - subfstate = re.sub('\(.*', '', fstate) - dbgprint('Firmware State: '+str(fstate)+' '+str(subfstate)) - elif re.match(r'Inquiry Data: .*$',line.strip()): - model = line.split(':')[1].strip() - model = re.sub(' +', ' ', model) + if controllermodel != "Unknown": + table.append(["c" + str(controllerid), controllermodel, controllerram, str(controllertemp), str(controllerbbu), str("FW: " + controllerrev)]) - # re-define our "sub-code" - # our seagate drives have an ID string of - # 'Z1E19S2QST2000DM001-1CH164 CC43' - # or - # '6XW02738ST32000542AS CC32' - m = re.match(r'(\w{8})(ST\w+)(?:-(\w{6}))?(?:\s+(\w+))', model) - if m: - if m.group(3): - model = '{0}-{1} {2} {3}'.format(m.group(2), m.group(3), m.group(4), m.group(1)) - else: - model = '{0} {1:>10} {2}'.format(m.group(2), m.group(4), m.group(1)) - continue +def returnArrayInfo(output, controllerid, arrayid, arrayindex): + id = "c" + str(controllerid) + "u" + str(arrayid) + operationlinennumber = False + linenumber = 0 + targetid = "" + raidtype = "" + raidlvl = "" + size = "" + state = "N/A" + strpsz = "" + dskcache = "N/A" + properties = "" + spandepth = 0 + diskperspan = 0 + cachecade_info = "None" - manuf = re.sub(' .*', '', model) - dtype = re.sub(manuf+' ', '', model) - dtype = re.sub(' .*', '', dtype) - hwserial = re.sub('.*'+dtype+' *', '', model) - elif re.match(r'^Media Type: .*$',line.strip()): - mtype = line.split(':')[1].strip() - if mtype == 'Hard Disk Device': - mtype = 'HDD' - else: - if mtype == 'Solid State Device': - mtype = 'SSD' - else: - mtype = 'N/A' - elif re.match(r'Device Speed: .*$',line.strip()): - speed = line.split(':')[1].strip() - elif re.match(r'Drive Temperature :.*$',line.strip()): - # Drive temp is amongst the last few lines matched, decide here if we add information to the table.. - if (notempmode): - temp = 'N/A' - else: - temp = line.split(':')[1].strip() - temp = re.sub('\(.*\)', '', temp) - if arrayid == False: - if subfstate == 'Unconfigured': - dbgprint('Unconfigured Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate)) - elif subfstate == 'Online, Spun Up': - dbgprint('Online Unconfed Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate)) - table.append([ mtype, model, dsize, fstate, speed, temp, enclid, slotid, diskid, ospath]) - return table + for line in output: + if re.match(r"^(CacheCade )?Virtual Drive:.*(Target Id: [0-9]+).*$", line.strip()): + # Extract the SCSI Target ID + targetid = line.strip().split(":")[2].split(")")[0].strip() + elif re.match(r"^RAID Level.*?:.*$", line.strip()): + # Extract the primary raid type, decide on X0 RAID level later when we hit Span Depth + raidlvl = int(line.strip().split(":")[1].split(",")[0].split("-")[1].strip()) + elif re.match(r"^Size.*?:.*$", line.strip()): + # Size reported in MB + if re.match(r"^.*MB$", line.strip().split(":")[1]): + size = line.strip().split(":")[1].strip("MB").strip() + if float(size) > 1000: + size = str(int(round((float(size) / 1000)))) + "G" + else: + size = str(int(round(float(size)))) + "M" + # Size reported in TB + elif re.match(r"^.*TB$", line.strip().split(":")[1]): + size = line.strip().split(":")[1].strip("TB").strip() + size = str(int(round((float(size) * 1000)))) + "G" + # Size reported in GB (default) + else: + size = line.strip().split(":")[1].strip("GB").strip() + size = str(int(round((float(size))))) + "G" + elif re.match(r"^Span Depth.*?:.*$", line.strip()): + # If Span Depth is greater than 1 chances are we have a RAID 10, 50 or 60 + spandepth = line.strip().split(":")[1].strip() + elif re.match(r"^State.*?:.*$", line.strip()): + state = line.strip().split(":")[1].strip() + elif re.match(r"^Strip Size.*?:.*$", line.strip()): + strpsz = line.strip().split(":")[1].strip() + elif re.match(r"^Number Of Drives per span.*:.*$", line.strip()): + diskperspan = int(line.strip().split(":")[1].strip()) + elif re.match(r"^Current Cache Policy.*?:.*$", line.strip()): + props = line.strip().split(":")[1].strip() + if re.search("ReadAdaptive", props): + properties += "ADRA" + if re.search("ReadAhead", props): + properties += "RA" + if re.match("ReadAheadNone", props): + properties += "NORA" + if re.search("WriteBack", props): + properties += ",WB" + if re.match("WriteThrough", props): + properties += ",WT" + elif re.match(r"^Disk Cache Policy.*?:.*$", line.strip()): + props = line.strip().split(":")[1].strip() + if re.search("Disabled", props): + dskcache = "Disabled" + if re.search("Disk.s Default", props): + dskcache = "Default" + if re.search("Enabled", props): + dskcache = "Enabled" + elif re.match(r"^Ongoing Progresses.*?:.*$", line.strip()): + operationlinennumber = linenumber + elif re.match(r"Cache Cade Type\s*:.*$", line): + cachecade_info = "Type : " + line.strip().split(":")[1].strip() + elif re.match(r"^Target Id of the Associated LDs\s*:.*$", line): + associated = [] + for array in line.split(":")[1].strip().split(","): + if array.isdigit(): + associated.append("c%du%d" % (controllerid, int(array))) + if len(associated) >= 1: + cachecade_info = "Associated : %s" % (", ".join(associated)) + linenumber += 1 -cmd = '%s -adpCount -NoLog' % (megaclipath) + # If there was an ongoing operation, find the relevant line in the previous output + if operationlinennumber: + inprogress = str(output[operationlinennumber + 1]) + # some ugly output fix.. + str1 = inprogress.split(":")[0].strip() + str2 = inprogress.split(":")[1].strip() + inprogress = str1 + " : " + str2 + else: + inprogress = "None" + + # Compute the RAID level + NestedLDTable[int(controllerid)][int(arrayindex)] = False + if raidlvl == "": + raidtype = str("N/A") + else: + if int(spandepth) >= 2: + raidtype = str("RAID-" + str(raidlvl) + "0") + NestedLDTable[controllerid][int(arrayindex)] = True + else: + if raidlvl == 1: + if diskperspan > 2: + raidtype = str("RAID-10") + NestedLDTable[controllerid][int(arrayindex)] = True + else: + raidtype = str("RAID-" + str(raidlvl)) + else: + raidtype = str("RAID-" + str(raidlvl)) + + dbgprint("RAID Level: " + str(raidlvl) + " Span Depth: " + str(spandepth) + " Disk Per Span: " + str(diskperspan) + " Raid Type: " + str(raidtype)) + return [id, raidtype, size, strpsz, properties, dskcache, state, targetid, cachecade_info, inprogress] + + +def returnDiskInfo(output, controllerid): + arrayid = False + arrayindex = -1 + sarrayid = "Unknown" + diskid = False + oldenclid = False + enclid = False + spanid = False + slotid = False + lsidid = "Unknown" + table = [] + fstate = "Offline" + substate = "Unknown" + model = "Unknown" + speed = "Unknown" + dsize = "Unknown" + temp = "Unk0C" + percent = 0 + for line in output: + if re.match(r"^Span: [0-9]+ - Number of PDs:", line.strip()): + spanid = line.split(":")[1].strip() + spanid = re.sub(" - Number of PDs.*", "", spanid) + elif re.match(r"Enclosure Device ID: .*$", line.strip()): + # We match here early in the analysis so reset the vars if this is a new disk we're reading.. + oldenclid = enclid + enclid = line.split(":")[1].strip().replace("N/A", "") + if oldenclid != False: + fstate = "Offline" + model = "Unknown" + speed = "Unknown" + temp = "Unk0C" + slotid = False + lsidid = "Unknown" + elif re.match(r"^Coerced Size: ", line.strip()): + dsize = line.split(":")[1].strip() + dsize = re.sub(" \[.*\.*$", "", dsize) + dsize = re.sub("[0-9][0-9] GB", " Gb", dsize) + elif re.match(r"^(CacheCade )?Virtual (Disk|Drive): [0-9]+.*$", line.strip()): + arrayindex += 1 + arrayid = line.split("(")[0].split(":")[1].strip() + elif re.match(r"^Drive.s posi*tion: DiskGroup: [0-9]+,.*$", line.strip()): + notarrayid = line.split(",")[1].split(":")[1].strip() + elif re.match(r"PD: [0-9]+ Information.*$", line.strip()): + diskid = line.split()[1].strip() + elif re.match(r"^Device Id: .*$", line.strip()): + lsidid = line.split(":")[1].strip() + elif re.match(r"Slot Number: .*$", line.strip()): + slotid = line.split(":")[1].strip() + elif re.match(r"Firmware state: .*$", line.strip()): + fstate = line.split(":")[1].strip() + subfstate = re.sub("\(.*", "", fstate) + dbgprint("Firmware State: " + str(fstate) + " " + str(subfstate)) + elif re.match(r"Inquiry Data: .*$", line.strip()): + model = line.split(":")[1].strip() + model = re.sub(" +", " ", model) + + # re-define our "sub-code" + # our seagate drives have an ID string of + # 'Z1E19S2QST2000DM001-1CH164 CC43' + # or + # '6XW02738ST32000542AS CC32' + + m = re.match(r"(\w{8})(ST\w+)(?:-(\w{6}))?(?:\s+(\w+))", model) + if m: + if m.group(3): + model = "{0}-{1} {2} {3}".format(m.group(2), m.group(3), m.group(4), m.group(1)) + else: + model = "{0} {1:>10} {2}".format(m.group(2), m.group(4), m.group(1)) + continue + + # Sub code + manuf = re.sub(" .*", "", model) + dtype = re.sub(manuf + " ", "", model) + dtype = re.sub(" .*", "", dtype) + hwserial = re.sub(".*" + dtype + " *", "", model) + elif re.match(r"^Media Type: .*$", line.strip()): + mtype = line.split(":")[1].strip() + if mtype == "Hard Disk Device": + mtype = "HDD" + else: + if mtype == "Solid State Device": + mtype = "SSD" + else: + mtype = "N/A" + elif re.match(r"Device Speed: .*$", line.strip()): + speed = line.split(":")[1].strip() + elif re.match(r"Drive Temperature :.*$", line.strip()): + if notempmode: + temp = "N/A" + else: + # Drive temp is amongst the last few lines matched, decide here if we add information to the table.. + temp = line.split(":")[1].strip() + temp = re.sub(" \(.*\)", "", temp) + if model != "Unknown": + dbgprint("Disk Info: " + str(arrayid) + " " + str(diskid) + " " + str(oldenclid)) + if subfstate == "Rebuild": + cmd = "%s pdrbld -showprog -physdrv\[%s:%s\] -a%d -NoLog" % (megaclipath, enclid, slotid, controllerid) + output = getOutput(cmd) + percent = returnRebuildProgress(output) + fstate = str("Rebuilding (%d%%)" % (percent)) + + if (NestedLDTable[controllerid][int(arrayindex)] == True) and (spanid != False): + sarrayid = str(arrayid) + "s" + spanid + else: + sarrayid = str(arrayid) + table.append([sarrayid, str(diskid), mtype, model, dsize, fstate, speed, temp, enclid, slotid, lsidid]) + return table + + +def returnUnconfDiskInfo(output, controllerid): + arrayid = False + diskid = False + olddiskid = False + enclid = False + slotid = False + lsidid = "Unknown" + table = [] + fstate = "Offline" + substate = "Unknown" + model = "Unknown" + speed = "Unknown" + mtype = "Unknown" + dsize = "Unknown" + temp = "Unk0C" + ospath = "N/A" + for line in output: + if re.match(r"Enclosure Device ID: .*$", line.strip()): + # We match here early in the analysis so reset the vars if this is a new disk we're reading.. + oldenclid = enclid + enclid = line.split(":")[1].strip().replace("N/A", "") + if oldenclid != False: + arrayid = False + fstate = "Offline" + model = "Unknown" + speed = "Unknown" + temp = "Unk0C" + slotid = False + lsidid = "Unknown" + + elif re.match(r"^Coerced Size: ", line.strip()): + dsize = line.split(":")[1].strip() + dsize = re.sub(" \[.*\.*$", "", dsize) + dsize = re.sub("[0-9][0-9] GB", " Gb", dsize) + elif re.match(r"^Drive.s posi*tion: DiskGroup: [0-9]+,.*$", line.strip()): + arrayid = line.split(",")[1].split(":")[1].strip() + elif re.match(r"^Device Id: [0-9]+.*$", line.strip()): + diskid = line.split(":")[1].strip() + elif re.match(r"Slot Number: .*$", line.strip()): + slotid = line.split(":")[1].strip() + elif re.match(r"Firmware state: .*$", line.strip()): + fstate = line.split(":")[1].strip() + subfstate = re.sub("\(.*", "", fstate) + dbgprint("Firmware State: " + str(fstate) + " " + str(subfstate)) + elif re.match(r"Inquiry Data: .*$", line.strip()): + model = line.split(":")[1].strip() + model = re.sub(" +", " ", model) + + # re-define our "sub-code" + # our seagate drives have an ID string of + # 'Z1E19S2QST2000DM001-1CH164 CC43' + # or + # '6XW02738ST32000542AS CC32' + + m = re.match(r"(\w{8})(ST\w+)(?:-(\w{6}))?(?:\s+(\w+))", model) + if m: + if m.group(3): + model = "{0}-{1} {2} {3}".format(m.group(2), m.group(3), m.group(4), m.group(1)) + else: + model = "{0} {1:>10} {2}".format(m.group(2), m.group(4), m.group(1)) + continue + + manuf = re.sub(" .*", "", model) + dtype = re.sub(manuf + " ", "", model) + dtype = re.sub(" .*", "", dtype) + hwserial = re.sub(".*" + dtype + " *", "", model) + elif re.match(r"^Media Type: .*$", line.strip()): + mtype = line.split(":")[1].strip() + if mtype == "Hard Disk Device": + mtype = "HDD" + else: + if mtype == "Solid State Device": + mtype = "SSD" + else: + mtype = "N/A" + elif re.match(r"Device Speed: .*$", line.strip()): + speed = line.split(":")[1].strip() + elif re.match(r"Drive Temperature :.*$", line.strip()): + # Drive temp is amongst the last few lines matched, decide here if we add information to the table.. + if notempmode: + temp = "N/A" + else: + temp = line.split(":")[1].strip() + temp = re.sub("\(.*\)", "", temp) + if arrayid == False: + if subfstate == "Unconfigured": + dbgprint("Unconfigured Disk: Arrayid: " + str(arrayid) + " DiskId: " + str(diskid) + " " + str(olddiskid) + " " + str(fstate)) + elif subfstate == "Online, Spun Up": + dbgprint("Online Unconfed Disk: Arrayid: " + str(arrayid) + " DiskId: " + str(diskid) + " " + str(olddiskid) + " " + str(fstate)) + table.append([mtype, model, dsize, fstate, speed, temp, enclid, slotid, diskid, ospath]) + return table + + +cmd = "%s -adpCount -NoLog" % (megaclipath) output = getOutput(cmd) controllernumber = returnControllerNumber(output) @@ -623,361 +647,376 @@ bad = False # List available controller if printcontroller: - if controllernumber: - if not nagiosmode: - print '-- Controller information --' + if controllernumber: + if not nagiosmode: + print "-- Controller information --" - i = 0 - controllerid = 0 - mlen = 0 - hbainfo = [] - while controllerid < controllernumber: - cmd = '%s -AdpAllInfo -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - returnHBAInfo(hbainfo, output,controllerid) - controllerid += 1 - mlen = returnWdthFromArrayCol(hbainfo,1) + i = 0 + controllerid = 0 + mlen = 0 + hbainfo = [] + while controllerid < controllernumber: + cmd = "%s -AdpAllInfo -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + returnHBAInfo(hbainfo, output, controllerid) + controllerid += 1 + mlen = returnWdthFromArrayCol(hbainfo, 1) - controllerid = 0 - for hba in hbainfo: - hbafmt = str('%-5s | %-'+str(mlen)+'s | %-6s | %-4s | %-6s | %-12s ') - # Header - if ( i == 0 ): - if not nagiosmode: - print hbafmt % ("-- ID","H/W Model","RAM","Temp","BBU", "Firmware") - if not nagiosmode: - print hbafmt % ( - hba[0], - hba[1], - hba[2], - hba[3], - hba[4], - hba[5]) - i += 1 - if not nagiosmode: - print '' - else: - print "No MegaRAID or PERC adapter detected on your system!" - exit(1) + controllerid = 0 + for hba in hbainfo: + hbafmt = str("%-5s | %-" + str(mlen) + "s | %-6s | %-4s | %-6s | %-12s ") + # Header + if i == 0: + if not nagiosmode: + print hbafmt % ("-- ID", "H/W Model", "RAM", "Temp", "BBU", "Firmware") + if not nagiosmode: + print hbafmt % (hba[0], hba[1], hba[2], hba[3], hba[4], hba[5]) + i += 1 + if not nagiosmode: + print "" + else: + print "No MegaRAID or PERC adapter detected on your system!" + exit(1) if printarray: - if not nagiosmode: - print '-- Array information --' + if not nagiosmode: + print "-- Array information --" - controllerid = 0 - pcipath = '' - diskpath = '' - i = 0 ; j = 0 - mlen = 0 ; rlen = 0 ; clen = 0 - while controllerid < controllernumber: - arrayindex = 0 + controllerid = 0 + pcipath = "" + diskpath = "" + i = 0 + j = 0 + mlen = 0 + rlen = 0 + clen = 0 + while controllerid < controllernumber: + arrayindex = 0 - cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraynumber = returnArrayNumber(output) - # We need to explore each HBA to look for gaps in LD's - ldid = 0 ; ldcount = 0 - while ldcount < arraynumber: - cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid) - output = getOutput(cmd) - for line in output: - if re.match(r'^Adapter.*Virtual Drive .* Does not Exist',line.strip()): - ldid += 1 - elif re.match(r'^(CacheCade )?Virtual Drive:',line.strip()): - LDTable[controllerid].append ( ldid ) - #NestedLDTable[controllerid][int(arrayindex)] = False - ldcount += 1 - ldid += 1 + cmd = "%s -LDInfo -lall -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraynumber = returnArrayNumber(output) + # We need to explore each HBA to look for gaps in LD's + ldid = 0 + ldcount = 0 + while ldcount < arraynumber: + cmd = "%s -LDInfo -l%d -a%d -NoLog" % (megaclipath, ldid, controllerid) + output = getOutput(cmd) + for line in output: + if re.match(r"^Adapter.*Virtual Drive .* Does not Exist", line.strip()): + ldid += 1 + elif re.match(r"^(CacheCade )?Virtual Drive:", line.strip()): + LDTable[controllerid].append(ldid) + # NestedLDTable[controllerid][int(arrayindex)] = False + ldcount += 1 + ldid += 1 - while arrayindex < arraynumber: - ldid = LDTable[controllerid][arrayindex] - cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid) - output = getOutput(cmd) - arrayinfo = returnArrayInfo(output, controllerid, ldid, arrayindex) - if ( len(arrayinfo[1]) > rlen): - rlen = len(arrayinfo[1]) - if ( len(arrayinfo[4]) > mlen): - mlen = len(arrayinfo[4]) - if ( len(arrayinfo[8]) > clen): - clen = len(arrayinfo[8]) - arrayindex += 1 - controllerid += 1 + while arrayindex < arraynumber: + ldid = LDTable[controllerid][arrayindex] + cmd = "%s -LDInfo -l%d -a%d -NoLog" % (megaclipath, ldid, controllerid) + output = getOutput(cmd) + arrayinfo = returnArrayInfo(output, controllerid, ldid, arrayindex) + if len(arrayinfo[1]) > rlen: + rlen = len(arrayinfo[1]) + if len(arrayinfo[4]) > mlen: + mlen = len(arrayinfo[4]) + if len(arrayinfo[8]) > clen: + clen = len(arrayinfo[8]) + arrayindex += 1 + controllerid += 1 - controllerid = 0 - while controllerid < controllernumber: - arrayindex = 0 + controllerid = 0 + while controllerid < controllernumber: + arrayindex = 0 - cmd = '%s -AdpGetPciInfo -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - pcipath = returnHBAPCIInfo(output) + cmd = "%s -AdpGetPciInfo -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + pcipath = returnHBAPCIInfo(output) - cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraynumber = returnArrayNumber(output) - while arrayindex < arraynumber: - ldid = LDTable[controllerid][arrayindex] - cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid) - output = getOutput(cmd) - arrayinfo = returnArrayInfo(output,controllerid, ldid, arrayindex) + cmd = "%s -LDInfo -lall -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraynumber = returnArrayNumber(output) + while arrayindex < arraynumber: + ldid = LDTable[controllerid][arrayindex] + cmd = "%s -LDInfo -l%d -a%d -NoLog" % (megaclipath, ldid, controllerid) + output = getOutput(cmd) + arrayinfo = returnArrayInfo(output, controllerid, ldid, arrayindex) - if pcipath: - diskprefix = str('/dev/disk/by-path/pci-' + pcipath + '-scsi-0:') - dbgprint('Will look for DISKprefix : ' + diskprefix) - # RAID disks are usually with a channel of '2', JBOD disks with a channel of '0' - for j in range (1, 8): - diskpath = diskprefix + str(j) + ':' + str(arrayinfo[7]) + ':0' - dbgprint('Looking for DISKpath : ' + diskpath) - if os.path.exists(diskpath): - arrayinfo[7] = os.path.realpath(diskpath) - dbgprint('Found DISK match: ' + diskpath + ' -> ' + arrayinfo[7]) - break - else: - arrayinfo[7] = 'N/A' + if pcipath: + diskprefix = str("/dev/disk/by-path/pci-" + pcipath + "-scsi-0:") + dbgprint("Will look for DISKprefix : " + diskprefix) + # RAID disks are usually with a channel of '2', JBOD disks with a channel of '0' + for j in range(1, 8): + diskpath = diskprefix + str(j) + ":" + str(arrayinfo[7]) + ":0" + dbgprint("Looking for DISKpath : " + diskpath) + if os.path.exists(diskpath): + arrayinfo[7] = os.path.realpath(diskpath) + dbgprint("Found DISK match: " + diskpath + " -> " + arrayinfo[7]) + break + else: + arrayinfo[7] = "N/A" - # Pad the string length, just to make sure it's aligned with the headers... - if (rlen < len("Type")): - rlen = len("Type") - if (mlen < len("Flags")): - mlen = len("Flags") - if (clen < len("CacheCade")): - clen = len("CacheCade") + # Pad the string length, just to make sure it's aligned with the headers... + if rlen < len("Type"): + rlen = len("Type") + if mlen < len("Flags"): + mlen = len("Flags") + if clen < len("CacheCade"): + clen = len("CacheCade") - ldfmt = str('%-5s | %-'+str(rlen)+'s | %7s | %7s | %'+str(mlen)+'s | %8s | %8s | %8s | %-'+str(clen)+'s |%-12s ') - # Header - if ( i == 0 ): - if not nagiosmode: - print ldfmt % ("-- ID", "Type", "Size", "Strpsz", "Flags", "DskCache", "Status", "OS Path", "CacheCade", "InProgress" ) - if not nagiosmode: - print ldfmt % ( - arrayinfo[0], - arrayinfo[1], - arrayinfo[2], - arrayinfo[3], - arrayinfo[4], - arrayinfo[5], - arrayinfo[6], - arrayinfo[7], - arrayinfo[8], - arrayinfo[9]) - dbgprint('Array state : LD ' + arrayinfo[0] + ', status : ' + arrayinfo[6]) - if arrayinfo[6] not in [ 'Optimal', 'N/A' ]: - bad = True - nagiosbadarray += 1 - else: - nagiosgoodarray += 1 - arrayindex += 1 - i += 1 - controllerid += 1 - if not nagiosmode: - print '' + ldfmt = str("%-5s | %-" + str(rlen) + "s | %7s | %7s | %" + str(mlen) + "s | %8s | %8s | %8s | %-" + str(clen) + "s |%-12s ") + # Header + if i == 0: + if not nagiosmode: + print ldfmt % ("-- ID", "Type", "Size", "Strpsz", "Flags", "DskCache", "Status", "OS Path", "CacheCade", "InProgress") + if not nagiosmode: + print ldfmt % ( + arrayinfo[0], + arrayinfo[1], + arrayinfo[2], + arrayinfo[3], + arrayinfo[4], + arrayinfo[5], + arrayinfo[6], + arrayinfo[7], + arrayinfo[8], + arrayinfo[9], + ) + dbgprint("Array state : LD " + arrayinfo[0] + ", status : " + arrayinfo[6]) + if arrayinfo[6] not in ["Optimal", "N/A"]: + bad = True + nagiosbadarray += 1 + else: + nagiosgoodarray += 1 + arrayindex += 1 + i += 1 + controllerid += 1 + if not nagiosmode: + print "" controllerid = 0 while controllerid < controllernumber: - cmd = '%s -PDGetNum -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - totaldrivenumber += returnTotalDriveNumber(output) - controllerid += 1 + cmd = "%s -PDGetNum -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + totaldrivenumber += returnTotalDriveNumber(output) + controllerid += 1 if totaldrivenumber: - if not nagiosmode: - print '-- Disk information --' + if not nagiosmode: + print "-- Disk information --" - i = 0 - dlen = 0 ; mlen = 0 ; flen = 0 - controllerid = 0 - while controllerid < controllernumber: - arrayid = 0 - cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraynumber = returnArrayNumber(output) - #### BUG: -LdPdInfo shows all PD on the adapter, not just for the LD we wanted.. - #### while arrayid <= arraynumber: - cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraydisk = returnDiskInfo(output,controllerid) - for array in arraydisk: - diskname = str(controllerid) + array[8] + array[9] - dbgprint('Disk c'+diskname + ' status : ' + array[5]) - if re.match("|".join([ '^Online$', '^Online, Spun Up$', '^Rebuilding \(.*' ]), array[5]): - if ( AddDisk(NagiosGoodDisks, diskname) ): - nagiosgooddisk += 1 - else: - bad = True - if ( AddDisk(NagiosBadDisks, diskname) ): - nagiosbaddisk += 1 + i = 0 + dlen = 0 + mlen = 0 + flen = 0 + controllerid = 0 + while controllerid < controllernumber: + arrayid = 0 + cmd = "%s -LDInfo -lall -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraynumber = returnArrayNumber(output) + #### BUG: -LdPdInfo shows all PD on the adapter, not just for the LD we wanted.. + #### while arrayid <= arraynumber: + cmd = "%s -LdPdInfo -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraydisk = returnDiskInfo(output, controllerid) + for array in arraydisk: + diskname = str(controllerid) + array[8] + array[9] + dbgprint("Disk c" + diskname + " status : " + array[5]) + if re.match("|".join(["^Online$", "^Online, Spun Up$", "^Rebuilding \(.*"]), array[5]): + if AddDisk(NagiosGoodDisks, diskname): + nagiosgooddisk += 1 + else: + bad = True + if AddDisk(NagiosBadDisks, diskname): + nagiosbaddisk += 1 - if ( returnWdthFromArrayCol(arraydisk,0) > dlen): - dlen = returnWdthFromArrayCol(arraydisk,0) - if ( returnWdthFromArrayCol(arraydisk,3) > mlen): - mlen = returnWdthFromArrayCol(arraydisk,3) - if ( returnWdthFromArrayCol(arraydisk,5) > flen): - flen = returnWdthFromArrayCol(arraydisk,5) - controllerid += 1 + if returnWdthFromArrayCol(arraydisk, 0) > dlen: + dlen = returnWdthFromArrayCol(arraydisk, 0) + if returnWdthFromArrayCol(arraydisk, 3) > mlen: + mlen = returnWdthFromArrayCol(arraydisk, 3) + if returnWdthFromArrayCol(arraydisk, 5) > flen: + flen = returnWdthFromArrayCol(arraydisk, 5) + controllerid += 1 - controllerid = 0 - while controllerid < controllernumber: - arrayid = 0 + controllerid = 0 + while controllerid < controllernumber: + arrayid = 0 - cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraynumber = returnArrayNumber(output) - #### BUG: -LdPdInfo shows all PD on the adapter, not just for said LD.. - #### while arrayid <= arraynumber: + cmd = "%s -LDInfo -lall -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraynumber = returnArrayNumber(output) + #### BUG: -LdPdInfo shows all PD on the adapter, not just for said LD.. + #### while arrayid <= arraynumber: - cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraydisk = returnDiskInfo(output,controllerid) + cmd = "%s -LdPdInfo -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraydisk = returnDiskInfo(output, controllerid) - # Adjust print format with width computed above - drvfmt = "%-"+str(dlen+6)+"s | %-4s | %-"+str(mlen)+"s | %-8s | %-"+str(flen)+"s | %-8s | %-4s | %-8s | %-8s" - for array in arraydisk: - # Header - if ( i == 0 ): - if not nagiosmode: - print drvfmt % ( - "-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI ID") - # Drive information - if not nagiosmode: - print drvfmt % ( - str('c'+str(controllerid)+'u'+array[0]+'p'+array[1]), # c0p0 - array[2], # HDD/SDD - array[3], # Model Information (Variable len) - array[4], # Size - array[5], # Status (Variable len) - array[6], # Speed - array[7], # Temp - str('['+array[8]+':'+array[9]+']'), # Slot ID - array[10]) # LSI ID - i = i + 1 - controllerid += 1 - if not nagiosmode: - print '' + # Adjust print format with width computed above + drvfmt = "%-" + str(dlen + 6) + "s | %-4s | %-" + str(mlen) + "s | %-8s | %-" + str(flen) + "s | %-8s | %-4s | %-8s | %-8s" + for array in arraydisk: + # Header + if i == 0: + if not nagiosmode: + print drvfmt % ("-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI ID") + # Drive information + if not nagiosmode: + print drvfmt % ( + str("c" + str(controllerid) + "u" + array[0] + "p" + array[1]), # c0p0 + array[2], # HDD/SDD + array[3], # Model Information (Variable len) + array[4], # Size + array[5], # Status (Variable len) + array[6], # Speed + array[7], # Temp + str("[" + array[8] + ":" + array[9] + "]"), # Slot ID + array[10], + ) # LSI ID + i = i + 1 + controllerid += 1 + if not nagiosmode: + print "" controllerid = 0 totalconfdrivenumber = 0 totalunconfdrivenumber = 0 totaldrivenumber = 0 while controllerid < controllernumber: - cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - totalconfdrivenumber += returnConfDriveNumber(controllerid,output) + cmd = "%s -LdPdInfo -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + totalconfdrivenumber += returnConfDriveNumber(controllerid, output) - cmd = '%s -PDGetNum -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - totaldrivenumber += returnTotalDriveNumber(output) + cmd = "%s -PDGetNum -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + totaldrivenumber += returnTotalDriveNumber(output) - cmd = '%s -PDList -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - # Sometimes a drive will be reconfiguring without any info on that it is going through a rebuild process. - # This happens when expanding an R{5,6,50,60} array, for example. In that case, totaldrivenumber will still be - # greater than totalconfdrivenumber while returnUnConfDriveNumber(output) will be zero. The math below attempts to solve this. - totalunconfdrivenumber += max(returnUnConfDriveNumber(output), totaldrivenumber - totalconfdrivenumber) + cmd = "%s -PDList -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + # Sometimes a drive will be reconfiguring without any info on that it is going through a rebuild process. + # This happens when expanding an R{5,6,50,60} array, for example. In that case, totaldrivenumber will still be + # greater than totalconfdrivenumber while returnUnConfDriveNumber(output) will be zero. The math below attempts to solve this. + totalunconfdrivenumber += max(returnUnConfDriveNumber(output), totaldrivenumber - totalconfdrivenumber) - controllerid += 1 + controllerid += 1 -dbgprint('Total Drives in system : ' + str(totaldrivenumber)) -dbgprint('Total Configured Drives : ' + str(totalconfdrivenumber)) -dbgprint('Total Unconfigured Drives : ' + str(totalunconfdrivenumber)) +dbgprint("Total Drives in system : " + str(totaldrivenumber)) +dbgprint("Total Configured Drives : " + str(totalconfdrivenumber)) +dbgprint("Total Unconfigured Drives : " + str(totalunconfdrivenumber)) if totalunconfdrivenumber: - if not nagiosmode: - print '-- Unconfigured Disk information --' + if not nagiosmode: + print "-- Unconfigured Disk information --" - controllerid = 0 - pcipath = '' - while controllerid < controllernumber: - arrayid = 0 + controllerid = 0 + pcipath = "" + while controllerid < controllernumber: + arrayid = 0 - cmd = '%s -LDInfo -lall -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraynumber = returnArrayNumber(output) - cmd = '%s -AdpGetPciInfo -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - pcipath = returnHBAPCIInfo(output) - #### BUG: -LdPdInfo shows all PD on the adapter, not just for given LD.. - #### while arrayid <= arraynumber: + cmd = "%s -LDInfo -lall -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraynumber = returnArrayNumber(output) + cmd = "%s -AdpGetPciInfo -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + pcipath = returnHBAPCIInfo(output) + #### BUG: -LdPdInfo shows all PD on the adapter, not just for given LD.. + #### while arrayid <= arraynumber: - cmd = '%s -PDList -a%d -NoLog' % (megaclipath, controllerid) - output = getOutput(cmd) - arraydisk = returnUnconfDiskInfo(output,controllerid) - for array in arraydisk: - dbgprint('Unconfed '+str(nagiosgooddisk)+'/'+str(nagiosbaddisk)+' Disk c'+str(controllerid)+'uXpY status : ' + array[3]) - if array[3] in [ 'Online', 'Unconfigured(good), Spun Up', 'Unconfigured(good), Spun down', 'JBOD','Hotspare, Spun Up','Hotspare, Spun down','Online, Spun Up' ]: - nagiosgooddisk += 1 - else: - bad = True - nagiosbaddisk += 1 + cmd = "%s -PDList -a%d -NoLog" % (megaclipath, controllerid) + output = getOutput(cmd) + arraydisk = returnUnconfDiskInfo(output, controllerid) + for array in arraydisk: + dbgprint("Unconfed " + str(nagiosgooddisk) + "/" + str(nagiosbaddisk) + " Disk c" + str(controllerid) + "uXpY status : " + array[3]) + if array[3] in [ + "Online", + "Unconfigured(good), Spun Up", + "Unconfigured(good), Spun down", + "JBOD", + "Hotspare, Spun Up", + "Hotspare, Spun down", + "Online, Spun Up", + ]: + nagiosgooddisk += 1 + else: + bad = True + nagiosbaddisk += 1 - # JBOD disks has a real device path and are not masked. Try to find a device name here, if possible. - if pcipath: - if array[3] in [ 'JBOD' ]: - diskprefix = str('/dev/disk/by-path/pci-' + pcipath + '-scsi-0:0:') - dbgprint('Will look for DISKprefix : ' + diskprefix) - # RAID disks are usually with a channel of '2', JBOD disks with a channel of '0' - diskpath = diskprefix + str(array[8]) + ':0' - dbgprint('Looking for DISKpath : ' + diskpath) - if os.path.exists(diskpath): - dbgprint('Found DISK match: ' + diskpath + ' -> ' + array[9]) - array[9] = os.path.realpath(diskpath) - else: - dbgprint('DISK NOT present: ' + diskpath) - array[9] = 'N/A' + # JBOD disks has a real device path and are not masked. Try to find a device name here, if possible. + if pcipath: + if array[3] in ["JBOD"]: + diskprefix = str("/dev/disk/by-path/pci-" + pcipath + "-scsi-0:0:") + dbgprint("Will look for DISKprefix : " + diskprefix) + # RAID disks are usually with a channel of '2', JBOD disks with a channel of '0' + diskpath = diskprefix + str(array[8]) + ":0" + dbgprint("Looking for DISKpath : " + diskpath) + if os.path.exists(diskpath): + dbgprint("Found DISK match: " + diskpath + " -> " + array[9]) + array[9] = os.path.realpath(diskpath) + else: + dbgprint("DISK NOT present: " + diskpath) + array[9] = "N/A" - mlen = returnWdthFromArrayCol(arraydisk,1) - flen = returnWdthFromArrayCol(arraydisk,3) + mlen = returnWdthFromArrayCol(arraydisk, 1) + flen = returnWdthFromArrayCol(arraydisk, 3) - # Adjust print format with widths computed above - drvfmt = "%-7s | %-4s | %-"+str(mlen)+"s | %-8s | %-"+str(flen+2)+"s | %-8s | %-4s | %-8s | %-6s | %-8s" - i = 0 - for array in arraydisk: - # Header - if ( i == 0 ): - if not nagiosmode: - print drvfmt % ( - "-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI ID", "Path") - # Drive information - if not nagiosmode: - print drvfmt % ( - str('c'+str(controllerid)+'uXpY'), # cXpY - array[0], # HDD/SDD - array[1], # Model Information (Variable len) - array[2], # Size - array[3], # Status (Variable len) - array[4], # Speed - array[5], # Temp - str('['+array[6]+':'+array[7]+']'), # Slot ID - array[8], # LSI ID - array[9]) # OS path, if any - i += 1 - controllerid += 1 - if not nagiosmode: - print '' + # Adjust print format with widths computed above + drvfmt = "%-7s | %-4s | %-" + str(mlen) + "s | %-8s | %-" + str(flen + 2) + "s | %-8s | %-4s | %-8s | %-6s | %-8s" + i = 0 + for array in arraydisk: + # Header + if i == 0: + if not nagiosmode: + print drvfmt % ("-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI ID", "Path") + # Drive information + if not nagiosmode: + print drvfmt % ( + str("c" + str(controllerid) + "uXpY"), # cXpY + array[0], # HDD/SDD + array[1], # Model Information (Variable len) + array[2], # Size + array[3], # Status (Variable len) + array[4], # Speed + array[5], # Temp + str("[" + array[6] + ":" + array[7] + "]"), # Slot ID + array[8], # LSI ID + array[9], + ) # OS path, if any + i += 1 + controllerid += 1 + if not nagiosmode: + print "" -if (debugmode): - dbgprint ('Printing Outputs[][]') - for myl in Outputs: - dbgprint(myl+'\n') - sys.stderr.write("\n".join("".join(map(str,myd)) for myd in Outputs[myl])+'\n') - dbgprint ('Printing arraydisk[]') - sys.stderr.write("\n".join(" | ".join(map(str,myd)) for myd in arraydisk)+'\n') - dbgprint ('Printing ConfDisks[]') - sys.stderr.write("\n".join("".join(map(str,myd)) for myd in ConfDisks)+'\n') - dbgprint ('Printing NagiosGoodDisks[]') - sys.stderr.write("\n".join("".join(map(str,myd)) for myd in NagiosGoodDisks)+'\n') - dbgprint ('Printing NagiosBadDisks[]') - sys.stderr.write("\n".join("".join(map(str,myd)) for myd in NagiosBadDisks)+'\n') +if debugmode: + dbgprint("Printing Outputs[][]") + for myl in Outputs: + dbgprint(myl + "\n") + sys.stderr.write("\n".join("".join(map(str, myd)) for myd in Outputs[myl]) + "\n") + dbgprint("Printing arraydisk[]") + sys.stderr.write("\n".join(" | ".join(map(str, myd)) for myd in arraydisk) + "\n") + dbgprint("Printing ConfDisks[]") + sys.stderr.write("\n".join("".join(map(str, myd)) for myd in ConfDisks) + "\n") + dbgprint("Printing NagiosGoodDisks[]") + sys.stderr.write("\n".join("".join(map(str, myd)) for myd in NagiosGoodDisks) + "\n") + dbgprint("Printing NagiosBadDisks[]") + sys.stderr.write("\n".join("".join(map(str, myd)) for myd in NagiosBadDisks) + "\n") 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) + 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: - # DO NOT MODIFY OUTPUT BELOW - # Scripts may relies on it - # https://github.com/eLvErDe/hwraid/issues/99 - print '\nThere is at least one disk/array in a NOT OPTIMAL state.' - print 'RAID ERROR - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk) - sys.exit(1) + if bad: + # DO NOT MODIFY OUTPUT BELOW + # Scripts may relies on it + # https://github.com/eLvErDe/hwraid/issues/99 + print "\nThere is at least one disk/array in a NOT OPTIMAL state." + print "RAID ERROR - Arrays: OK:" + str(nagiosgoodarray) + " Bad:" + str(nagiosbadarray) + " - Disks: OK:" + str(nagiosgooddisk) + " Bad:" + str( + nagiosbaddisk + ) + sys.exit(1) diff --git a/wrapper-scripts/megaide-status b/wrapper-scripts/megaide-status index 5e33c6a..85879c2 100755 --- a/wrapper-scripts/megaide-status +++ b/wrapper-scripts/megaide-status @@ -5,46 +5,50 @@ import re import sys if len(sys.argv) > 2: - print 'Usage: megaide-status [-d]' + print "Usage: megaide-status [-d]" sys.exit(1) printarray = True printcontroller = True if len(sys.argv) > 1: - if sys.argv[1] == '-d': + if sys.argv[1] == "-d": printarray = False printcontroller = False else: - print 'Usage: megaide-status [-d]' + print "Usage: megaide-status [-d]" sys.exit(1) + def returnControllerNumber(): - for dir in os.listdir('/proc/megaide/'): + 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 + # 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_')) + 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') + +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() + 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] + return [id, type, size, state] + def returnDiskInfo(): # Megaide module report all available port, even there's no disk on it @@ -55,60 +59,61 @@ def returnDiskInfo(): # c0u0d0 # c0u0d2 # If logical drive 0 uses disk 0 and disk 2 (chan0 disk0, chan1 disk 0) - f = open('/etc/megaide-status.conf') + 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()): + 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') + 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() + 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' + print "-- Arrays informations --" + print "-- ID | Type | Size | Status" while controllerid <= controllernumber: arrayid = 0 - arraynumber = returnArrayNumber(controllerid) + 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 + 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 "" -print '-- Disks informations' -print '-- ID | Model | Status' +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 + 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.' + print "\nThere is at least one disk/array in a NOT OPTIMAL state." sys.exit(1) diff --git a/wrapper-scripts/megaraid-status b/wrapper-scripts/megaraid-status index a7e4d15..aaf5d15 100644 --- a/wrapper-scripts/megaraid-status +++ b/wrapper-scripts/megaraid-status @@ -7,99 +7,102 @@ import sys binarypath = "/usr/sbin/megactl" if len(sys.argv) > 2: - print 'Usage: megaraid-status [-d]' + print "Usage: megaraid-status [-d]" sys.exit(1) printarray = True if len(sys.argv) > 1: - if sys.argv[1] == '-d': + if sys.argv[1] == "-d": printarray = False else: - print 'Usage: megaraid-status [-d]' + print "Usage: megaraid-status [-d]" sys.exit(1) # Check binary exists (and +x), if not print an error message if os.path.exists(binarypath) and os.access(binarypath, os.X_OK): - pass + pass else: - sys.exit(3) + 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()): + if not re.match(r"^$", line.strip()): lines.append(line.strip()) return lines - + + def returnDiskList(output): lines = [] for line in output: - if re.match(r'^[a-z][0-9]+[a-z][0-9\*]+[a-z][0-9]+\s.*$',line.strip()): + if re.match(r"^[a-z][0-9]+[a-z][0-9\*]+[a-z][0-9]+\s.*$", line.strip()): list = line.split() # Let's hack... Some disk may report smart error after status # Get theses errors, join them into one list item and place it # before status errindex = False try: - errindex = list.index('errs:') + errindex = list.index("errs:") except ValueError: pass if errindex: - list.insert(errindex-1, ' '.join(list[errindex:])) - list = list[:errindex+1] + list.insert(errindex - 1, " ".join(list[errindex:])) + list = list[: errindex + 1] lines.append(list) if fake_failure: - lines[0][-1] = 'BAD' + lines[0][-1] = "BAD" return lines + def returnArrayList(output): lines = [] for line in output: - if re.match(r'^[a-z][0-9]+[a-z][0-9]+\s.*$',line.strip()): + if re.match(r"^[a-z][0-9]+[a-z][0-9]+\s.*$", line.strip()): lines.append(line.split()) if fake_failure: - lines[0][-1] = 'DEGRADED' + lines[0][-1] = "DEGRADED" return lines + # A way to force a fake failure fake_failure = False -if os.path.exists('/root/fake_megaraid_failure'): +if os.path.exists("/root/fake_megaraid_failure"): fake_failure = True -cmd = binarypath+' -v' +cmd = binarypath + " -v" output = getOutput(cmd) disklist = returnDiskList(output) arraylist = returnArrayList(output) if printarray: - print '-- Arrays informations --' - print '-- ID | Type | Size | Status' + print "-- Arrays informations --" + print "-- ID | Type | Size | Status" for array in arraylist: - print array[0]+' | '+array[2]+' '+array[3]+' | '+array[1]+' | '+array[-1] - print '' + print array[0] + " | " + array[2] + " " + array[3] + " | " + array[1] + " | " + array[-1] + print "" -print '-- Disks informations' -print '-- ID | Model | Status | Warnings' +print "-- Disks informations" +print "-- ID | Model | Status | Warnings" for disk in disklist: # Check if there's some smart non critical warnings - if re.match(r'^errs:.*$', disk[-2]): + if re.match(r"^errs:.*$", disk[-2]): # Some disk may have vendor or model containing spaces - print disk[0]+' | '+' '.join(disk[1:-3])+' | '+disk[-1]+' | '+disk[-2] + print disk[0] + " | " + " ".join(disk[1:-3]) + " | " + disk[-1] + " | " + disk[-2] else: - print disk[0]+' | '+' '.join(disk[1:-2])+' | '+disk[-1] + print disk[0] + " | " + " ".join(disk[1:-2]) + " | " + disk[-1] # Check if there's a bad disk bad = False for array in arraylist: - if not array[-1] == 'optimal': + if not array[-1] == "optimal": bad = True for disk in disklist: - if disk[-1] not in [ 'online', 'hotspare', 'ready' ]: + if disk[-1] not in ["online", "hotspare", "ready"]: bad = True if bad: - print '\nThere is at least one disk/array in a NOT OPTIMAL state.' + print "\nThere is at least one disk/array in a NOT OPTIMAL state." sys.exit(1) diff --git a/wrapper-scripts/megaraidsas-status b/wrapper-scripts/megaraidsas-status index f5b21e0..95a3e84 100644 --- a/wrapper-scripts/megaraidsas-status +++ b/wrapper-scripts/megaraidsas-status @@ -7,99 +7,102 @@ import sys binarypath = "/usr/sbin/megasasctl" if len(sys.argv) > 2: - print 'Usage: megaraidsas-status [-d]' + print "Usage: megaraidsas-status [-d]" sys.exit(1) printarray = True if len(sys.argv) > 1: - if sys.argv[1] == '-d': + if sys.argv[1] == "-d": printarray = False else: - print 'Usage: megaraidsas-status [-d]' + print "Usage: megaraidsas-status [-d]" sys.exit(1) # Check binary exists (and +x), if not print an error message if os.path.exists(binarypath) and os.access(binarypath, os.X_OK): - pass + pass else: - sys.exit(3) + 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()): + if not re.match(r"^$", line.strip()): lines.append(line.strip()) return lines - + + def returnDiskList(output): lines = [] for line in output: - if re.match(r'^[a-z][0-9]+[a-z][0-9\*]+[a-z][0-9]+\s.*$',line.strip()): + if re.match(r"^[a-z][0-9]+[a-z][0-9\*]+[a-z][0-9]+\s.*$", line.strip()): list = line.split() # Let's hack... Some disk may report smart error after status # Get theses errors, join them into one list item and place it # before status errindex = False try: - errindex = list.index('errs:') + errindex = list.index("errs:") except ValueError: pass if errindex: - list.insert(errindex-1, ' '.join(list[errindex:])) - list = list[:errindex+1] + list.insert(errindex - 1, " ".join(list[errindex:])) + list = list[: errindex + 1] lines.append(list) if fake_failure: - lines[0][-1] = 'BAD' + lines[0][-1] = "BAD" return lines + def returnArrayList(output): lines = [] for line in output: - if re.match(r'^[a-z][0-9]+[a-z][0-9]+\s.*$',line.strip()): + if re.match(r"^[a-z][0-9]+[a-z][0-9]+\s.*$", line.strip()): lines.append(line.split()) if fake_failure: - lines[0][-1] = 'DEGRADED' + lines[0][-1] = "DEGRADED" return lines + # A way to force a fake failure fake_failure = False -if os.path.exists('/root/fake_megaraid_failure'): +if os.path.exists("/root/fake_megaraid_failure"): fake_failure = True -cmd = binarypath+' -v' +cmd = binarypath + " -v" output = getOutput(cmd) disklist = returnDiskList(output) arraylist = returnArrayList(output) if printarray: - print '-- Arrays informations --' - print '-- ID | Type | Size | Status' + print "-- Arrays informations --" + print "-- ID | Type | Size | Status" for array in arraylist: - print array[0]+' | '+array[2]+' '+array[3]+' | '+array[1]+' | '+array[-1] - print '' + print array[0] + " | " + array[2] + " " + array[3] + " | " + array[1] + " | " + array[-1] + print "" -print '-- Disks informations' -print '-- ID | Model | Status | Warnings' +print "-- Disks informations" +print "-- ID | Model | Status | Warnings" for disk in disklist: # Check if there's some smart non critical warnings - if re.match(r'^errs:.*$', disk[-2]): + if re.match(r"^errs:.*$", disk[-2]): # Some disk may have vendor or model containing spaces - print disk[0]+' | '+' '.join(disk[1:-3])+' | '+disk[-1]+' | '+disk[-2] + print disk[0] + " | " + " ".join(disk[1:-3]) + " | " + disk[-1] + " | " + disk[-2] else: - print disk[0]+' | '+' '.join(disk[1:-2])+' | '+disk[-1] + print disk[0] + " | " + " ".join(disk[1:-2]) + " | " + disk[-1] # Check if there's a bad disk bad = False for array in arraylist: - if not array[-1] == 'optimal': + if not array[-1] == "optimal": bad = True for disk in disklist: - if disk[-1] not in [ 'online', 'hotspare', 'ready' ]: + if disk[-1] not in ["online", "hotspare", "ready"]: bad = True if bad: - print '\nThere is at least one disk/array in a NOT OPTIMAL state.' + print "\nThere is at least one disk/array in a NOT OPTIMAL state." sys.exit(1) diff --git a/wrapper-scripts/sas2ircu-status b/wrapper-scripts/sas2ircu-status index 295b901..7b7c0cf 100755 --- a/wrapper-scripts/sas2ircu-status +++ b/wrapper-scripts/sas2ircu-status @@ -6,174 +6,186 @@ import sys binarypath = "/usr/sbin/sas2ircu" if not os.path.isfile(binarypath): - print 'sas2ircu is not available in expected location: {}'.format(binarypath) - sys.exit(1) - -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]' + print "sas2ircu is not available in expected location: {}".format(binarypath) sys.exit(1) -bad=False +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 + 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 and a volume exists - cmd=binarypath+' '+str(ctrlnmbr)+' DISPLAY' - res=getOutput(cmd) - raid=False - validarray=False - for line in res: - if re.match('^RAID Support\s+:\s+Yes$',line): - raid=True - if re.match('^IR volume [0-9]+.*$',line): - validarray=True - if raid and validarray: - list.append([ctrlnmbr,ctrlname]) - # ie: [['0', 'SAS2008']] - return list + 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 and a volume exists + cmd = binarypath + " " + str(ctrlnmbr) + " DISPLAY" + res = getOutput(cmd) + raid = False + validarray = False + for line in res: + if re.match("^RAID Support\s+:\s+Yes$", line): + raid = True + if re.match("^IR volume [0-9]+.*$", line): + validarray = True + if raid and validarray: + 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 - disklist=[] - 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 + 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 + disklist = [] + 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) or re.match('^Device is a unknown 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 + 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) + or re.match("^Device is a unknown 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 -ctrls=getCtrlList() -arraymap={} + +ctrls = getCtrlList() +arraymap = {} if not nagiosmode: - print '-- Controller informations --' - print '-- ID | Model' - for ctrl in ctrls: - print 'c'+str(ctrl[0])+' | '+ctrl[1] - print '' + print "-- Controller informations --" + print "-- ID | Model" + for ctrl in ctrls: + print "c" + str(ctrl[0]) + " | " + ctrl[1] + print "" if not nagiosmode: - print '-- Arrays informations --' - print '-- ID | Type | Size | Status' + print "-- Arrays informations --" + print "-- ID | Type | Size | Status" for ctrl in ctrls: - for array in getArrayList(ctrl[0]): - arraymap[ctrl[0]]=array - 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] + for array in getArrayList(ctrl[0]): + arraymap[ctrl[0]] = array + 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 '' + print "" if not nagiosmode: - print '-- Disks informations' - print '-- ID | Model | Status' + print "-- Disks informations" + print "-- ID | Model | Status" for ctrl in ctrls: - for disk in getDiskList(ctrl[0]): - # Compare disk enc/slot to array's ones - for array in [arraymap.get(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] + for disk in getDiskList(ctrl[0]): + # Compare disk enc/slot to array's ones + for array in [arraymap.get(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) + 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) + if bad: + print "\nThere is at least one disk/array in a NOT OPTIMAL state." + sys.exit(1)