From 684adff3ca6c24a272af766d57ca8bd24b321e60 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Tue, 5 Dec 2017 23:51:59 -0500 Subject: [PATCH 01/17] Patch by David Cole: Add notemp to unconfigured drives... --- wrapper-scripts/megaclisas-status | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 3d04388..b3a2b8e 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -1,5 +1,5 @@ #!/usr/bin/python -# $Id: megaclisas-status,v 1.71 2017/04/04 18:45:52 root Exp root $ +# $Id: megaclisas-status,v 1.72 2017/12/06 04:50:58 root Exp root $ # # Written by Adam Cecile # Modified by Vincent S. Cojot @@ -547,9 +547,12 @@ def returnUnconfDiskInfo(output,controllerid): 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('\(.*\)', '', temp) # 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)) From 7aa8bb4a27985beb9ba64b715c94f18d29c594f3 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Wed, 6 Dec 2017 11:08:16 -0500 Subject: [PATCH 02/17] Add debugging hooks --- wrapper-scripts/megaclisas-status | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index b3a2b8e..fc8de76 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -668,10 +668,14 @@ if printarray: if pcipath: diskprefix = str('/dev/disk/by-path/pci-' + pcipath + '-scsi-0:') + dbgprint('Will look for DISKprefix : ' + diskprefix) for j in range (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' From 563709c1e3d4b0d7c8b9d8a6df637acf0d241778 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Mon, 26 Feb 2018 11:09:21 -0500 Subject: [PATCH 03/17] Add more debug output, initial support for storcli, investigating R60 bug.. --- wrapper-scripts/megaclisas-status | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index fc8de76..3c6e82f 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -1,5 +1,5 @@ #!/usr/bin/python -# $Id: megaclisas-status,v 1.72 2017/12/06 04:50:58 root Exp root $ +# $Id: megaclisas-status,v 1.73 2017/12/06 16:08:43 root Exp root $ # # Written by Adam Cecile # Modified by Vincent S. Cojot @@ -9,6 +9,7 @@ import os import re import sys import pdb +import inspect if sys.platform == 'win32': import ctypes @@ -70,7 +71,7 @@ if len(sys.argv) > 1: # Functions def dbgprint(msg): if (debugmode): - sys.stderr.write ( str('# DEBUG : '+msg+'\n')) + 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) @@ -85,6 +86,8 @@ def which(program): # 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/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)) @@ -96,7 +99,7 @@ def which(program): return None # Find MegaCli -for megabin in "MegaCli64","MegaCli","megacli", "MegaCli.exe": +for megabin in "MegaCli64","MegaCli","megacli", "MegaCli.exe", "storcli64", "storcli": dbgprint ('Looking for '+str(megabin)+' in PATH next..') megaclipath = which(megabin) if (megaclipath != None): @@ -556,9 +559,9 @@ def returnUnconfDiskInfo(output,controllerid): if arrayid == False: if subfstate == 'Unconfigured': dbgprint('Unconfigured Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate)) + table.append([ mtype, model, dsize, fstate, speed, temp, enclid, slotid, lsidid]) 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 cmd = '%s -adpCount -NoLog' % (megaclipath) From 5ec3ffd077c2fd820b3df1c40ba06b7d38bcd476 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Tue, 27 Feb 2018 17:16:00 -0500 Subject: [PATCH 04/17] Handle typo in LSI storcli : postion instead of position --- wrapper-scripts/megaclisas-status | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 3c6e82f..1d5e5dd 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -434,6 +434,8 @@ def returnDiskInfo(output,controllerid): 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 pos[a-z]*tion: DiskGroup: [0-9]+,.*$',line.strip()): + arrayid = 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()): @@ -519,7 +521,7 @@ def returnUnconfDiskInfo(output,controllerid): 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 position: DiskGroup: [0-9]+,.*$',line.strip()): + elif re.match(r'^Drive.s pos[a-z]*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() From 548d32124089f779e9991cc2f2d8ec414e84ec72 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Tue, 27 Feb 2018 18:59:37 -0500 Subject: [PATCH 05/17] Initial support for perccli64 too... --- wrapper-scripts/megaclisas-status | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 1d5e5dd..325a6ca 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -86,6 +86,7 @@ def which(program): # 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])) @@ -99,7 +100,7 @@ def which(program): return None # Find MegaCli -for megabin in "MegaCli64","MegaCli","megacli", "MegaCli.exe", "storcli64", "storcli": +for megabin in "MegaCli64","MegaCli","megacli", "MegaCli.exe", "perccli64", "perccli", "storcli64", "storcli": dbgprint ('Looking for '+str(megabin)+' in PATH next..') megaclipath = which(megabin) if (megaclipath != None): From 49be830f6d2b018f35e52f3439f564c09fb3912d Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Tue, 27 Feb 2018 22:34:28 -0500 Subject: [PATCH 06/17] Fix a few typos, improve debugging output --- wrapper-scripts/megaclisas-status | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 325a6ca..3dc7f2b 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -101,10 +101,10 @@ def which(program): # Find MegaCli for megabin in "MegaCli64","MegaCli","megacli", "MegaCli.exe", "perccli64", "perccli", "storcli64", "storcli": - dbgprint ('Looking for '+str(megabin)+' in PATH next..') + dbgprint ('Looking for '+str(megabin)+' in PATH...') megaclipath = which(megabin) if (megaclipath != None): - dbgprint ('Will use MegaCLI from here: '+str(megaclipath)) + dbgprint ('Will use this executable: '+str(megaclipath)) break # Check binary exists (and +x), if not print an error message @@ -118,7 +118,7 @@ if (megaclipath != None): 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.' + print 'Cannot find "MegaCli{64,}", "megacli{64,}", "perccli{64,}" or "storcli{64,}" in your PATH. Please install one of them.' sys.exit(3) @@ -878,6 +878,14 @@ if totalunconfdrivenumber: 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') + if nagiosmode: if bad: print 'RAID ERROR - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk) From 660371fbd5265ee94df6f0954f7204c961609a46 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Tue, 27 Feb 2018 22:35:45 -0500 Subject: [PATCH 07/17] Add update --- 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 3dc7f2b..02393f5 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -1,5 +1,5 @@ #!/usr/bin/python -# $Id: megaclisas-status,v 1.73 2017/12/06 16:08:43 root Exp root $ +# $Id: megaclisas-status,v 1.74 2018/02/28 03:34:56 root Exp root $ # # Written by Adam Cecile # Modified by Vincent S. Cojot From 5952d939dc2cdd46f8064ed2ed5a3625c16d0576 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Tue, 27 Feb 2018 22:48:57 -0500 Subject: [PATCH 08/17] Some more typos --- wrapper-scripts/megaclisas-status | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 02393f5..3002276 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -710,12 +710,12 @@ if printarray: arrayinfo[7], arrayinfo[8], arrayinfo[9]) - dbgprint("Array state : "+arrayinfo[6]) + dbgprint('Array state : LD ' + arrayinfo[0] + ', status : ' + arrayinfo[6]) if arrayinfo[6] not in [ 'Optimal', 'N/A' ]: bad = True - nagiosbadarray=nagiosbadarray+1 + nagiosbadarray += 1 else: - nagiosgoodarray=nagiosgoodarray+1 + nagiosgoodarray += 1 arrayindex += 1 i += 1 controllerid += 1 @@ -750,9 +750,9 @@ if totaldrivenumber: 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 + nagiosbaddisk += 1 else: - nagiosgooddisk=nagiosgooddisk+1 + nagiosgooddisk += 1 if ( returnWdthFromArrayCol(arraydisk,0) > dlen): dlen = returnWdthFromArrayCol(arraydisk,0) @@ -845,9 +845,9 @@ if totalunconfdrivenumber: 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 + nagiosbaddisk += 1 else: - nagiosgooddisk=nagiosgooddisk+1 + nagiosgooddisk += 1 mlen = returnWdthFromArrayCol(arraydisk,1) flen = returnWdthFromArrayCol(arraydisk,3) @@ -895,4 +895,5 @@ if nagiosmode: else: if bad: 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) From 67372fa585160c1a87a47f0f37265b25cd3d06fc Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Tue, 27 Feb 2018 22:50:02 -0500 Subject: [PATCH 09/17] Update revision --- 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 3002276..19910c0 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -1,5 +1,5 @@ #!/usr/bin/python -# $Id: megaclisas-status,v 1.74 2018/02/28 03:34:56 root Exp root $ +# $Id: megaclisas-status,v 1.75 2018/02/28 03:49:21 root Exp root $ # # Written by Adam Cecile # Modified by Vincent S. Cojot From be7e6a0211740ff9c636e9d6ffbadbdc2260c2c3 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Wed, 28 Feb 2018 18:03:35 -0500 Subject: [PATCH 10/17] More debugging hooks, fixed improper pattern matching and drive enumeration.. --- wrapper-scripts/megaclisas-status | 88 +++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 19910c0..4d4b2e0 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -29,6 +29,8 @@ printcontroller = True debugmode = False notempmode = False totaldrivenumber = 0 +totalconfdrivenumber = 0 +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 @@ -38,6 +40,9 @@ 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.. Outputs = {} +ConfDisks = {} +NagiosBadDisks = {} +NagiosGoodDisks = {} # Startup def print_usage(): @@ -131,7 +136,7 @@ def returnWdthFromArrayCol(glarray,idx): maxwdth = len(glrow[idx]) return maxwdth -# Get command output +# Get and cache command output def getOutput(cmd): lines = [] if ( Outputs.has_key(cmd) ): @@ -146,6 +151,17 @@ def getOutput(cmd): 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 returnControllerNumber(output): for line in output: if re.match(r'^Controller Count.*$',line.strip()): @@ -165,23 +181,29 @@ def returnRebuildProgress(output): percent = int(tmpstr.split('%')[0].strip()) return percent -def returnConfDriveNumber(output): +def returnConfDriveNumber(controllerid,output): # Count the configured drives - confdrives = 0 + confdrives = 0 ; enclid = 'N/A' ; slotid = 'N/A' for line in output: - if re.match(r'.*Number of PDs:.*$',line.strip()): - confdrives += int(line.split(':')[2].strip()) + + 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 configured drives - confdrives = 0 + # Count the un-configured/Hotspare drives + unconfdrives = 0 for line in output: if re.match(r'^Firmware state: Unconfigured.*$',line.strip()): - confdrives += 1 - if re.match(r'^Firmware state: Hotspare.*$',line.strip()): - confdrives += 1 - return int(confdrives) + unconfdrives += 1 + elif re.match(r'^Firmware state: Hotspare.*$',line.strip()): + unconfdrives += 1 + return int(unconfdrives) def returnControllerModel(output): for line in output: @@ -435,8 +457,8 @@ def returnDiskInfo(output,controllerid): 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 pos[a-z]*tion: DiskGroup: [0-9]+,.*$',line.strip()): - arrayid = line.split(',')[1].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()): @@ -522,7 +544,7 @@ def returnUnconfDiskInfo(output,controllerid): 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 pos[a-z]*tion: DiskGroup: [0-9]+,.*$',line.strip()): + 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() @@ -562,9 +584,9 @@ def returnUnconfDiskInfo(output,controllerid): if arrayid == False: if subfstate == 'Unconfigured': dbgprint('Unconfigured Disk: Arrayid: '+str(arrayid)+' DiskId: '+str(diskid)+' '+str(olddiskid)+' '+str(fstate)) - table.append([ mtype, model, dsize, fstate, speed, temp, enclid, slotid, lsidid]) 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 cmd = '%s -adpCount -NoLog' % (megaclipath) @@ -741,18 +763,21 @@ if totaldrivenumber: 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.. + #### 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: - 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 += 1 + 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: - nagiosgooddisk += 1 + bad = True + if ( AddDisk(NagiosBadDisks, diskname) ): + nagiosbaddisk += 1 if ( returnWdthFromArrayCol(arraydisk,0) > dlen): dlen = returnWdthFromArrayCol(arraydisk,0) @@ -808,7 +833,7 @@ totaldrivenumber = 0 while controllerid < controllernumber: cmd = '%s -LdPdInfo -a%d -NoLog' % (megaclipath, controllerid) output = getOutput(cmd) - totalconfdrivenumber += returnConfDriveNumber(output) + totalconfdrivenumber += returnConfDriveNumber(controllerid,output) cmd = '%s -PDGetNum -a%d -NoLog' % (megaclipath, controllerid) output = getOutput(cmd) @@ -842,12 +867,12 @@ if totalunconfdrivenumber: 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' ]: + 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' ]: + nagiosgooddisk += 1 + else: bad = True nagiosbaddisk += 1 - else: - nagiosgooddisk += 1 mlen = returnWdthFromArrayCol(arraydisk,1) flen = returnWdthFromArrayCol(arraydisk,3) @@ -885,7 +910,13 @@ if (debugmode): 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) @@ -894,6 +925,5 @@ if nagiosmode: 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 'RAID ERROR - Arrays: OK:'+str(nagiosgoodarray)+' Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+' Bad:'+str(nagiosbaddisk) + print '\nThere is at least one disk/array NOT in an OPTIMAL state.: Arrays: OK:'+str(nagiosgoodarray)+', Bad:'+str(nagiosbadarray)+' - Disks: OK:'+str(nagiosgooddisk)+', Bad:'+str(nagiosbaddisk) sys.exit(1) From 7262d9be81bc88fdf500191dc61cb69d79274777 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Wed, 28 Feb 2018 18:14:15 -0500 Subject: [PATCH 11/17] Rev 1.76 --- 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 4d4b2e0..9c61d5f 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -1,5 +1,5 @@ #!/usr/bin/python -# $Id: megaclisas-status,v 1.75 2018/02/28 03:49:21 root Exp root $ +# $Id: megaclisas-status,v 1.76 2018/02/28 23:13:35 root Exp root $ # # Written by Adam Cecile # Modified by Vincent S. Cojot From 563cd2a3a79fb0071be0c9863a664337460ce257 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Sat, 17 Mar 2018 18:44:00 -0400 Subject: [PATCH 12/17] Minor bugfixes for drives that are currently reconstructing --- wrapper-scripts/megaclisas-status | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 9c61d5f..9c15cf6 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -389,7 +389,11 @@ def returnArrayInfo(output,controllerid,arrayid,arrayindex): # If there was an ongoing operation, find the relevant line in the previous output if operationlinennumber: - inprogress = output[operationlinennumber + 1] + 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' @@ -548,8 +552,6 @@ def returnUnconfDiskInfo(output,controllerid): 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()): @@ -585,8 +587,8 @@ def returnUnconfDiskInfo(output,controllerid): 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]) + 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]) return table cmd = '%s -adpCount -NoLog' % (megaclipath) @@ -841,7 +843,10 @@ while controllerid < controllernumber: cmd = '%s -PDList -a%d -NoLog' % (megaclipath, controllerid) output = getOutput(cmd) - totalunconfdrivenumber += returnUnConfDriveNumber(output) + # 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 @@ -868,7 +873,7 @@ if totalunconfdrivenumber: 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' ]: + 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 From b2d7f60baa45e84629e3c6b8de9bab77f572a144 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Sat, 17 Mar 2018 18:44:45 -0400 Subject: [PATCH 13/17] Update build --- 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 9c15cf6..83649e6 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -1,5 +1,5 @@ #!/usr/bin/python -# $Id: megaclisas-status,v 1.76 2018/02/28 23:13:35 root Exp root $ +# $Id: megaclisas-status,v 1.77 2018/03/17 22:44:22 root Exp root $ # # Written by Adam Cecile # Modified by Vincent S. Cojot From 2a8d11d88e4a86eb77a7fe7fab5d130751a61f8b Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Sun, 30 Sep 2018 13:33:58 -0400 Subject: [PATCH 14/17] Attempt to fix Channel exploration --- wrapper-scripts/megaclisas-status | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 83649e6..798b835 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -699,7 +699,8 @@ if printarray: if pcipath: diskprefix = str('/dev/disk/by-path/pci-' + pcipath + '-scsi-0:') dbgprint('Will look for DISKprefix : ' + diskprefix) - for j in range (8): + # 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): From c7a75f48d1e8aa952e9cb601d6ee537ab0edd8af Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Sun, 30 Sep 2018 14:26:05 -0400 Subject: [PATCH 15/17] Try to determine JBOD device path... --- wrapper-scripts/megaclisas-status | 33 +++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/wrapper-scripts/megaclisas-status b/wrapper-scripts/megaclisas-status index 798b835..7b75558 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -302,7 +302,7 @@ def returnHBAInfo(table,output,controllerid): 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) ]) @@ -530,6 +530,7 @@ def returnUnconfDiskInfo(output,controllerid): 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.. @@ -588,7 +589,7 @@ def returnUnconfDiskInfo(output,controllerid): 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]) + table.append([ mtype, model, dsize, fstate, speed, temp, enclid, slotid, diskid, ospath]) return table cmd = '%s -adpCount -NoLog' % (megaclipath) @@ -860,12 +861,16 @@ if totalunconfdrivenumber: print '-- Unconfigured Disk information --' 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: @@ -880,18 +885,33 @@ if totalunconfdrivenumber: 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' + 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" + 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 Device ID") + "-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI ID", "Path") # Drive information if not nagiosmode: print drvfmt % ( @@ -903,8 +923,9 @@ if totalunconfdrivenumber: array[4], # Speed array[5], # Temp str('['+array[6]+':'+array[7]+']'), # Slot ID - array[8]) # LSI ID - i = i + 1 + array[8], # LSI ID + array[9]) # OS path, if any + i += 1 controllerid += 1 if not nagiosmode: print '' From 4dffa3cbbd7462ca1f850faf1c74e8e55065c887 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Sun, 30 Sep 2018 15:30:57 -0400 Subject: [PATCH 16/17] Make output consistent --- 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 7b75558..baa077c 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -812,7 +812,7 @@ if totaldrivenumber: if ( i == 0 ): if not nagiosmode: print drvfmt % ( - "-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI Device ID") + "-- ID", "Type", "Drive Model", "Size", "Status", "Speed", "Temp", "Slot ID", "LSI ID") # Drive information if not nagiosmode: print drvfmt % ( From b1976c289b8dff97c260157065d91556aeb5cc67 Mon Sep 17 00:00:00 2001 From: "Vincent S. Cojot" Date: Sun, 30 Sep 2018 23:53:16 -0400 Subject: [PATCH 17/17] Update rev number --- 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 baa077c..1d8e881 100755 --- a/wrapper-scripts/megaclisas-status +++ b/wrapper-scripts/megaclisas-status @@ -1,5 +1,5 @@ #!/usr/bin/python -# $Id: megaclisas-status,v 1.77 2018/03/17 22:44:22 root Exp root $ +# $Id: megaclisas-status,v 1.78 2018/10/01 03:52:57 root Exp root $ # # Written by Adam Cecile # Modified by Vincent S. Cojot