Mini Shell
Direktori : /opt/sharedrads/ |
|
Current File : //opt/sharedrads/megaclisas-status |
#!/opt/imh-python/bin/python3
# $Id: megaclisas-status,v 1.68 2016/10/21 14:38:56 root Exp root $
#
# Written by Adam Cecile <gandalf@NOSPAM.le-vert.net>
# Modified by Vincent S. Cojot <vincent@NOSPAM.cojot.name>
#
import os
import re
import sys
if sys.platform == 'win32':
import ctypes
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
notempmode = False
totaldrivenumber = 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 = 64
MaxNumLD = 128
LDTable = [[] * MaxNumHBA for i in range(MaxNumLD)]
NestedLDTable = [[False for i in range(MaxNumHBA)] for j in range(MaxNumLD)]
# 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|--notemp]')
# We need root access to query
if __name__ == '__main__':
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)
# 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
elif sys.argv[1] == '--notemp':
notempmode = 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
for megabin in "MegaCli64", "MegaCli", "megacli", "MegaCli.exe":
dbgprint('Looking for ' + str(megabin) + ' in PATH next..')
megaclipath = which(megabin)
if megaclipath != None:
dbgprint('Will use MegaCLI from here: ' + 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)
else:
print(
'Cannot find "MegaCli64","MegaCli" or "megacli" or "MegaCli.exe" 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 cmd in Outputs:
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 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
def returnConfDriveNumber(output):
# Count the configured drives
confdrives = 0
for line in output:
if re.match(r'.*Number of PDs:.*$', line.strip()):
confdrives += int(line.split(':')[2].strip())
return int(confdrives)
def returnUnConfDriveNumber(output):
# Count the configured drives
confdrives = 0
for line in output:
if re.match(r'^Firmware state: Unconfigured.*$', line.strip()):
confdrives += 1
return int(confdrives)
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 = ''
if notempmode:
return '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 '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 '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 'REPL'
else:
return 'Good'
def returnArrayNumber(output):
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 = output[operationlinennumber + 1]
else:
inprogress = 'None'
# Compute the RAID level
NestedLDTable[int(controllerid)][int(arrayindex)] = False
if raidlvl == '':
raidtype = '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 = '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()
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(r' \[.*\.*$', '', 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'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(r'\(.*', '', 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)
# 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(r' \(.*\)', '', temp)
if model != 'Unknown':
dbgprint(
'Disk Info: '
+ str(arrayid)
+ ' '
+ str(diskid)
+ ' '
+ str(oldenclid)
)
if subfstate == 'Rebuild':
cmd = (
r'%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'
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'
elif re.match(r'^Coerced Size: ', line.strip()):
dsize = line.split(':')[1].strip()
dsize = re.sub(r' \[.*\.*$', '', dsize)
dsize = re.sub('[0-9][0-9] GB', ' Gb', dsize)
elif re.match(
r'^Drive.s position: 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'^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(r'\(.*', '', 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)
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()):
temp = line.split(':')[1].strip()
temp = re.sub(r'\(.*\)', '', 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)
)
elif 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
def returnForeignDisks(controllerid):
cmd = "%s -CfgForeign -Dsply -a%d" % (megaclipath, controllerid)
foreignout = getOutput(cmd)
foreigndisks = []
for line in foreignout:
result = re.search(r"Slot Number: (.*)", line)
if result:
matches = result.groups()
foreigndisks.append(matches[0])
return foreigndisks
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 | %-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 --')
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
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
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)
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'
# 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 : " + arrayinfo[6])
if arrayinfo[6] not in ['Optimal', 'N/A']:
bad = True
nagiosbadarray = nagiosbadarray + 1
else:
nagiosgoodarray = 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
if totaldrivenumber:
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 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 array[5] not in ['Online', 'Online, Spun Up']:
bad = True
nagiosbaddisk = nagiosbaddisk + 1
else:
nagiosgooddisk = nagiosgooddisk + 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
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 = (
"%-"
+ str(dlen + 5)
+ "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 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
totalconfdrivenumber = 0
totalunconfdrivenumber = 0
totaldrivenumber = 0
while controllerid < controllernumber:
cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid)
output = getOutput(cmd)
totalconfdrivenumber += returnConfDriveNumber(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)
totalunconfdrivenumber += returnUnConfDriveNumber(output)
controllerid += 1
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 --')
controllerid = 0
while controllerid < controllernumber:
foreigndisks = returnForeignDisks(controllerid)
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 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('Disk c' + str(controllerid) + 'uXpY status : ' + array[3])
if array[3] not in [
'Online',
'Unconfigured(good), Spun Up',
'Unconfigured(good), Spun down',
'JBOD',
'Hotspare, Spun Up',
'Hotspare, Spun down',
]:
bad = True
nagiosbaddisk = nagiosbaddisk + 1
else:
nagiosgooddisk = nagiosgooddisk + 1
if array[7] in foreigndisks:
array[3] = array[3] + " (Foreign)"
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 | %-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)
Zerion Mini Shell 1.0