Created
August 22, 2018 14:32
-
-
Save jrelo/4acaaa1a2bf10e5792e15455f25c49f6 to your computer and use it in GitHub Desktop.
megaraid_status.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# $Id: megaclisas-status,v 1.52 2015/04/18 02:49:07 root Exp root $ | |
# | |
# Written by Adam Cecile <gandalf@NOSPAM.le-vert.net> | |
# Modified vy Vincent S. Cojot <vincent@NOSPAM.cojot.name> | |
# | |
import os | |
import re | |
import sys | |
import pdb | |
def_megaclipath = "/opt/MegaRAID/MegaCli/MegaCli64" | |
# Non-Nagios Mode defaults | |
nagiosmode = False | |
nagiosoutput='' | |
nagiosgoodarray = 0 | |
nagiosbadarray = 0 | |
nagiosgooddisk = 0 | |
nagiosbaddisk = 0 | |
# Sane defaults | |
printarray = True | |
printcontroller = True | |
debugmode = False | |
totaldrivenumber = 0 | |
totalunconfdrivenumber = 0 | |
# Hardcode a max of 16 HBA for now. LDTable must be initiazlied to accept populating list of LD's into each ctlr's list. | |
LDTable = [ [] * 16 for i in range(16) ] | |
# Outputs is a 'dict' of all MegaCLI outputs so we can re-use them during loops.. | |
Outputs = {} | |
# Startup | |
def print_usage(): | |
print 'Usage: megaraid-status [--nagios|--debug]' | |
# We need root access to query | |
if __name__ == '__main__': | |
if os.getenv('USER') != 'root': | |
print '# This script requires Administrator privs! e.g :\r' | |
print 'sudo '+str(sys.argv[0])+'\r' | |
sys.exit(5) | |
# Check command line arguments to enable nagios or not | |
if len(sys.argv) > 2: | |
print_usage() | |
sys.exit(1) | |
if len(sys.argv) > 1: | |
if sys.argv[1] == '--nagios': | |
nagiosmode = True | |
elif sys.argv[1] == '--debug': | |
debugmode = True | |
else: | |
print_usage() | |
sys.exit(1) | |
# Functions | |
def dbgprint(msg): | |
if (debugmode): | |
sys.stderr.write ( str('# DEBUG : '+msg+'\n')) | |
def is_exe(fpath): | |
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 + 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 | |
megaclipath = which("megacli") | |
if (megaclipath == None): | |
megaclipath = which("megacli") | |
if (megaclipath == None): | |
megaclipath = "megacli" | |
# Check binary exists (and +x), if not print an error message | |
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) | |
#### pdb.set_trace() | |
def returnWdthFromArrayCol(glarray,idx): | |
maxwdth = 0 | |
for glrow in glarray: | |
if ( len(glrow[idx]) > maxwdth): | |
maxwdth = len(glrow[idx]) | |
return maxwdth | |
# Get 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 | |
def returnControllerNumber(output): | |
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()) | |
def returnUnconfDriveNumber(output): | |
confdrives = 0 | |
unconfdrives = 0 | |
for line in output: | |
if re.match(r'.*Number of PDs:.*$',line.strip()): | |
confdrives += int(line.split(':')[2].strip()) | |
unconfdrives = totaldrivenumber - confdrives | |
return int(unconfdrives) | |
def returnControllerModel(output): | |
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() | |
def returnFirmwareVersion(output): | |
for line in output: | |
if re.match(r'^FW Package Build.*$',line.strip()): | |
return line.split(':')[1].strip() | |
def returnROCTemp(output): | |
ROCtemp = '' | |
tmpstr = '' | |
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 returnArrayNumber(output): | |
i = 0 | |
for line in output: | |
if re.match(r'^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) | |
if controllermodel != 'Unknown': | |
table.append([ 'c'+str(controllerid), controllermodel, controllerram, str(controllertemp), str('FW: '+controllerrev) ]) | |
def returnArrayInfo(output,controllerid,arrayid): | |
id = 'c'+str(controllerid)+'u'+str(arrayid) | |
operationlinennumber = False | |
linenumber = 0 | |
targetid = '' | |
raidtype = '' | |
raidlvl = '' | |
size = '' | |
state = '' | |
strpsz = '' | |
dskcache = 'N/A' | |
properties = '' | |
spandepth = 0 | |
diskperspan = 0 | |
for line in output: | |
if re.match(r'^Virtual Drive:.*(Target Id: [0-9]+).*$',line.strip()): | |
# Extract the SCSI Target ID | |
targetid = line.strip().split(':')[2].split(')')[0].strip() | |
if 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()) | |
if 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' | |
if 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() | |
if re.match(r'^State.*?:.*$',line.strip()): | |
state = line.strip().split(':')[1].strip() | |
if re.match(r'^Strip Size.*?:.*$',line.strip()): | |
strpsz = line.strip().split(':')[1].strip() | |
if re.match(r'^Number Of Drives.*:.*$',line.strip()): | |
diskperspan = int(line.strip().split(':')[1].strip()) | |
if 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' | |
if 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' | |
if re.match(r'^Ongoing Progresses.*?:.*$',line.strip()): | |
operationlinennumber = linenumber | |
linenumber += 1 | |
if operationlinennumber: | |
inprogress = output[operationlinennumber+1] | |
else: | |
inprogress = 'None' | |
# Compute the RAID level | |
if (int(spandepth) >= 2): | |
raidtype = str('RAID-' + str(raidlvl) + '0') | |
else: | |
if(raidlvl == 1): | |
if(diskperspan > 2): | |
raidtype = str('RAID-10') | |
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,inprogress] | |
def returnDiskInfo(output,controllerid): | |
arrayid = False | |
diskid = False | |
oldenclid = False | |
enclid = False | |
slotid = False | |
lsidid = 'Unknown' | |
table = [] | |
fstate = 'Offline' | |
model = 'Unknown' | |
speed = 'Unknown' | |
dsize = 'Unknown' | |
temp = 'Unk0C' | |
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() | |
if oldenclid != False: | |
fstate = 'Offline' | |
model = 'Unknown' | |
speed = 'Unknown' | |
temp = 'Unk0C' | |
slotid = False | |
lsidid = 'Unknown' | |
if 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) | |
if re.match(r'^Virtual Drive: [0-9]+.*$',line.strip()): | |
arrayid = line.split('(')[0].split(':')[1].strip() | |
if re.match(r'PD: [0-9]+ Information.*$',line.strip()): | |
diskid = line.split()[1].strip() | |
if re.match(r'^Device Id: .*$',line.strip()): | |
lsidid = line.split(':')[1].strip() | |
if re.match(r'Slot Number: .*$',line.strip()): | |
slotid = line.split(':')[1].strip() | |
if re.match(r'Firmware state: .*$',line.strip()): | |
fstate = line.split(':')[1].strip() | |
if re.match(r'Inquiry Data: .*$',line.strip()): | |
model = line.split(':')[1].strip() | |
model = re.sub(' +', ' ', model) | |
# Sub code | |
manuf = re.sub(' .*', '', model) | |
dtype = re.sub(manuf+' ', '', model) | |
dtype = re.sub(' .*', '', dtype) | |
hwserial = re.sub('.*'+dtype+' *', '', model) | |
if 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' | |
if re.match(r'Device Speed: .*$',line.strip()): | |
speed = line.split(':')[1].strip() | |
if 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.. | |
temp = line.split(':')[1].strip() | |
temp = re.sub(' \(.*\)', '', temp) | |
if model != 'Unknown': | |
#### print str(arrayid)+' '+str(diskid)+' '+str(olddiskid) | |
table.append([str(arrayid), 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' | |
model = 'Unknown' | |
speed = 'Unknown' | |
mtype = 'Unknown' | |
dsize = 'Unknown' | |
temp = 'Unk0C' | |
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() | |
if oldenclid != False: | |
arrayid = False | |
fstate = 'Offline' | |
model = 'Unknown' | |
speed = 'Unknown' | |
temp = 'Unk0C' | |
slotid = False | |
lsidid = 'Unknown' | |
if 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) | |
if re.match(r'^Drive.s position: DiskGroup: [0-9]+,.*$',line.strip()): | |
arrayid = line.split(',')[1].split(':')[1].strip() | |
if re.match(r'^Device Id: [0-9]+.*$',line.strip()): | |
diskid = line.split(':')[1].strip() | |
if re.match(r'^Device Id: .*$',line.strip()): | |
lsidid = line.split(':')[1].strip() | |
if re.match(r'Slot Number: .*$',line.strip()): | |
slotid = line.split(':')[1].strip() | |
if re.match(r'Firmware state: .*$',line.strip()): | |
fstate = line.split(':')[1].strip() | |
subfstate = re.sub('\(.*', '', fstate) | |
if re.match(r'Inquiry Data: .*$',line.strip()): | |
model = line.split(':')[1].strip() | |
model = re.sub(' +', ' ', model) | |
manuf = re.sub(' .*', '', model) | |
dtype = re.sub(manuf+' ', '', model) | |
dtype = re.sub(' .*', '', dtype) | |
hwserial = re.sub('.*'+dtype+' *', '', model) | |
if 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' | |
if re.match(r'Device Speed: .*$',line.strip()): | |
speed = line.split(':')[1].strip() | |
if re.match(r'Drive Temperature :.*$',line.strip()): | |
temp = line.split(':')[1].strip() | |
temp = re.sub('\(.*\)', '', temp) | |
# Drive temp is amongst the last few lines matched, decide here if we add information to the table.. | |
if arrayid == False: | |
if subfstate == 'Unconfigured': | |
dbgprint('Unconfigured Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate)) | |
if subfstate == 'Online, Spun Up': | |
dbgprint('Online Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate)) | |
table.append([ mtype, model, dsize, fstate, speed, temp, enclid, slotid, lsidid]) | |
return table | |
cmd = '%s -adpCount -NoLog' % (megaclipath) | |
output = getOutput(cmd) | |
controllernumber = returnControllerNumber(output) | |
bad = False | |
# List available controller | |
if printcontroller: | |
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) | |
controllerid = 0 | |
for hba in hbainfo: | |
hbafmt = str('%-5s | %-'+str(mlen)+'s | %-6s | %-4s | %-12s ') | |
# Header | |
if ( i == 0 ): | |
if not nagiosmode: | |
print hbafmt % ("-- ID","H/W Model","RAM","Temp","Firmware") | |
if not nagiosmode: | |
print hbafmt % ( | |
hba[0], | |
hba[1], | |
hba[2], | |
hba[3], | |
hba[4]) | |
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 --' | |
controllerid = 0 | |
pcipath = '' | |
diskpath = '' | |
i = 0 ; j = 0 | |
mlen = 0 | |
rlen = 0 | |
while controllerid < controllernumber: | |
arrayid = 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 | |
if re.match(r'^Virtual Drive:',line.strip()): | |
LDTable[controllerid].append ( ldid ) | |
ldcount += 1 | |
ldid += 1 | |
while arrayid < arraynumber: | |
ldid = LDTable[controllerid][arrayid] | |
cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid) | |
output = getOutput(cmd) | |
arrayinfo = returnArrayInfo(output, controllerid, ldid) | |
if ( len(arrayinfo[4]) > mlen): | |
mlen = len(arrayinfo[4]) | |
if ( len(arrayinfo[1]) > rlen): | |
rlen = len(arrayinfo[1]) | |
arrayid += 1 | |
controllerid += 1 | |
controllerid = 0 | |
while controllerid < controllernumber: | |
arrayid = 0 | |
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 arrayid < arraynumber: | |
ldid = LDTable[controllerid][arrayid] | |
cmd = '%s -LDInfo -l%d -a%d -NoLog' % (megaclipath, ldid, controllerid) | |
output = getOutput(cmd) | |
arrayinfo = returnArrayInfo(output,controllerid, ldid) | |
if pcipath: | |
diskprefix = str('/dev/disk/by-path/pci-' + pcipath + '-scsi-0:') | |
for j in range (8): | |
diskpath = diskprefix + str(j) + ':' + str(arrayinfo[7]) + ':0' | |
if os.path.exists(diskpath): | |
arrayinfo[7] = os.path.realpath(diskpath) | |
else: | |
arrayinfo[7] = 'N/A' | |
ldfmt = str('%-5s | %-'+str(rlen)+'s | %7s | %7s | %'+str(mlen)+'s | %8s | %8s | %8s | %-12s ') | |
# Header | |
if ( i == 0 ): | |
if not nagiosmode: | |
print ldfmt % ("-- ID", "Type", "Size", "Strpsz", "Flags", "DskCache", "Status", "OS Path", "InProgress" ) | |
if not nagiosmode: | |
print ldfmt % ( | |
arrayinfo[0], | |
arrayinfo[1], | |
arrayinfo[2], | |
arrayinfo[3], | |
arrayinfo[4], | |
arrayinfo[5], | |
arrayinfo[6], | |
arrayinfo[7], | |
arrayinfo[8]) | |
dbgprint("Array state : "+arrayinfo[6]) | |
if not arrayinfo[6] == 'Optimal': | |
bad = True | |
nagiosbadarray=nagiosbadarray+1 | |
else: | |
nagiosgoodarray=nagiosgoodarray+1 | |
arrayid += 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 | |
if totaldrivenumber: | |
if not nagiosmode: | |
print '-- Disk information --' | |
i = 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 said LD.. | |
#### while arrayid <= arraynumber: | |
cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid) | |
output = getOutput(cmd) | |
arraydisk = returnDiskInfo(output,controllerid) | |
for array in arraydisk: | |
dbgprint('Disk c'+str(controllerid)+'u'+array[0]+'p'+array[1] + ' status : ' + array[5]) | |
if not array[5] == 'Online' and not array[5] == 'Online, Spun Up': | |
bad = True | |
nagiosbaddisk=nagiosbaddisk+1 | |
else: | |
nagiosgooddisk=nagiosgooddisk+1 | |
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 | |
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) | |
# Adjust print format with width computed above | |
drvfmt = "%-7s | %-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", "Device 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 | |
while controllerid < controllernumber: | |
cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid) | |
output = getOutput(cmd) | |
totalunconfdrivenumber += returnUnconfDriveNumber(output) | |
controllerid += 1 | |
if totalunconfdrivenumber: | |
if not nagiosmode: | |
print '-- Unconfigured Disk information --' | |
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 -PDList -a%d -NoLog' % (megaclipath, controllerid) | |
output = getOutput(cmd) | |
arraydisk = returnUnconfDiskInfo(output,controllerid) | |
for array in arraydisk: | |
dbgprint('Disk c'+str(controllerid)+'uXpY status : ' + array[3]) | |
if not array[3] == 'Online' and not array[3] == 'Unconfigured(good), Spun Up': | |
bad = True | |
nagiosbaddisk=nagiosbaddisk+1 | |
else: | |
nagiosgooddisk=nagiosgooddisk+1 | |
mlen = returnWdthFromArrayCol(arraydisk,1) | |
flen = returnWdthFromArrayCol(arraydisk,3) | |
# Adjust print format with widths computed above | |
drvfmt = "%-7s | %-4s | %-"+str(mlen)+"s | %-8s | %-"+str(flen)+"s | %-8s | %-4s | %-8s | %-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 Device ID") | |
# 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 | |
i = i + 1 | |
controllerid += 1 | |
if not nagiosmode: | |
print '' | |
if nagiosmode: | |
if bad: | |
print 'RAID ERROR - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk) | |
sys.exit(2) | |
else: | |
print 'RAID OK - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk) | |
else: | |
if bad: | |
print '\nThere is at least one disk/array in a NOT OPTIMAL state.' | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I realized this was merged upstream
https://raw.githubusercontent.com/eLvErDe/hwraid/master/wrapper-scripts/megaclisas-status