Re: slightly off-topic, RAID program for on-board SAS 2308-4i ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



On 2/16/2016 3:23 PM, Zube wrote:
Does anyone know what program can be used to query the RAID status
from the OS for an on-board LSI SAS 2308-4i?

the 2308 isn't actually a megaraid, its a simple SAS HBA that has an optional raid mode IF its flashed with IR firmware... this only supports raid 0/1/10. I always(!) flash these with the IT firmware that turns them back into a plain SAS HBA, and then use operating system native raid (mdraid for centos).

the megaraid management software does support these chips in IR mode, but megacli is an awful thing to use. i found it so awful that I located and tweaked a couple python scripts to make it easier to use on a LSI MegaRAID 9261-8i (which doesn't /have/ any IT mode)

# lsi-raidinfo
-- Controllers --
-- ID | Model
c0 | LSI MegaRAID SAS 9261-8i

-- Volumes --
-- ID | Type | Size | Status | InProgress
volume c0u0 | RAID10 1x2 | 2727G | Optimal | None
volume c0u1 | RAID60 1x8 | 16370G | Optimal | None
volume c0u2 | RAID60 1x8 | 16370G | Optimal | None

-- Disks --
-- Encl:Slot | vol-span-unit | Model | Status
disk 8:0 | 0-0-0 | Z291VTS5ST33000650NS 0003 | Online, Spun Up
disk 8:1 | 0-0-1 | Z291VTRPST33000650NS 0003 | Online, Spun Up
disk 8:2 | 1-0-0 | Z291VTKWST33000650NS 0003 | Online, Spun Up
disk 8:3 | 1-0-1 | Z291VT9YST33000650NS 0003 | Online, Spun Up
disk 8:4 | 1-0-2 | Z291VTT6ST33000650NS 0003 | Online, Spun Up
disk 8:5 | 1-0-3 | Z291VT6CST33000650NS 0003 | Online, Spun Up
disk 8:6 | 1-0-4 | Z291VTLAST33000650NS 0003 | Online, Spun Up
disk 8:7 | 1-0-5 | Z291VTK1ST33000650NS 0003 | Online, Spun Up
disk 8:8 | 1-0-6 | Z291VTNGST33000650NS 0003 | Online, Spun Up
disk 8:9 | 1-0-7 | Z291VTRAST33000650NS 0003 | Online, Spun Up
disk 8:10 | 2-0-0 | Z291VV05ST33000650NS 0003 | Online, Spun Up
disk 8:11 | 2-0-1 | Z291VTW1ST33000650NS 0003 | Online, Spun Up
disk 8:12 | 2-0-2 | Z291VTRLST33000650NS 0003 | Online, Spun Up
disk 8:13 | 2-0-3 | Z291VTRXST33000650NS 0003 | Online, Spun Up
disk 8:14 | 2-0-4 | Z291VSZGST33000650NS 0003 | Online, Spun Up
disk 8:15 | 2-0-5 | Z291VSW1ST33000650NS 0003 | Online, Spun Up
disk 8:16 | 2-0-6 | Z291VTB5ST33000650NS 0003 | Online, Spun Up
disk 8:17 | 2-0-7 | Z291VSX8ST33000650NS 0003 | Online, Spun Up
disk 8:18 | x-x-x | Z291VTS7ST33000650NS 0003 | Hotspare, Spun down
disk 8:19 | x-x-x | Z291VT3HST33000650NS 0003 | Hotspare, Spun down

the script that does this is here...


# more bin/lsi-raidinfo
#!/usr/bin/python

# megaclisas-status 0.6
# renamed lsi-raidinfo
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Pulse 2; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# Copyright (C) 2007-2009 Adam Cecile (Le_Vert)

## modified by johnpuskar@xxxxxxxxx 08/14/11
# fixed for LSI 9285-8e on Openfiler

## modified by pierce@xxxxxxxxxxxx 2012-01-05
# fixed for newer version of megacli output on RHEL6/CentOS6
# output format extended to show raid span-unit and rebuild % complete

import os
import re
import sys

if len(sys.argv) > 2:
    print 'Usage: lsi-raidinfo [-d]'
    sys.exit(1)

# if argument -d, only print disk info
printarray = True
printcontroller = True
if len(sys.argv) > 1:
    if sys.argv[1] == '-d':
        printarray = False
        printcontroller = False
    else:
        print 'Usage: lsi-raidinfo [-d]'
        sys.exit(1)

# Get command output
def getOutput(cmd):
    output = os.popen(cmd)
    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'^Controller Count.*$',line.strip()):
            return int(line.split(':')[1].strip().strip('.'))

def returnControllerModel(output):
    for line in output:
        if re.match(r'^Product Name.*$',line.strip()):
            return line.split(':')[1].strip()

def returnArrayNumber(output):
    i = 0
    for line in output:
        if re.match(r'^Virtual (Drive|Disk).*$',line.strip()):
            i += 1
    return i

def returnArrayInfo(output,controllerid,arrayid):
    id = 'c'+str(controllerid)+'u'+str(arrayid)
    # print 'DEBUG: id = '+str(id)
    operationlinennumber = False
    linenumber = 0
    units = 1
    type = 'JBOD'
    span = 0
    size = 0
    for line in output:
        if re.match(r'^RAID Level.*$',line.strip()):
            type = line.strip().split(':')[1].strip()
            type = 'RAID' + type.split(',')[0].split('-')[1].strip()
            # print 'debug: type = '+str(type)
        if re.match(r'^Number.*$',line.strip()):
            units = line.strip().split(':')[1].strip()
        if re.match(r'^Span Depth.*$',line.strip()):
            span = line.strip().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()
                size = str(int(round((float(size) / 1000))))+'G'
            # 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'^State.*$',line.strip()):
            state = line.strip().split(':')[1].strip()
        if re.match(r'^Ongoing Progresses.*$',line.strip()):
            operationlinennumber = linenumber
        linenumber += 1
        if operationlinennumber:
            inprogress = output[operationlinennumber+1]
        else:
            inprogress = 'None'
    if span > 1:
        type = type+'0'
    type = type + ' ' + str(span) + 'x' + str(units)
    return [id,type,size,state,inprogress]

