mirror of https://github.com/eLvErDe/hwraid.git
222 lines
8.1 KiB
Python
Executable File
222 lines
8.1 KiB
Python
Executable File
#!/usr/bin/python
|
|
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
if len(sys.argv) > 2:
|
|
print 'Usage: aacraid-status [-d]'
|
|
sys.exit(1)
|
|
|
|
printarray = True
|
|
printcontroller = True
|
|
|
|
bad = False
|
|
|
|
if len(sys.argv) > 1:
|
|
if sys.argv[1] == '-d':
|
|
printarray = False
|
|
printcontroller = False
|
|
else:
|
|
print 'Usage: aacraid-status [-d]'
|
|
sys.exit(1)
|
|
|
|
# Get command output
|
|
def getOutput(cmd):
|
|
output = os.popen(cmd+' 2>/dev/null')
|
|
lines = []
|
|
for line in output:
|
|
if not re.match(r'^$',line.strip()):
|
|
lines.append(line.strip())
|
|
return lines
|
|
|
|
def returnControllerNumber(output):
|
|
for line in output:
|
|
if re.match(r'^Controllers found: [0-9]+$',line.strip()):
|
|
return int(line.split(':')[1].strip().strip('.'))
|
|
|
|
def returnControllerModel(output):
|
|
for line in output:
|
|
if re.match(r'^Controller Model.*$',line.strip()):
|
|
return line.split(':')[1].strip()
|
|
|
|
def returnControllerStatus(output):
|
|
for line in output:
|
|
if re.match(r'^Controller Status.*$',line.strip()):
|
|
return line.split(':')[1].strip()
|
|
|
|
def returnArrayIds(output):
|
|
ids = []
|
|
for line in output:
|
|
if re.match(r'^Logical device number [0-9]+$',line.strip()):
|
|
ids.append(line.strip('Logical device number').strip())
|
|
return ids
|
|
|
|
def returnArrayInfo(output):
|
|
members = []
|
|
for line in output:
|
|
# RAID level may be either N or Simple_Volume
|
|
# (a disk connected to the card, not hotspare, not part of any array)
|
|
if re.match(r'^RAID level\s+: .+$',line.strip()):
|
|
type = line.split(':')[1].strip()
|
|
if re.match(r'^Status of logical device\s+: .*$',line.strip()):
|
|
status = line.split(':')[1].strip()
|
|
if re.match(r'^Size\s+: [0-9]+ MB$',line.strip()):
|
|
size = str(int(line.strip('MB').split(':')[1].strip()) / 1000)
|
|
if re.match(r'^(Group\s[0-9]+,\s)?Segment [0-9]+\s+: .*$',line.strip()):
|
|
splitter = re.compile('(\(.*\))')
|
|
# The line can be either
|
|
# Segment 0 : Present (Controller:1,Enclosure:0,Slot:0) JPW9J0N00RWMUV
|
|
# Or
|
|
# Segment 0 : Present (Controller:1,Channel:0,Device:0) S13PJ1CQ719255
|
|
# Or
|
|
# Segment 0 : Present (Controller:1,Connector:1,Device:2) 9QJ7D0MJ
|
|
line = re.sub('Controller:','',line)
|
|
line = re.sub('(Channel|Enclosure|Connector):','',line)
|
|
line = re.sub('(Device|Slot):','',line)
|
|
line = line.split(':')[1]
|
|
if re.match(r'^ Missing',line):
|
|
members.append('?,?')
|
|
else:
|
|
members.append(splitter.split(line)[1].strip('(').strip(')'))
|
|
if re.match(r'^Group [0-9], Segment [0-9]+\s+: .*$',line.strip()):
|
|
splitter = re.compile('(\(.*\))')
|
|
line = line.split(':')[1]
|
|
if re.match(r'^ Missing',line):
|
|
members.append('?,?')
|
|
else:
|
|
members.append(splitter.split(line)[1].strip('(').strip(')'))
|
|
return [type,status,size,members]
|
|
|
|
def returnControllerTasks(output):
|
|
arrayid = False
|
|
type = False
|
|
state = False
|
|
tasks = []
|
|
for line in output:
|
|
if re.match(r'^Logical device\s+: [0-9]+$',line.strip()):
|
|
arrayid = line.split(':')[1].strip()
|
|
if re.match(r'^Current operation\s+: .*$',line.strip()):
|
|
type = line.split(':')[1].strip()
|
|
if re.match(r'^Percentage complete\s+: [0-9]+$',line.strip()):
|
|
state = line.split(':')[1].strip()
|
|
if arrayid != False and type != False and state != False:
|
|
tasks.append([arrayid,type,state])
|
|
arrayid = False
|
|
type = False
|
|
state = False
|
|
return tasks
|
|
|
|
def returnDisksInfo(output,controllerid):
|
|
diskid = False
|
|
vendor = False
|
|
model = False
|
|
state = False
|
|
disks = []
|
|
for line in output:
|
|
if re.match(r'^Reported Channel,Device(\(T:L\))?\s+: [0-9]+,[0-9]+(\([0-9]+:[0-9]+\))?$',line.strip()):
|
|
diskid = re.split('\s:\s',line)[1].strip()
|
|
diskid = re.sub('\(.*\)','',diskid)
|
|
diskid = str(controllerid)+','+diskid
|
|
if re.match(r'^State\s+:.*$',line.strip()):
|
|
state = line.split(':')[1].strip()
|
|
if re.match(r'^Vendor\s+:.*$',line.strip()):
|
|
vendor = line.split(':')[1].strip()
|
|
if re.match(r'^Model\s+:.*$',line.strip()):
|
|
model = line.split(':')[1].strip()
|
|
if diskid != False and vendor != False and model != False and state != False:
|
|
disks.append([diskid,state,vendor,model])
|
|
diskid = False
|
|
vendor = False
|
|
model = False
|
|
state = False
|
|
return disks
|
|
|
|
cmd = '/usr/sbin/arcconf GETVERSION'
|
|
output = getOutput(cmd)
|
|
controllernumber = returnControllerNumber(output)
|
|
|
|
# List controllers
|
|
if printcontroller:
|
|
print '-- Controller informations --'
|
|
print '-- ID | Model | Status'
|
|
controllerid = 1
|
|
while controllerid <= controllernumber:
|
|
cmd = '/usr/sbin/arcconf GETCONFIG '+str(controllerid)
|
|
output = getOutput(cmd)
|
|
controllermodel = returnControllerModel(output)
|
|
controllerstatus = returnControllerStatus(output)
|
|
if controllerstatus != 'Optimal':
|
|
bad = True
|
|
print 'c'+str(controllerid-1)+' | '+controllermodel+' | '+controllerstatus
|
|
controllerid += 1
|
|
print ''
|
|
|
|
# List arrays
|
|
if printarray:
|
|
controllerid = 1
|
|
print '-- Arrays informations --'
|
|
print '-- ID | Type | Size | Status | Task | Progress'
|
|
while controllerid <= controllernumber:
|
|
arrayid = 0
|
|
cmd = '/usr/sbin/arcconf GETCONFIG '+str(controllerid)
|
|
output = getOutput(cmd)
|
|
arrayids = returnArrayIds(output)
|
|
for arrayid in arrayids:
|
|
cmd = '/usr/sbin/arcconf GETCONFIG '+str(controllerid)+' LD '+str(arrayid)
|
|
output = getOutput(cmd)
|
|
arrayinfo = returnArrayInfo(output)
|
|
if arrayinfo[1] != 'Optimal':
|
|
bad = True
|
|
cmd = '/usr/sbin/arcconf GETSTATUS '+str(controllerid)
|
|
output = getOutput(cmd)
|
|
tasksinfo = returnControllerTasks(output)
|
|
done = False
|
|
# Usually it should return either [0-9] or Simple_Volume but...
|
|
# It can also return "6 Reed-Solomon" so we need to handle this too...
|
|
# So let's match [0-9] followed by a space or EOL.
|
|
if re.match('^[0-9]+(\s|$)',arrayinfo[0]):
|
|
raidtype = re.sub('^','RAID',arrayinfo[0])
|
|
else:
|
|
raidtype = arrayinfo[0]
|
|
for tasks in tasksinfo:
|
|
if int(tasks[0]) == int(arrayid):
|
|
print 'c'+str(controllerid-1)+'u'+str(arrayid)+' | '+raidtype+' | '+arrayinfo[2]+'G | '+arrayinfo[1]+' | '+tasks[1]+' | '+tasks[2]+'%'
|
|
done = True
|
|
break
|
|
if done == False:
|
|
print 'c'+str(controllerid-1)+'u'+str(arrayid)+' | '+raidtype+' | '+arrayinfo[2]+'G | '+arrayinfo[1]
|
|
controllerid += 1
|
|
print ''
|
|
|
|
# List disks
|
|
controllerid = 1
|
|
print '-- Disks informations'
|
|
print '-- ID | Model | Status'
|
|
while controllerid <= controllernumber:
|
|
arrayid = 0
|
|
cmd = '/usr/sbin/arcconf GETCONFIG '+str(controllerid)
|
|
output = getOutput(cmd)
|
|
arrayids = returnArrayIds(output)
|
|
for arrayid in arrayids:
|
|
cmd = '/usr/sbin/arcconf GETCONFIG '+str(controllerid)+' LD '+str(arrayid)
|
|
output = getOutput(cmd)
|
|
arrayinfo = returnArrayInfo(output)
|
|
cmd = '/usr/sbin/arcconf GETCONFIG '+str(controllerid)+' PD'
|
|
output = getOutput(cmd)
|
|
diskinfo = returnDisksInfo(output,controllerid)
|
|
for member in arrayinfo[3]:
|
|
i = 0
|
|
for disk in diskinfo:
|
|
if disk[1] != 'Online' and disk[1] != 'Hot Spare' and disk[1] != 'Ready':
|
|
bad = True
|
|
if disk[0] == member:
|
|
print 'c'+str(controllerid-1)+'u'+str(arrayid)+'d'+str(i)+' | '+disk[2]+' '+disk[3]+' | '+disk[1]
|
|
i += 1
|
|
controllerid += 1
|
|
|
|
if bad:
|
|
print '\nThere is at least one disk/array in a NOT OPTIMAL state.'
|
|
print '\nUse "arcconf GETCONFIG [1-9]" to get details.'
|
|
sys.exit(1)
|