From 8ef38aa659fb553d7c880759dad234563fe027cc Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Thu, 14 Jan 2016 14:15:15 -0500 Subject: [PATCH 1/5] [megaclisas-stat] Improve support for Nested RAID levels by display the span ID as well.. --- wrapper-scripts/megaclisas-status | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 8ec0a76..9c17c85 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -29,6 +29,7 @@ totalunconfdrivenumber = 0 # Hardcode a max of 16 HBA for now. LDTable must be initialized to accept populating list of LD's into each ctlr's list. LDTable = [ [] * 16 for i in range(16) ] +NestedLDTable = [ [] * 16 for i in range(16) ] # Outputs is a 'dict' of all MegaCLI outputs so we can re-use them during loops.. Outputs = {} @@ -289,7 +290,7 @@ def returnArrayInfo(output,controllerid,arrayid): 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()): + if re.match(r'^Number Of Drives per span.*:.*$',line.strip()): diskperspan = int(line.strip().split(':')[1].strip()) if re.match(r'^Current Cache Policy.*?:.*$',line.strip()): props = line.strip().split(':')[1].strip() @@ -321,10 +322,12 @@ def returnArrayInfo(output,controllerid,arrayid): # Compute the RAID level if (int(spandepth) >= 2): raidtype = str('RAID-' + str(raidlvl) + '0') + NestedLDTable[controllerid][arrayid] = True else: if(raidlvl == 1): if(diskperspan > 2): raidtype = str('RAID-10') + NestedLDTable[controllerid][arrayid] = True else: raidtype = str('RAID-' + str(raidlvl)) else: @@ -341,6 +344,7 @@ def returnDiskInfo(output,controllerid): diskid = False oldenclid = False enclid = False + spanid = False slotid = False lsidid = 'Unknown' table = [] @@ -350,6 +354,9 @@ def returnDiskInfo(output,controllerid): dsize = 'Unknown' temp = 'Unk0C' 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) 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 @@ -399,8 +406,11 @@ def returnDiskInfo(output,controllerid): 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]) + dbgprint('Disk Info: '+str(arrayid)+' '+str(diskid)+' '+str(oldenclid)) + if ( NestedLDTable[controllerid][int(arrayid)] == True): + table.append([str(arrayid)+"s"+spanid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) + else: + table.append([str(arrayid), str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) return table @@ -548,6 +558,7 @@ if printarray: ldid += 1 if re.match(r'^Virtual Drive:',line.strip()): LDTable[controllerid].append ( ldid ) + NestedLDTable[controllerid].append ( False ) ldcount += 1 ldid += 1 @@ -629,6 +640,7 @@ if totaldrivenumber: print '-- Disk information --' i = 0 + dlen = 0 mlen = 0 flen = 0 controllerid = 0 @@ -644,12 +656,14 @@ if totaldrivenumber: 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' ]: + if not array[5] == 'Online' and not array[5] == '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): @@ -671,7 +685,7 @@ if totaldrivenumber: 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" + 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 ): From 7aa60e87fbc63ad153a2ecb4c7c7e8855d39ffb0 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Thu, 14 Jan 2016 14:18:13 -0500 Subject: [PATCH 2/5] [megaclisas-stat] some extra level of protection.. --- wrapper-scripts/megaclisas-status | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 9c17c85..c8f4385 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -407,7 +407,7 @@ def returnDiskInfo(output,controllerid): temp = re.sub(' \(.*\)', '', temp) if model != 'Unknown': dbgprint('Disk Info: '+str(arrayid)+' '+str(diskid)+' '+str(oldenclid)) - if ( NestedLDTable[controllerid][int(arrayid)] == True): + if (( NestedLDTable[controllerid][int(arrayid)] == True) and (spanid != False)): table.append([str(arrayid)+"s"+spanid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) else: table.append([str(arrayid), str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) From 583ec5e295c2fab26a7b65386b1c587704bc92fb Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Wed, 20 Jan 2016 11:58:48 -0500 Subject: [PATCH 3/5] [megaclisas-status] Enhance display of rebuild progress for single drive. --- wrapper-scripts/megaclisas-status | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index c8f4385..6785b39 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -139,6 +139,15 @@ def returnTotalDriveNumber(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 returnUnconfDriveNumber(output): confdrives = 0 unconfdrives = 0 @@ -349,10 +358,12 @@ def returnDiskInfo(output,controllerid): 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() @@ -382,6 +393,7 @@ def returnDiskInfo(output,controllerid): 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) @@ -407,10 +419,17 @@ def returnDiskInfo(output,controllerid): 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(arrayid)] == True) and (spanid != False)): - table.append([str(arrayid)+"s"+spanid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) + arrayid = str(arrayid)+"s"+spanid else: - table.append([str(arrayid), str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) + arrayid = str(arrayid) + table.append([arrayid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) return table @@ -423,6 +442,7 @@ def returnUnconfDiskInfo(output,controllerid): lsidid = 'Unknown' table = [] fstate = 'Offline' + substate = 'Unknown' model = 'Unknown' speed = 'Unknown' mtype = 'Unknown' From 1bec3578f7068a172a179fb0c68c1f3392a4a7e7 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Wed, 20 Jan 2016 12:03:26 -0500 Subject: [PATCH 4/5] [megaclisas-status] Minor fix. --- wrapper-scripts/megaclisas-status | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 6785b39..c212e03 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -350,6 +350,7 @@ def returnArrayInfo(output,controllerid,arrayid): def returnDiskInfo(output,controllerid): arrayid = False + sarrayid = 'Unknown' diskid = False oldenclid = False enclid = False @@ -426,10 +427,10 @@ def returnDiskInfo(output,controllerid): fstate = str('Rebuilding (%d%%)' % (percent)) if (( NestedLDTable[controllerid][int(arrayid)] == True) and (spanid != False)): - arrayid = str(arrayid)+"s"+spanid + sarrayid = str(arrayid)+"s"+spanid else: - arrayid = str(arrayid) - table.append([arrayid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) + sarrayid = str(arrayid) + table.append([sarrayid, str(diskid), mtype, model, dsize, fstate , speed, temp, enclid, slotid, lsidid]) return table From 517b2d35cdcb18ef94ae6fb1617d323cbfc3accf Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Wed, 20 Jan 2016 18:07:44 -0500 Subject: [PATCH 5/5] [megaclisas-status] bug fix : properly detect unconfigured drives when they were previously part of an array --- wrapper-scripts/megaclisas-status | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index c212e03..2a73dff 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -151,9 +151,12 @@ def returnRebuildProgress(output): def returnUnconfDriveNumber(output): confdrives = 0 unconfdrives = 0 + totaldrivenumber = 0 for line in output: if re.match(r'.*Number of PDs:.*$',line.strip()): - confdrives += int(line.split(':')[2].strip()) + totaldrivenumber += int(line.split(':')[2].strip()) + if re.match(r'^Firmware state:.*$',line.strip()): + confdrives += 1 unconfdrives = totaldrivenumber - confdrives return int(unconfdrives)