def returnDiskInfo(output,controllerid,currentarrayid):
    arrayid = False
    oldarrayid = False
    olddiskid = False
    table = []
    state = 'Offline'
    model = 'Unknown'
    enclnum = 'Unknown'
    slotnum = 'Unknown'
    enclsl = 'Unknown'

    firstDisk = True
    for line in output:
        if re.match(r'Firmware state: .*$',line.strip()):
            state = line.split(':')[1].strip()
            if re.match(r'Rebuild',state):
cmd2 = '/opt/MegaRAID/MegaCli/MegaCli64 pdrbld showprog physdrv['+str(enclnum)+':'+str(slotnum)+'] a'+str(controllerid)+' nolog'
                ll = getOutput(cmd2)
state += ' completed ' + re.sub(r'Rebuild Progress.*Completed', '', ll[0]).strip();
        if re.match(r'Slot Number: .*$',line.strip()):
            slotnum = line.split(':')[1].strip()
        if re.match(r'Inquiry Data: .*$',line.strip()):
            model = line.split(':')[1].strip()
            model = re.sub(' +', ' ', model)
model = re.sub('Hotspare Information', '', model).strip() #remove bogus output from firmware 12.12
        if re.match(r"(Drive|Disk)'s postion: .*$",line.strip()):
            spans = line.split(',')
span = re.sub(r"(Drive|Disk).*DiskGroup:", '', spans[0]).strip()+'-'
            span += spans[1].split(':')[1].strip()+'-'
            span += spans[2].split(':')[1].strip()
        if re.match(r'Enclosure Device ID: [0-9]+$',line.strip()):
            if firstDisk == True:
                firstDisk = False
            else:
                enclsl = str(enclnum)+':'+str(slotnum)
                table.append([str(enclsl), span, model, state])
            span = 'x-x-x'
            enclnum = line.split(':')[1].strip()
    # Last disk of last array
    enclsl = str(enclnum)+':'+str(slotnum)
    table.append([str(enclsl), span, model, state])
    arraytable = []
    for disk in table:
        arraytable.append(disk)
    return arraytable

cmd = '/opt/MegaRAID/MegaCli/MegaCli64 adpcount nolog'
output = getOutput(cmd)
controllernumber = returnControllerNumber(output)

bad = False

# List available controller
if printcontroller:
    print '-- Controllers --'
    print '-- ID | Model'
    controllerid = 0
    while controllerid < controllernumber:
cmd = '/opt/MegaRAID/MegaCli/MegaCli64 adpallinfo a'+str(controllerid)+' nolog'
        output = getOutput(cmd)
        controllermodel = returnControllerModel(output)
        print 'c'+str(controllerid)+' | '+controllermodel
        controllerid += 1
    print ''

if printarray:
    controllerid = 0
    print '-- Volumes --'
    print '-- ID | Type | Size | Status | InProgress'
    # print 'controller number'+str(controllernumber)
    while controllerid < controllernumber:
        arrayid = 0
cmd = '/opt/MegaRAID/MegaCli/MegaCli64 ldinfo lall a'+str(controllerid)+' nolog'
        output = getOutput(cmd)
        arraynumber = returnArrayNumber(output)
#       print 'array number'+str(arraynumber)
        while arrayid < arraynumber:
cmd = '/opt/MegaRAID/MegaCli/MegaCli64 ldinfo l'+str(arrayid)+' a'+str(controllerid)+' nolog'
#           print 'DEBUG: running '+str(cmd)
            output = getOutput(cmd)
#           print 'DEBUG: output '+str(output)
            arrayinfo = returnArrayInfo(output,controllerid,arrayid)
print 'volume '+arrayinfo[0]+' | '+arrayinfo[1]+' | '+arrayinfo[2]+' | '+arrayinfo[3]+' | '+arrayinfo[4]
            if not arrayinfo[3] == 'Optimal':
                bad = True
            arrayid += 1
        controllerid += 1
    print ''

print '-- Disks --'
print '-- Encl:Slot | vol-span-unit | Model | Status'

controllerid = 0
while controllerid < controllernumber:
    arrayid = 0
cmd = '/opt/MegaRAID/MegaCli/MegaCli64 ldinfo lall a'+str(controllerid)+' nolog'
    output = getOutput(cmd)
    arraynumber = returnArrayNumber(output)
    while arrayid<arraynumber:         #grab disk arrayId info
cmd = '/opt/MegaRAID/MegaCli/MegaCli64 pdlist a'+str(controllerid)+' nolog'
        #print 'debug: running '+str(cmd)
        output = getOutput(cmd)
        arraydisk = returnDiskInfo(output,controllerid,arrayid)

        for array in arraydisk:
print 'disk '+array[0]+' | '+array[1]+' | '+array[2]+' | '+array[3]
            arrayid += 1
    controllerid += 1

if bad:
    print '\nThere is at least one disk/array in a NOT OPTIMAL state.'
    sys.exit(1)









--
john r pierce, recycling bits in santa cruz

_______________________________________________
CentOS mailing list
CentOS@xxxxxxxxxx
https://lists.centos.org/mailman/listinfo/centos



[Index of Archives]     [CentOS]     [CentOS Announce]     [CentOS Development]     [CentOS ARM Devel]     [CentOS Docs]     [CentOS Virtualization]     [Carrier Grade Linux]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Linux USB]
  Powered by Linux