Python常用脚本
- Python
- 2024-03-27
- 205热度
- 0评论
获取磁盘及raid配置
用法如下:
# python check_disk.py -c
/a0/v0 RAID1 1.090 TB Optimal /dev/sda /
/a0/c8/d0 /e8/s0 1.090 TB Online (SAS)HDD /D0/S0/R0
/a0/c8/d1 /e8/s1 1.090 TB Online (SAS)HDD /D0/S0/R1
更多详细的用法可以-h查看提示
# python check_disk.py -h
usage: check_disk.py [-h] [-i | -I | -c | -o [/an/cn/dn] | -f [/an/cn/dn] | -r
| -d | -delvd [/an/vn]]
optional arguments:
-h, --help show this help message and exit
-i, --inspect 默认选项, 输出==check_disk故障信息
-I, --inspecttype 输出故障信息
-c, --checkdisk 输出所有的pd和vd信息
-o [/an/cn/dn], --onblink [/an/cn/dn]
进行亮灯,
当不指定参数时只进行故障盘亮灯,
指定参数时进行指定的盘亮灯.
-f [/an/cn/dn], --offblink [/an/cn/dn]
进行灭灯,
当不指定参数时只灭自动亮的灯,
指定参数时进行指定盘灭灯.
-r, --recordpderr 记录报错盘信息
-d, --diskdetail 格式化输出磁盘详细信息
-delvd [/an/vn] 删除指定vd
完整代码如下:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from __future__ import print_function
import os
import re
import json
import sys
import tempfile
import time
import datetime
import subprocess
import copy
import traceback
def exit(num=0):
sys.exit(num)
statelist = ["Online", "JBOD", "configured(good)", "configured(good), Spun dow", "Unconfigured(good)",
"Rebuild", "Ready", "Okay", "Optimal", "Online (JBOD)", "OK"]
proc_dir = "/tmp/diskerr"
config = {
# 保存控制器相关信息
"controllerjs": proc_dir + "/Controller.js",
# 保存vd pd 相关信息
"diskinfofilejs": proc_dir + "/diskinfo.js",
# 保存pd详细信息
"pdinfofilejs": proc_dir + "/pdinfo.js",
# 每天保存一份pd 报错信息
"pderrfile": proc_dir + "/pderr",
# 记录换盘是故障盘数据
"replacefile": proc_dir + "/replace",
# 记录换盘后挂载盘数据
"replaceagofile": proc_dir + "/replace_ago"
}
def humanSort(list):
# slist= sorted(list)
def tryint(s): # 将元素中的数字转换为int后再排序
try:
return int(s)
except ValueError:
return s
def str2int(v_str): # 将元素中的字符串和数字分割开
return [tryint(sub_str) for sub_str in re.split('([0-9]+)', v_str)]
def sort_humanly(v_list): # 以分割后的list为单位进行排序
return sorted(v_list, key=str2int)
return sort_humanly(sorted(list))
# 转换时间格式到字符串(天) 年月日
def human_date(date=None):
if not date:
assert isinstance(date, datetime)
else:
date = datetime.datetime.today()
return date.strftime('%Y%m%d')
# 将字符串转换为时间
def parse_time(value):
if isinstance(value, str):
if len(value) == 8:
return datetime.datetime.strptime(value, '%Y%m%d')
if len(value) == 10:
return datetime.datetime.strptime(value, '%Y-%m-%d')
elif len(value) == 19:
return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
raise TypeError('Expect a datetime.datetime value')
class humanJson():
@classmethod
def load(self, file_handle):
return self._byteify(
json.load(file_handle, object_hook=self._byteify),
ignore_dicts=True
)
@classmethod
def loads(self, json_text):
return self._byteify(
json.loads(json_text, object_hook=self._byteify),
ignore_dicts=True
)
@classmethod
def _byteify(self, data, ignore_dicts=False):
if sys.version[0] == "3":
return data
# if this is a unicode string, return its string representation
if isinstance(data, unicode):
return data.encode('utf-8')
# if this is a list of values, return list of byteified values
if isinstance(data, list):
return [self._byteify(item, ignore_dicts=True) for item in data]
# if this is a dictionary, return dictionary of byteified keys and values
# but only if we haven’t already byteified it
if isinstance(data, dict) and not ignore_dicts:
return {
self._byteify(key, ignore_dicts=True): self._byteify(value, ignore_dicts=True)
for key, value in data.iteritems()
}
# if it’s anything else, return it in its original form
return data
class RaidError(Exception):
def __init__(self, msg, stat):
super(RaidError, self).__init__(msg, stat)
self.msg = msg
self.stat = stat
def __str__(self):
return "RaidError: %s\nError Code: %s" % (self.msg, self.stat)
class OsCmd():
def __init__(self, cmd, timeout=20):
# 创建临时文件
self.cmd = cmd
self.timeout = timeout
self.f = tempfile.SpooledTemporaryFile(max_size=10 * 1000)
fileno = self.f.fileno()
self.proc = subprocess.Popen(
cmd, shell=True, stdout=fileno, stderr=fileno)
def data(self):
try:
start_time = time.time()
while self.proc.poll() is None:
time.sleep(0.1)
now_time = time.time()
if (now_time - start_time) > self.timeout:
self.proc.terminate()
raise RaidError(
"{} command timeout".format(self.cmd), "124")
break
self.f.seek(0)
lines = self.f.read().strip()
if sys.version_info[0] >= 3:
d = lines.decode('utf-8')
else:
d = lines
return d
except Exception:
self.proc.terminate()
raise RaidError("{} command ERR".format(self.cmd), "125")
finally:
if self.f:
self.f.close()
def install_cmd(raid_cmd=""):
# 进行安装命令
if raid_cmd != '':
# res = OsCmd("sudo lsb_release -a 2>&1")
res = OsCmd("sudo cat /etc/*-release 2>&1").data()
if 'Debian' in res:
raidCmdRes = OsCmd("sudo dpkg -s %s 2>&1" % (raid_cmd)).data()
if 'install ok installed' not in raidCmdRes:
OsCmd("sudo apt-get -y --allow-unauthenticated install %s 2>&1" %
(raid_cmd)).data()
smartmontoolsRes = OsCmd("sudo dpkg -s smartmontools 2>&1").data()
if 'install ok installed' not in smartmontoolsRes:
OsCmd(
"sudo apt-get install smartmontools -y --allow-unauthenticated 2>&1").data()
elif 'CentOS' in res or 'Red Hat' in res or 'Kylin' in res:
# elif 'CentOS' in res:
if raid_cmd == 'megacli':
raid_cmd = 'MegaCli'
raidCmdRes = os.popen(
"sudo rpm -qa %s 2>&1" % (raid_cmd)).read()
raidCmdRes2 = os.popen(
"whereis %s|awk -F ':' '{print $NF}' 2>&1" % (raid_cmd)).read()
if raid_cmd not in raidCmdRes and raid_cmd not in raidCmdRes2:
if 'Red Hat' in res and raid_cmd == 'MegaCli':
print("s--")
OsCmd(
"sudo yum -y install MegaCli.i386 --enablerepo=netease-self").data()
OsCmd(
"sudo ln -s /opt/MegaRAID/MegaCli/MegaCli64 /usr/sbin/megacli 2>/dev/null;exit 0").data()
else:
OsCmd("sudo yum -y install %s 2>&1" % (raid_cmd)).data()
elif 'MegaCli-8.00.46-1.i386' in raidCmdRes or 'MegaCli-8.07.14-1.noarch' in raidCmdRes:
if not os.path.exists("/usr/sbin/megacli"):
OsCmd(
"sudo ln -s /opt/MegaRAID/MegaCli/MegaCli64 /usr/sbin/megacli").data()
smartmontoolsRes = OsCmd("sudo rpm -qa smartmontools 2>&1").data()
if 'smartmontools' not in smartmontoolsRes:
OsCmd("sudo yum install smartmontools -y").data()
else:
raise RaidError("Please confirm the system version", "127")
class CmdLsblk():
@classmethod
def out(self):
self.pvs = self.islvm()
util_linux_verlion = OsCmd("sudo fdisk -v|awk '{print $NF}'").data()
util_linux_verlionList = util_linux_verlion.split(".")
if int(util_linux_verlionList[0]) >= 2 and int(util_linux_verlionList[1]) >= 27:
blockList = self.lsblk2_27()
else:
blockList = self.lsblk()
return blockList
@classmethod
def islvm(self):
try:
disk_lvm = OsCmd(
"sudo pvs 2> /dev/null|awk '{print $1}'|grep -v -E 'PV|nvme|failed'|| exit 0").data()
except Exception:
disk_lvm = ""
finally:
return disk_lvm
@classmethod
def lsblk2_27(self):
get_pci = OsCmd(
"ls -l /sys/block/|grep sd|awk -F '->' '{print $2}'").data()
blockList = []
# block = OsCmd("ls -l /sys/block/|grep sd|awk -F '->' '{print $2}'").data()
blockdevices = humanJson.loads(
OsCmd("lsblk -O -J").data())["blockdevices"]
for d in blockdevices:
blockdeviceDict = {}
# 获取逻辑盘符
kname = d.get("name").strip()
if "nvme" in kname or "sd" not in kname:
continue
blockdeviceDict["name"] = "/dev/" + kname
# 获取挂载点,只是其中之一
#
mount = d.get("mountpoint")
if not mount and d.get("children"):
for children in d.get("children"):
if children.get("mountpoint"):
mount = children.get("mountpoint").strip()
break
if self.pvs and blockdeviceDict["name"] in self.pvs:
mount = "lvm"
blockdeviceDict["mount"] = mount
blockdeviceDict["vendor"] = d.get("vendor").strip()
blockdeviceDict["model"] = d.get("model").strip()
blockdeviceDict["sn"] = d.get("serial").strip()
try:
blockdeviceDict["wwn"] = d.get("wwn").strip()
except Exception:
blockdeviceDict["wwn"] = ""
blockdeviceDict["hctl"] = d.get("hctl").strip()
pci = re.findall("\.\..*%s" % (kname), get_pci)[0]
if "pci" in pci:
blockdeviceDict["pci"] = re.findall("\.\..*%s" % (kname), get_pci)[0].split("/")[4].replace("0000:", '')
else:
continue
blockList.append(blockdeviceDict)
return blockList
@classmethod
def lsblk(self):
blockList = []
get_pci = OsCmd(
"ls -l /sys/block/|grep sd|awk -F '->' '{print $2}'").data()
get_disk = OsCmd(
"sudo lsblk -o NAME,TYPE,MOUNTPOINT,TYPE,MODEL|grep -i ' disk '|grep -v nvme").data().strip()
get_part = OsCmd(
"sudo lsblk -o NAME,TYPE,MOUNTPOINT,TYPE,MODEL|grep -i part|grep -v nvme").data().strip()
for disk in get_disk.split("\n"):
blockdeviceDict = {}
d = disk.split("disk")
# 获取逻辑盘符
kname = d[0].strip()
if "nvme" in kname or "sd" not in kname:
continue
blockdeviceDict["name"] = "/dev/" + kname
# 获取挂载点
mount = d[1].strip()
if not mount:
for part in re.findall(".*%s.*" % (kname), get_part):
p = part.split("part")
if p[1].strip():
mount = p[1].strip()
break
if self.pvs and blockdeviceDict["name"] in self.pvs:
mount = "lvm"
blockdeviceDict["mount"] = mount
block = self.diskcmd(kname)
blockdeviceDict["vendor"] = block["vendor"]
blockdeviceDict["model"] = block["model"]
blockdeviceDict["sn"] = block["sn"]
try:
blockdeviceDict["wwn"] = d.get("wwn").strip()
except Exception:
blockdeviceDict["wwn"] = ""
blockdeviceDict["hctl"] = block["hctl"]
pci = re.findall("\.\..*%s" % (kname), get_pci)[0]
if "pci" in pci:
blockdeviceDict["pci"] = re.findall("\.\..*%s" % (kname), get_pci)[0].split("/")[4].replace("0000:", '')
else:
continue
blockList.append(blockdeviceDict)
return blockList
@classmethod
def diskcmd(self, kname):
disk = {}
# 并行执行命令
vendor = OsCmd(
"cat /sys/class/block/%s/device/vendor" % (kname))
model = OsCmd("cat /sys/class/block/%s/device/model" % (kname))
#sn = OsCmd("sudo smartctl -a /dev/%s|grep -i Serial|awk '{print $NF}' || echo " % (kname))
sn = OsCmd(
"sudo udevadm info --query=all --name=/dev/%s|awk -F '=' ' /ID_SCSI_SERIAL|ID_SERIAL_SHORT/{print $2}'" % (kname))
#sn = OsCmd("cat /sys/class/block/%s/device/inquiry" % (kname))
wwn = OsCmd(
"cat /sys/class/block/%s/device/wwid|awk -F '.' '{print $NF}'" % (kname))
hctl = OsCmd("ls /sys/class/block/%s/device/bsg" % (kname))
# 获取命令执行结果
disk["vendor"] = vendor.data()
disk["model"] = model.data()
SN = sn.data().split("\n")
if len(SN) > 1:
disk["sn"] = SN[-1]
else:
disk["sn"] = SN[0]
disk["wwn"] = "0x" + wwn.data()
disk["hctl"] = hctl.data()
return disk
class MegaCli():
def __init__(self):
install_cmd("megacli")
self.Disklist = CmdLsblk.out()
self.ContList = [] # 定义控制器信息
self.PDList = {} # 所有PD信息
self.VDList = {} # 所有VD信息
def get_Cont_List(self):
'''
[{"ContId":"0","PCI":"af:00.0"}]
'''
ContList = []
getcontlist = OsCmd("sudo megacli -AdpGetPciInfo -aall").data()
for cont in getcontlist.strip().split("PCI information for"):
if cont and "Controller" in cont:
continfo = {}
continfo["ContId"] = re.findall(
"Controller.*", cont)[0].split(" ")[1].strip()
PCI = re.findall("Bus Number.*", cont)[0].split(":")[1].strip()
if len(PCI) == 1:
continfo["PCI"] = ("0%s:00.0" % (PCI))
else:
continfo["PCI"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
self.ContList = ContList
return ContList
def get_pdinfo(self, pd, ContId):
diskinfo = {}
AID = ContId
EID = re.findall("Enclosure Device ID.*", pd)[0].split(":")[1].strip()
if EID == "N/A":
EID = "00"
SID = re.findall("Slot Number.*", pd)[0].split(":")[1].strip()
CID = EID
DID = SID
# diskinfo["acd"] = ("/a%s/c%s/d%s/e%s/s%s" % (diskinfo["CID"], diskinfo["DID"], diskinfo["ContId"], diskinfo["EID"], diskinfo["SID"]))
diskinfo["ACD"] = ("/a%s/c%s/d%s" % (AID, CID, DID))
diskinfo["ES"] = ("/e%s/s%s" % (EID, SID))
# 获取wwn
try:
diskinfo["WWN"] = "0x" + \
re.findall("WWN.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["WWN"] = ""
# 获取state
try:
State = re.findall(
"Firmware state.*", pd)[0].split(":")[1]
diskinfo["State"] = re.split(", Spun Up", State)[0].strip()
except Exception:
diskinfo["State"] = "NO"
# 获取media_err
try:
diskinfo["Media_err"] = re.findall(
"Media Error Count.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Media_err"] = "0"
# 获取other
try:
diskinfo["Other_err"] = re.findall(
"Other Error Count.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Other_err"] = "0"
# 获取failure
try:
diskinfo["Failure"] = re.findall(
"Predictive Failure Count.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Failure"] = "0"
# 获取
try:
diskinfo["Size"] = re.findall(
"Raw Size.*", pd)[0].split(":")[1].split("[")[0].strip()
except Exception:
diskinfo["Size"] = "NO"
# 获取类型
try:
Intf = re.findall("PD Type.*", pd)[0].split(":")[1].strip()
if "Hard Disk Device" in pd:
Med = "HDD"
else:
Med = "SSD"
diskinfo["Type"] = ("(%s)%s" % (Intf, Med))
except Exception:
diskinfo["Type"] = "NO"
try:
try:
DEVID = re.findall("Device Id.*", pd)[0].split(":")[1].strip()
smart = OsCmd(
"sudo smartctl -a -d megaraid,%s /dev/sda" % (DEVID)).data()
diskinfo["SN"] = re.findall(
"Serial.*", smart)[0].split(":")[-1].strip()
diskinfo["Model"] = re.findall(
"Product:.*|.*Device Model.*", smart)[0].split(":")[-1].strip()
if "SSD" in diskinfo["Type"]:
if "Media_Wearout_Indicator" in smart:
diskinfo["Wearout"] = re.findall(
".*Media_Wearout_Indicator.*", smart)[0].split()[3].strip()
elif "Unknown_SSD_Attribute" in smart:
diskinfo["Wearout"] = re.findall(
".*202 *Unknown_SSD_Attribute.*", smart)[0].split()[3].strip()
elif "Percentage" in smart:
diskinfo["Wearout"] = re.findall(
".*Unknown_SSD_Attribute.*", smart)[0].split()[3].strip()
except Exception:
Model = re.findall(
"Inquiry Data.*", pd)[0].split(":")[1].strip().split()
diskinfo["SN"] = '-'.join(Model)
diskinfo["Model"] = '-'.join(Model)
except Exception:
diskinfo["SN"] = ''
diskinfo["Model"] = ''
# 获取DSR
try:
Diskid = re.findall(
"Drive's position: DiskGroup: \d+, Span: \d+, Arm: \d+", pd)[0].strip()
DiskGroup = re.split(":|\,", Diskid)
diskinfo['DSR'] = ("/D%s/S%s/R%s" % (DiskGroup[2].strip(),
DiskGroup[4].strip(), DiskGroup[6].strip()))
except Exception:
diskinfo['DSR'] = ''
diskinfo["diskName"] = ""
diskinfo["Mount"] = ""
# print(json.dumps(devInfo, indent= 2).replace('\"',''))
return diskinfo
def get_PD_List(self):
'''
{ "/c0/d0/a0/e10/s1":{},
"/c0/d0/a0/e10/s2":{},
}
'''
Disklist = self.Disklist
PDList = {}
getPdinfo = OsCmd("sudo megacli -pdlist -aall").data()
for pdinfo in getPdinfo.strip().split("Adapter"):
if pdinfo and "#" in pdinfo:
ContId = re.findall(
"#\\d+", pdinfo)[0].split('#')[1].strip() # 获取raid卡号
# 以Enclosure Device ID为分隔符获取pd信息
disklist = re.findall(
"Enclosure Device ID[\\s\\S]*?Drive Temperature", pdinfo)
for pd in disklist:
diskinfo = self.get_pdinfo(pd, ContId)
# PDList.append(diskinfo)
for lb in Disklist:
if lb["sn"] and lb["wwn"] and (str(lb["sn"]) in str(diskinfo["SN"]) or diskinfo["WWN"] == lb["wwn"]):
diskinfo["diskName"] = lb["name"]
diskinfo["Mount"] = lb["mount"]
PDList[diskinfo["ACD"]] = diskinfo
self.PDList = PDList
return PDList
def get_vdinfo(self, ContId, PCI):
Disklist = self.Disklist
try:
getvdinfo = OsCmd(
"sudo megacli -showsummary -a%s | sed -n '/Virtual Drives/,$p'" % (ContId)).data()
if not getvdinfo:
getvdinfo = OsCmd(
"sudo megacli -showsummary -aall | sed -n '/Virtual Drives/,$p'").data()
# VDinfo= []
VDinfo = {}
for vdinfo in getvdinfo.strip().split("\n\n"):
if vdinfo and "Virtual drive" in vdinfo:
vd = {}
vd["ContId"] = ContId
vd["PCI"] = PCI
vd['TYPE'] = "RAID" + \
re.findall("RAID Level.*",
vdinfo)[0].split(":")[1].strip()
vd['State'] = re.findall(
"State.*", vdinfo)[0].split(":")[1].strip()
vd['Cache'] = ""
# getcache= OsCmd(" sudo megacli -ldgetprop -cache -L%s -a%s"% (vd['VD'],ContId))
# if "WriteBack" in getcache:
# vd['Cache'] = "WB"
# elif "WriteThrough" in getcache:
# vd['Cache'] = "WT"
vd['Size'] = re.findall(
"Size.*", vdinfo)[0].split(":")[1].strip()
VD = re.findall("Virtual drive.*",
vdinfo)[0].split(":")[1].strip()
vd['VD'] = re.split(" ", VD)[2]
vd['AV'] = ("/a%s/v%s" % (vd["ContId"], vd['VD']))
vd['PDs'] = []
vd["diskName"] = ""
vd["Mount"] = ""
for dl in Disklist:
tid = re.split(":", dl["hctl"])[-2]
if (str(dl["pci"]) == str(vd["PCI"]) or str(vd["PCI"] == "00:00.0")) and str(tid) == str(vd["VD"]):
vd["diskName"] = dl["name"]
vd["Mount"] = dl["mount"]
# VDinfo.append(vd)
VDinfo[vd['AV']] = vd
return VDinfo
except Exception:
return {}
def get_VD_List(self):
Disklist = self.Disklist
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
VDList = {}
# 获取控制器id
for cont in ContList:
ContId = cont["ContId"]
PCI = cont["PCI"]
VDinfo = self.get_vdinfo(ContId, PCI)
getpds = OsCmd("sudo megacli -ldpdinfo -a%s " % (ContId)).data()
vd_list = re.split("Virtual Drive: \d+ \(Target ", getpds)
for vd in vd_list:
if vd and "Id:" in vd:
id = re.findall("Id: \d+\)",
vd)[0].split(":")[1].split(")")[0].strip()
AV = ("/a%s/v%s" % (ContId, id))
if VDinfo:
vdinfo = VDinfo[AV]
else:
vdinfo = {}
vdinfo["ContId"] = ContId
vdinfo["PCI"] = PCI
vdinfo['TYPE'] = "RAID"
vdinfo['State'] = "Optimal"
vdinfo['Size'] = ''
vdinfo['VD'] = id
vdinfo['AV'] = AV
vdinfo['PDs'] = []
vdinfo["Cache"] = ""
vdinfo["diskName"] = ""
vdinfo["Mount"] = ""
for dl in Disklist:
tid = re.split(":", dl["hctl"])[-2]
if str(dl["pci"]) == str(vdinfo["PCI"]) and str(tid) == str(vdinfo["VD"]):
vdinfo["diskName"] = dl["name"]
vdinfo["Mount"] = dl["mount"]
# VDinfo.append(vd)
vdinfo = vdinfo
disklist = re.findall(
"Enclosure Device ID[\\s\\S]*?Drive Temperature", vd)
for pd in disklist:
# smart=Oscmd.dir_data(sudo smartctl -a -d megaraid,25 /dev/sda|egrep -i "Media_Wearout_Indicator|Serial Number:|Product:|Device Model")
pdinfo = self.get_pdinfo(pd, ContId)
# try:
# slot = pdinfo["ES"].split("/s")[-1]
# smart = OsCmd("sudo smartctl -a -d megaraid,%s %s" % (slot, vdinfo["diskName"]))
# pdinfo["SN"] = re.findall("Serial.*", smart)[0].split(":")[-1].strip()
# pdinfo["Model"] = re.findall("Product:.*|.*Device Model.*", smart)[0].split(":")[-1].strip()
# if "SSD" in pdinfo["Type"]:
# pdinfo["Wearout"] = re.findall(".*Media_Wearout_Indicator.*", smart)[0].split()[3].strip()
# except Exception:
# pass
vdinfo["PDs"].append(pdinfo)
VDList[AV] = vdinfo
self.VDList = VDList
return VDList
class Arcconf():
def __init__(self):
install_cmd("arcconf")
self.Disklist = CmdLsblk.out()
self.ContList = [] # 定义控制器信息
self.PDList = {} # 所有PD信息
self.VDList = {} # 所有VD信息
def get_Cont_List(self):
'''
[{"ContId":"0","PCI":"af:00.0"}]
'''
ContList = []
ret = OsCmd("sudo lspci|grep -i Adaptec").data()
if re.findall(".*SAS/PCIe 2.*", ret):
ContId = 0
for cont in re.findall(".*SAS/PCIe 2.*", ret):
ContId = ContId + 1
PCI = re.split(":", cont)[0]
continfo = {}
continfo["ContId"] = ContId
if len(PCI) == 1:
continfo["PCI"] = ("0%s:00.0" % (PCI))
else:
continfo["PCI"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
else:
getcontlist = OsCmd("sudo arcconf list").data()
for cont in re.findall("Controller \d+:", getcontlist):
ContId = re.findall("\d", cont)[0]
getcontinfo = OsCmd(
"sudo arcconf getconfig %s ad" % (ContId)).data()
continfo = {}
continfo["ContId"] = ContId
PCI = re.findall(
"PCI Address.*", getcontinfo)[0].split(":")[-3].strip()
if len(PCI) == 1:
continfo["PCI"] = ("0%s:00.0" % (PCI))
else:
continfo["PCI"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
self.ContList = ContList
return ContList
def get_PD_List(self):
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
Disklist = self.Disklist
# PDList= []
PDList = {}
for cont in ContList:
ContId = cont["ContId"]
getPdinfo = OsCmd("sudo arcconf getconfig %s pd" % (ContId)).data()
for pd in re.split("Device #\d+", getPdinfo):
if 'Device is a Hard drive' not in pd:
continue
diskinfo = {}
AID = ContId
eidlot = re.findall("Reported Location.*",
pd)[0].split(":")[1].strip()
try:
EID = re.findall(
"Enclosure \d+", eidlot)[0].split()[-1].strip()
except Exception:
if re.findall("Enclosure Direct Attached", eidlot):
EID = "01"
else:
EID = "00"
try:
SID = re.findall(
"Slot \d+", eidlot)[0].split(" ")[-1].strip()
except Exception:
SID = "00"
CD = re.findall("Reported Channel,Device.*",
pd)[0].split(" ")[-1].strip()
DID = re.split(",|\(", CD)[1].strip()
CID = re.split(",|\(", CD)[0].strip()
# diskinfo["acd"] = ("/c%s/d%s/a%s/e%s/s%s" % (diskinfo["CID"], diskinfo["DID"], diskinfo["ContId"], diskinfo["EID"], diskinfo["SID"]))
diskinfo["ACD"] = ("/a%s/c%s/d%s" % (AID, CID, DID))
diskinfo["ES"] = ("/e%s/s%s" % (EID, SID))
# wwn
try:
diskinfo["WWN"] = "0x" + \
re.findall("World-wide name.*",
pd)[0].split(":")[1].strip()
except Exception:
diskinfo["WWN"] = ""
# state
try:
diskinfo["State"] = re.findall(
"State.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["State"] = "NO"
# media
try:
diskinfo["Media_err"] = re.findall(
"Media Failures.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Media_err"] = "0"
# other
try:
diskinfo["Other_err"] = re.findall(
"Other Time Out Errors.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Other_err"] = "0"
# failuer
try:
diskinfo["Failure"] = re.findall(
"Predictive Failures.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Failure"] = "0"
# model
try:
diskinfo["Model"] = re.findall(
"Model.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Model"] = "0"
# sn
try:
diskinfo["SN"] = re.findall(
"Serial number.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["SN"] = "0"
# size
try:
diskinfo["Size"] = re.findall(
"Total Size.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Size"] = "NO"
# type
try:
intf = re.findall("Transfer Speed.*",
pd)[0].split(":")[1].strip()
Intf = re.split(" ", intf)[0].strip()
med = re.findall("SSD.*", pd)[0].split(":")[1].strip()
if "NO" in med:
Med = 'SSD'
else:
Med = 'HDD'
diskinfo["Type"] = ("(%s)%s" % (Intf, Med))
except Exception:
diskinfo["Type"] = "NO"
diskinfo["DSR"] = ""
diskinfo["diskName"] = ""
diskinfo["Mount"] = ""
for lb in Disklist:
if lb["sn"] and (str(lb["sn"]) in str(diskinfo["SN"]) or diskinfo["WWN"] == lb["wwn"]):
diskinfo["diskName"] = lb["name"]
diskinfo["Mount"] = lb["mount"]
PDList[diskinfo["ACD"]] = diskinfo
# PDList.append(diskinfo)
self.PDList = PDList
return PDList
def get_VD_List(self):
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
Disklist = self.Disklist
if not self.PDList:
PDList = self.get_PD_List()
else:
PDList = self.PDList
# VDList= []
VDList = {}
for cont in ContList:
ContId = cont["ContId"]
PCI = cont["PCI"]
getVdinfo = OsCmd("sudo arcconf getconfig %s ld" % (ContId)).data()
for vd in re.split("\n\n\n", getVdinfo):
if "Logical Device number" not in vd:
continue
vdinfo = {}
vdinfo["ContId"] = ContId
vdinfo["PCI"] = PCI
vdinfo["TYPE"] = "RAID" + \
re.findall("RAID level.*", vd)[0].split(":")[1].strip()
vdinfo["State"] = re.findall(
"Status of Logical Device.*", vd)[0].split(":")[1].strip()
vdinfo["Cache"] = ""
vdinfo["Size"] = re.findall(
"Size .*", vd)[0].split(":")[1].strip()
vdinfo["VD"] = re.findall(
"Logical Device number \d+", vd)[0].split()[-1].strip()
vdinfo["AV"] = ("/a%s/v%s" % (vdinfo["ContId"], vdinfo["VD"]))
vdinfo['PDs'] = []
for Device in re.findall("Device \d+.*", vd):
try:
AID = ContId
EID = re.findall(
"Enclosure:\d+", Device)[0].split(":")[-1].strip()
SID = re.findall(
"Slot:\d+", Device)[0].split(":")[-1].strip()
ES = ("/e%s/s%s" % (EID, SID))
for acd in PDList:
pd = PDList[acd]
ad = re.findall("/a\\d+", acd)[0].strip("/a")
if str(ad) == str(AID) and str(pd["ES"]) == str(ES):
vdinfo["PDs"].append(pd)
except Exception:
AID = ContId
DID = re.findall(
"Device \d+", Device)[0].split(" ")[-1].strip()
acd = ("/a%s/c%s/d%s" % (AID, 0, DID))
vdinfo["PDs"].append(PDList[acd])
if "Disk Name" in vd:
vdinfo["diskName"] = re.findall(
"Disk Name.*", vd)[0].split(":")[1].strip()
else:
vdinfo["diskName"] = ""
if "Mount Points" in vd:
mount = re.findall(
"Mount Points.*", vd)[0].split(":")[1].strip()
vdinfo["Mount"] = re.split(" ", mount)[0]
else:
vdinfo["Mount"] = ""
if vdinfo["diskName"] == "":
for dl in Disklist:
lid = re.split(":", dl["hctl"])[-1]
if str(dl["pci"]) == str(vd["PCI"]) and str(lid) == str(vd["VD"]):
vdinfo["diskName"] = dl["name"]
vdinfo["Mount"] = dl["mount"]
# VDList.append(vdinfo)
if 'No' in vdinfo["diskName"]:
vdinfo["diskName"] = ""
if 'No' in vdinfo["Mount"]:
vdinfo["Mount"] = ""
VDList[vdinfo["AV"]] = vdinfo
self.VDList = VDList
return VDList
class Arcconf2():
def __init__(self):
install_cmd("arcconf")
self.Disklist = CmdLsblk.out()
self.ContList = [] # 定义控制器信息
self.PDList = {} # 所有PD信息
self.VDList = {} # 所有VD信息
def get_Cont_List(self):
'''
[{"ContId":"0","PCI":"af:00.0"}]
'''
ContList = []
ContId = 0
ret = OsCmd("sudo lspci|grep -i Adaptec").data()
for cont in re.findall(".*SAS/PCIe 2.*", ret):
ContId = ContId + 1
PCI = re.split(":", cont)[0]
continfo = {}
continfo["ContId"] = ContId
if len(PCI) == 1:
continfo["PCI"] = ("0%s:00.0" % (PCI))
else:
continfo["PCI"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
self.ContList = ContList
return ContList
def get_PD_List(self):
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
Disklist = self.Disklist
# PDList= []
PDList = {}
for cont in ContList:
ContId = cont["ContId"]
getPdinfo = OsCmd("sudo arcconf getconfig %s pd" % (ContId)).data()
for pd in re.split("Device #\d+", getPdinfo):
if 'Device is a Hard drive' not in pd:
continue
diskinfo = {}
AID = ContId
try:
eidlot = re.findall("Reported Location.*", pd)[0].split(":")[1].strip()
EID = re.findall("Enclosure \d+", eidlot)[0].split()[-1].strip()
SID = re.findall("Slot \d+", eidlot)[0].split(" ")[-1].strip()
except Exception:
EID = "00"
SID = "00"
CD = re.findall("Reported Channel,Device.*",
pd)[0].split(" ")[-1].strip()
DID = re.split(",|\(", CD)[1].strip()
CID = re.split(",|\(", CD)[0].strip()
diskinfo["ACD"] = ("/a%s/c%s/d%s" % (AID, CID, DID))
diskinfo["ES"] = ("/e%s/s%s" % (EID, SID))
# wwn
try:
diskinfo["WWN"] = "0x" + \
re.findall("World-wide name.*",
pd)[0].split(":")[1].strip()
except Exception:
diskinfo["WWN"] = ""
# state
try:
diskinfo["State"] = re.findall(
"State.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["State"] = "NO"
diskinfo["Media_err"] = "0"
diskinfo["Other_err"] = "0"
diskinfo["Failure"] = "0"
# model
try:
diskinfo["Model"] = re.findall(
"Model.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Model"] = "0"
try:
diskinfo["SN"] = re.findall(
"Serial number.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["SN"] = "NO"
# type
try:
diskinfo["Size"] = re.findall(
" Size.*|Total Size.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Size"] = "NO"
try:
intf = re.findall("Transfer Speed.*",
pd)[0].split(":")[1].strip()
Intf = re.split(" ", intf)[0].strip()
diskinfo["Type"] = Intf # sata
except Exception:
diskinfo["Type"] = "NO"
diskinfo["DSR"] = ""
diskinfo["diskName"] = ""
diskinfo["Mount"] = ""
for lb in Disklist:
if lb["sn"] and (str(lb["sn"]) in str(diskinfo["SN"]) or diskinfo["WWN"] == lb["wwn"]):
diskinfo["diskName"] = lb["name"]
diskinfo["Mount"] = lb["mount"]
PDList[diskinfo["ACD"]] = diskinfo
# PDList.append(diskinfo)
self.PDList = PDList
return PDList
def get_VD_List(self):
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
PDList = self.get_PD_List()
Disklist = self.Disklist
if not self.PDList:
PDList = self.get_PD_List()
else:
PDList = self.PDList
VDList = {}
for cont in ContList:
ContId = cont["ContId"]
PCI = cont["PCI"]
getVdinfo = OsCmd("sudo arcconf getconfig %s ld" % (ContId)).data()
for vd in re.split("\n\n", getVdinfo):
if "Logical device number" not in vd and "Logical Device number" not in vd:
continue
vdinfo = {}
vdinfo["ContId"] = ContId
vdinfo["PCI"] = PCI
TYPE = "RAID" + \
re.findall("RAID level.*", vd)[0].split(":")[1].strip()
if "Simple_volume" in TYPE:
vdinfo["TYPE"] = "RAID0"
else:
vdinfo["TYPE"] = TYPE
vdname = re.findall(
"Logical [d,D]evice name .*:.*", vd)[0].split(":")[1].strip()
if "JBOD" in vdname:
vdinfo["State"] = "JBOD"
else:
vdinfo["State"] = re.findall(
"Status of [l,L]ogical [d,D]evice.*", vd)[0].split(":")[1].strip()
vdinfo["Cache"] = ""
vdinfo["Size"] = re.findall(
"Size .*", vd)[0].split(":")[1].strip()
vdinfo["VD"] = re.findall(
"Logical [d,D]evice number \d+", vd)[0].split()[-1].strip()
vdinfo["AV"] = ("/a%s/v%s" % (vdinfo["ContId"], vdinfo["VD"]))
vdinfo['PDs'] = []
for Device in re.findall("Segment \d+.*", vd):
AID = ContId
EID = re.findall(
"Enclosure:\d+", Device)[0].split(":")[-1].strip()
SID = re.findall(
"Slot:\d+", Device)[0].split(":")[-1].strip()
ES = ("/e%s/s%s" % (EID, SID))
for acd in PDList:
pd = PDList[acd]
ad = re.findall("/a\\d+", acd)[0].strip("/a")
if str(ad) == str(AID) and str(pd["ES"]) == str(ES):
vdinfo["PDs"].append(pd)
vdinfo["diskName"] = ""
vdinfo["Mount"] = ""
for dl in Disklist:
lid = re.split(":", dl["hctl"])[-2]
if str(dl["model"]) == str(vdname) and str(lid) == str(vdinfo["VD"]):
vdinfo["diskName"] = dl["name"]
vdinfo["Mount"] = dl["mount"]
# VDList.append(vdinfo)
VDList[vdinfo["AV"]] = vdinfo
self.VDList = VDList
return VDList
class Sas2icu():
def __init__(self):
install_cmd("sas2ircu")
self.Disklist = CmdLsblk.out()
self.ContList = [] # 定义控制器信息
self.PDList = {} # 所有PD信息
self.VDList = {} # 所有VD信息
def get_Cont_List(self):
'''
[{"ContId":"0","PCI":"af:00.0"}]
'''
ContList = []
try:
getcontlist = OsCmd(
"sudo sas2ircu list|grep -i '^ *[0-9]'").data().strip()
for cont in re.split("\n", getcontlist):
continfo = {}
continfo["ContId"] = cont.split()[0]
pciinfo = cont.split()[4]
PCI = re.split("h:", pciinfo)[1]
if len(PCI) == 1:
continfo["PCI"] = ("0%s:00.0" % (PCI))
else:
continfo["PCI"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
self.ContList = ContList
except Exception:
ContId = -1
ret = OsCmd("sudo lspci|grep -i SAS").data()
for cont in re.findall(".*SAS.*", ret):
ContId = ContId + 1
PCI = re.split(":", cont)[0]
continfo = {}
continfo["ContId"] = ContId
if len(PCI) == 1:
continfo["PCI"] = ("0%s:00.0" % (PCI))
else:
continfo["PCI"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
self.ContList = ContList
return self.ContList
def get_PD_List(self):
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
Disklist = self.Disklist
PDList = {}
VDList = {}
for cont in ContList:
ContId = cont["ContId"]
PCI = cont["PCI"]
getinfo = OsCmd("sudo sas2ircu %s DISPLAY" % (ContId)).data()
# pd信息
getPdinfo = re.findall(
"Physical device information[\\s\\S]*Enclosure information", getinfo)
for pd in getPdinfo[0].split("\n\n"):
if 'Device is a Hard disk' not in pd:
continue
diskinfo = {}
AID = ContId
EID = re.findall("Enclosure .*", pd)[0].split(":")[1].strip()
SID = re.findall("Slot #.*", pd)[0].split(":")[1].strip()
CID = EID
DID = SID
# diskinfo["acd"] = ("/c%s/d%s/a%s/e%s/s%s" % (diskinfo["CID"], diskinfo["DID"], diskinfo["ContId"], diskinfo["EID"], diskinfo["SID"]))
diskinfo["ACD"] = ("/a%s/c%s/d%s" % (AID, CID, DID))
diskinfo["ES"] = ("/e%s/s%s" % (EID, SID))
# 获取wwn
try:
diskinfo["WWN"] = "0x" + \
re.findall("GUID.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["WWN"] = "NO"
# 获取size
try:
Size = re.findall("Size.*", pd)[0].split(":")[1].strip()
diskinfo["Size"] = re.split("/", Size)[0].strip() + "MB"
except Exception:
diskinfo["Size"] = "NO"
# 获取状态
try:
diskinfo["State"] = re.findall(
"State.*", pd)[0].split(":")[1].strip().split(" ")[0].strip()
except Exception:
diskinfo["State"] = "NO"
diskinfo["Media_err"] = 0
diskinfo["Other_err"] = 0
diskinfo["Failure"] = 0
# 获取磁盘型号
try:
diskinfo["Model"] = re.findall(
"Model Number.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Model"] = "NO"
# 获取磁盘sn
try:
diskinfo["SN"] = re.findall(
"Serial No.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["SN"] = "NO"
# 获取磁盘类型
try:
Intf = re.findall(
"Protocol.*", pd)[0].split(":")[1].strip()
Med = re.findall(
"Drive Type.*", pd)[0].split(":")[1].strip()
diskinfo["Type"] = ("(%s)%s" %
(Intf, re.split("_", Med)[-1]))
except Exception:
diskinfo["Type"] = "NO"
diskinfo["DSR"] = ""
diskinfo["diskName"] = ""
diskinfo["Mount"] = ""
for lb in Disklist:
if lb["sn"] and (str(lb["sn"]) == str(diskinfo["SN"]) or str(diskinfo["WWN"]) == str(lb["wwn"])):
diskinfo["diskName"] = lb["name"]
diskinfo["Mount"] = lb["mount"]
break
PDList[diskinfo["ACD"]] = diskinfo
# vd信息
getVdinfo = re.findall(
"IR Volume information[\\s\\S]*Physical device information", getinfo)
for vd in re.split("IR volume \d+", getVdinfo[0]):
vdinfo = {}
if 'Volume ID' not in vd:
continue
vdinfo["ContId"] = ContId
vdinfo["PCI"] = PCI
vdinfo['TYPE'] = re.findall(
"RAID level.*", vd)[0].split(":")[1].strip()
vdinfo['State'] = re.findall(
"Status of volume.*", vd)[0].split(":")[1].strip().split(" ")[0].strip() # Okay
vdinfo['Cache'] = ''
vdinfo['Size'] = re.findall(
"Size.*", vd)[0].split(":")[1].strip() + "MB"
vdinfo["VD"] = re.findall(
"Volume ID.*", vd)[0].split(":")[1].strip()
vdinfo['AV'] = ("/a%s/v%s" % (vdinfo["ContId"], vdinfo['VD']))
vdinfo['PDs'] = []
for acd in re.findall("PHY.*", vd):
CID = re.findall("PHY.*", acd)[0].split(":")[1].strip()
DID = re.findall("PHY.*", acd)[0].split(":")[-1].strip()
ACD = ("/a%s/c%s/d%s" % (AID, CID, DID))
vdinfo['PDs'].append(PDList[ACD])
vdinfo['diskName'] = 'NO'
vdinfo['Mount'] = 'NO'
VDList[vdinfo['AV']] = vdinfo
self.PDList = PDList
self.VDList = VDList
return PDList
def get_VD_List(self):
if not self.VDList:
self.get_PD_List()
return self.VDList
class Ssacli():
def __init__(self):
install_cmd("ssacli")
self.ContList = [] # 定义控制器信息
self.PDList = {} # 所有PD信息
self.VDList = {} # 所有VD信息
def get_Cont_List(self):
'''
[{"ContId":"0","PCI":"af:00.0"}]
'''
ContList = []
getcontlist = OsCmd("sudo ssacli ctrl all show detail").data()
for cont in getcontlist.strip().split("Smart Array"):
if cont and "Slot" in cont:
continfo = {}
continfo["ContId"] = re.findall(
"Slot:.*", cont)[0].split(":")[1].strip()
PCI = re.findall(
"PCI Address.*", cont)[0].split(":")[-2].strip()
if len(PCI) == 1:
continfo["PCI"] = ("0%s:00.0" % (PCI))
else:
continfo["PCI"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
self.ContList = ContList
return ContList
def get_PD_List(self):
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
Disklist = self.Disklist
# PDList= []
PDList = {}
for cont in ContList:
ContId = cont["ContId"]
getPdinfo = OsCmd(
"sudo ssacli ctrl slot=%s pd all show detail" % (ContId)).data()
for pd in re.split("physicaldrive", getPdinfo):
if 'Port' not in pd:
continue
diskinfo = {}
try:
AID = ContId
Port = re.findall("Port.*", pd)[0].split(":")[1].strip()
Box = re.findall("Box.*", pd)[0].split(":")[1].strip()
Bay = re.findall("Bay.*", pd)[0].split(":")[1].strip()
EID = Port+Box
SID = Bay
except Exception:
EID = "00"
SID = "00"
DID = SID
CID = EID
# diskinfo["acd"] = ("/c%s/d%s/a%s/e%s/s%s" % (diskinfo["CID"], diskinfo["DID"], diskinfo["ContId"], diskinfo["EID"], diskinfo["SID"]))
diskinfo["ACD"] = ("/a%s/c%s/d%s" % (AID, CID, DID))
diskinfo["ES"] = ("/e%s/s%s" % (EID, SID))
# wwn
try:
diskinfo["WWN"] = "0x" + \
re.findall("WWID.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["WWN"] = ""
# state
try:
diskinfo["State"] = re.findall(
"Status.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["State"] = "NO"
# media
diskinfo["Media_err"] = "0"
# other
diskinfo["Other_err"] = "0"
# failuer
diskinfo["Failure"] = "0"
# model
try:
diskinfo["Model"] = re.findall(
"Model.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Model"] = "0"
# sn
try:
diskinfo["SN"] = re.findall(
"Serial Number.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["SN"] = "0"
# size
try:
diskinfo["Size"] = re.findall(
"Size:.*", pd)[0].split(":")[1].strip()
except Exception:
diskinfo["Size"] = "NO"
# type
try:
Interface_Type = re.findall(
"Interface Type.*", pd)[0].split(":")[1].strip()
Intf = re.split(" ", Interface_Type)[-1].strip()
if "Solid State" in Interface_Type:
Med = 'SSD'
else:
Med = 'HDD'
diskinfo["Type"] = ("(%s)%s" % (Intf, Med))
except Exception:
diskinfo["Type"] = "NO"
diskinfo["DSR"] = ""
diskinfo["diskName"] = ""
diskinfo["Mount"] = ""
for lb in Disklist:
if lb["sn"] and (str(lb["sn"]) in str(diskinfo["SN"]) or diskinfo["WWN"] == lb["wwn"]):
diskinfo["diskName"] = lb["name"]
diskinfo["Mount"] = lb["mount"]
PDList[diskinfo["ACD"]] = diskinfo
# PDList.append(diskinfo)
self.PDList = PDList
return PDList
def get_VD_List(self):
if not self.ContList:
ContList = self.get_Cont_List()
else:
ContList = self.ContList
PDList = self.get_PD_List()
if not self.PDList:
PDList = self.get_PD_List()
else:
PDList = self.PDList
# VDList= []
VDList = {}
for cont in ContList:
ContId = cont["ContId"]
PCI = cont["PCI"]
getVdinfo = OsCmd(
" sudo ssacli ctrl slot=%s ld all show detail" % (ContId)).data()
getconfig = OsCmd(
" sudo ssacli ctrl slot=%s show config" % (ContId)).data()
for vd in re.split("Array", getVdinfo):
if "Logical Drive" not in vd:
continue
vdinfo = {}
vdinfo["ContId"] = ContId
vdinfo["PCI"] = PCI
vdinfo["TYPE"] = "RAID" + \
re.findall("Fault Tolerance.*",
vd)[0].split(":")[1].strip()
vdinfo["State"] = re.findall(
"Status:.*", vd)[0].split(":")[1].strip()
vdinfo["Cache"] = ""
vdinfo["Size"] = re.findall(
"Size.*", vd)[0].split(":")[1].strip()
vdinfo["VD"] = re.findall(
"Logical Drive:.*", vd)[0].split()[-1].strip()
vdinfo["AV"] = ("/a%s/v%s" % (vdinfo["ContId"], vdinfo["VD"]))
vdinfo['PDs'] = []
if "physicaldrive" in vd:
for Device in re.findall("physicaldrive.*", vd):
AID = ContId
devid = re.findall(
"physicaldrive.*", Device)[0].split(" ")[1].strip()
Port = devid.split(":")[0].strip()
Box = devid.split(":")[1].strip()
Bay = devid.split(":")[2].strip()
CID = Port+Box
DID = Bay
ACD = ("/a%s/c%s/d%s" % (AID, CID, DID))
vdinfo["PDs"].append(PDList[ACD])
else:
for pds in re.split("Array", getconfig):
if re.findall(" logicaldrive %s.*" % (vdinfo["VD"]), pds):
for Device in re.findall("physicaldrive.*", pds):
AID = ContId
devid = re.findall(
"physicaldrive.*", Device)[0].split(" ")[1].strip()
Port = devid.split(":")[0].strip()
Box = devid.split(":")[1].strip()
Bay = devid.split(":")[2].strip()
CID = Port+Box
DID = Bay
ACD = ("/a%s/c%s/d%s" % (AID, CID, DID))
vdinfo["PDs"].append(PDList[ACD])
if "Disk Name" in vd:
vdinfo["diskName"] = re.findall(
"Disk Name:.*", vd)[0].split(":")[1].strip()
else:
vdinfo["diskName"] = ""
if "Mount Points" in vd:
mount = re.findall("Mount Points:.*",
vd)[0].split(":")[1].strip()
vdinfo["Mount"] = re.split(",| ", mount)[0]
else:
vdinfo["Mount"] = ""
VDList[vdinfo["AV"]] = vdinfo
self.VDList = VDList
return VDList
# 判断故障盘
class FaultDiskInfo():
def getFailedPD(self, OtherPdList):
msg = {"state": 0, "media_err": 0, "other_err": 0,
"failuer": 0, "wearout": 100, "dropDiskNum": 0, "errtotal": 0}
data = {}
for pdid in humanSort(OtherPdList):
pd = OtherPdList.get(pdid)
msg["errtotal"] = msg["errtotal"] + \
int(pd["Media_err"]) + \
int(pd["Other_err"]) + int(pd["Failure"])
if pd["State"] not in statelist or (pd["diskName"] and not pd["Mount"]) or (not pd["diskName"] and not pd["Mount"]):
if "good" in pd["State"]:
continue
# 盘状态不在statelist 和 盘没有盘符,和挂载点,认为为故障盘
msg["state"] = msg["state"] + 1
data[pdid] = pd
elif int(pd["Media_err"]) > 0 or int(pd["Other_err"]) > 0 or int(pd["Failure"]) > 0 or (pd.get("Wearout") and int(pd["Wearout"]) < 30):
# 盘有media_err other_err failuer 和固态硬盘寿命小于30的为故障盘
if str(pdid) not in str(data.keys()):
data[pdid] = pd
if int(pd["Media_err"]) > int(msg["media_err"]):
msg["media_err"] = int(pd["Media_err"])
if int(pd["Other_err"]) > int(msg["other_err"]):
msg["other_err"] = int(pd["Other_err"])
if int(pd["Failure"]) > int(msg["failuer"]):
msg["failuer"] = int(pd["Failure"])
if pd.get("Wearout") and int(pd["Wearout"]) < int(msg["wearout"]):
msg["wearout"] = int(pd["Wearout"])
return msg, data
def getFaultVirDisk(self, VDList):
msg = {"state": 0, "media_err": 0, "other_err": 0,
"failuer": 0, "wearout": 100, "dropDiskNum": 0, "errtotal": 0}
data = {}
# 判断vd报错
for vid in humanSort(VDList):
vd = VDList[vid]
# 判断vd的状态
if vd["State"] not in statelist:
# 如果状态不对
msg["state"] = msg["state"] + 1
data[vid] = vd
# 判断改磁盘下的pd是否有err报错
else:
for pd in vd["PDs"]:
msg["errtotal"] = msg["errtotal"] + \
int(pd["Media_err"]) + \
int(pd["Other_err"]) + int(pd["Failure"])
# 将在vd中的pd进行过来
if pd["State"] not in statelist or int(pd["Media_err"]) > 0 or int(pd["Other_err"]) > 0 or int(pd["Failure"]) > 0 or (pd.get("Wearout") and int(pd["Wearout"]) < 30):
# 判断报错的vd信息是否已经记录,没记录进行记录
if str(vid) not in str(data.keys()):
data[vid] = vd
# 巡检输出最大报错
if int(pd["Media_err"]) > int(msg["media_err"]):
msg["media_err"] = int(pd["Media_err"])
if int(pd["Other_err"]) > int(msg["other_err"]):
msg["other_err"] = int(pd["Other_err"])
if int(pd["Failure"]) > int(msg["failuer"]):
msg["failuer"] = int(pd["Failure"])
if pd.get("Wearout") and int(pd["Wearout"]) < int(msg["wearout"]):
msg["wearout"] = int(pd["Wearout"])
return msg, data
def getDropDisk(self, PDList):
msg = {"state": 0, "media_err": 0, "other_err": 0,
"failuer": 0, "wearout": 100, "dropDiskNum": 0, "errtotal": 0}
data = {}
ACD1 = ""
for ACD in humanSort(PDList):
if ACD1:
# 判断是否为有不连续的盘
D1 = ACD1.split("/d")[-1]
D2 = ACD.split("/d")[-1]
AC1 = re.findall("/a\\d+/c\\d+|/a\\d+/c\\d+I\\d+", ACD1)[0]
AC2 = re.findall("/a\\d+/c\\d+|/a\\d+/c\\d+I\\d+", ACD)[0]
if str(AC1) == str(AC2) and int(D2) - int(D1) == 2:
msg["dropDiskNum"] = msg["dropDiskNum"] + 1
data[ACD1] = PDList[ACD1]
data[ACD] = PDList[ACD]
ACD1 = ACD
return msg, data
# 格式化输出
class FormatOutput():
def pdout(self, pd):
if pd.get("Wearout") is None:
Wearout = ""
else:
Wearout = "Wearout:{}".format(pd.get("Wearout"))
# 判断是否有media、other以及Failure报错,如果没有报错则不输出这三项
if int(pd["Media_err"]) == 0 and int(pd["Other_err"]) == 0 and int(pd["Failure"]) == 0:
value = (
pd.get("ACD"),
pd.get("ES"),
pd.get("Size"),
pd.get("State"),
pd.get("Type"),
pd.get("DSR"),
Wearout,
pd.get("diskName"),
pd.get("Mount")
)
msg = '{} {} {} {} {} {} {} {} {}'.format(*tuple(value))
else:
value = (
pd.get("ACD"),
pd.get("ES"),
pd.get("Size"),
pd.get("State"),
pd.get("Type"),
pd.get("DSR"),
Wearout,
pd.get("Media_err"),
pd.get("Other_err"),
pd.get("Failure"),
pd.get("diskName"),
pd.get("Mount")
)
msg = '{} {} {} {} {} {} {} Media_err:{} Other_err:{} Failure:{} {} {}'.format(
*tuple(value))
print(msg)
def vdout(self, VD, sign=False):
# sign 是否进格式化
# VirDiskInfoList = ["AV", "TYPE", "Size", "State", "Cache", "diskName", "Mount"]
value = (
VD["AV"],
VD["TYPE"],
VD["Size"],
VD["State"],
VD["Cache"],
VD["diskName"],
VD["Mount"]
)
if sign:
if VD["State"] not in statelist:
msg = '\033[1;34m{} {} {} \033[5;31m{}\033[1;34m {} {} {}\033[0m'.format(
*tuple(value))
else:
msg = '\033[1;34m{} {} {} {} {} {} {}\033[0m'.format(
*tuple(value))
else:
msg = '{} {} {} {} {} {} {}'.format(*tuple(value))
print(msg)
for pd in VD["PDs"]:
self.pdout(pd)
# 自动亮灯,灭灯
class AutoBlink():
def __init__(self):
self.raidType = getRaidtype()
def FaultVDAutoBlink(self, VDList):
_, faultvd = FaultDiskInfo().getFaultVirDisk(VDList)
autoPdBlink = []
if faultvd:
for vid in faultvd:
# 判断是raid几
vd = faultvd.get(vid)
raidnum = str(vd["TYPE"])
if (raidnum == "RAID0" and not vd.get("Mount")) or (raidnum == "RAID1" and len(vd["PDs"]) > 1) or (raidnum == "RAID10" and len(vd["PDs"]) % 2 == 0):
# raid0 并且没有挂载,可以直接亮
# 如果raid1没有掉盘的,可以直接换
# raid10 如果没有掉盘的,可以直接换
pds = []
for pd in vd["PDs"]:
if pd["State"] not in statelist or int(pd["Media_err"]) > 0 or int(pd["Other_err"]) > 0 or int(pd["Failure"]) > 0:
pds.append(pd)
if len(pds) == 1:
# 如果故障盘为一个的话可以直接换,否则不能直接换
autoPdBlink.extend(pds)
# elif len(pds) > 1:
# print("有多块盘报错, 不满足自动亮灯条件")
return autoPdBlink
def FaultPDAutoBlink(self, OtherPdList):
autoPdBlink = []
_, faultpd = FaultDiskInfo().getFailedPD(OtherPdList)
if faultpd:
for pid in faultpd:
pd = faultpd[pid]
if pd["State"] not in statelist:
# 如果盘状态不对的话,可以直接换
# pdBlinkNum.append(pd["ACD"])
autoPdBlink.append(pd)
elif pd["diskName"] and not pd["Mount"]:
# pdBlinkNum.append(pd["ACD"])
autoPdBlink.append(pd)
# else:
# print("%s 有报错,不满足自动亮灯条件,请人工操作" % (pd["ACD"]))
return autoPdBlink
def DropDiskAutoBlink(self, PDList):
_, otherfaultpd = FaultDiskInfo().getDropDisk(PDList)
if otherfaultpd:
return otherfaultpd.values()
else:
return []
def pdAutoBlink(self, VDList, OtherPdList):
autoPdBlink = []
autoPdBlink.extend(self.FaultVDAutoBlink(VDList))
autoPdBlink.extend(self.FaultPDAutoBlink(OtherPdList))
return autoPdBlink
def onBlink(self, acd='', pd={}):
# print(re.findall("/a\\d+/c\\d+I\\d+/d\\d+", acd))
if not acd:
raise RaidError("Please enter the correct slot number", "127")
elif not re.findall("/a\\d+/c\\d+/d\\d+", acd) and not re.findall("/a\\d+/c\\d+I\\d+/d\\d+", acd):
raise RaidError(
"Please enter the correct slot number format: /a0/c32/d1", "127")
aid = re.findall("/a\\d+", acd)[0].replace("/a", '').strip()
cid = re.findall("/c\\d+", acd)[0].replace("/c", '').strip()
did = re.findall("/d\\d+", acd)[0].replace("/d", '').strip()
try:
box = re.findall("I\\d+", acd)[0].replace("I", '').strip()
except Exception:
box = ""
acd = str(acd)
if self.raidType == "megacli":
ret = OsCmd(
"sudo megacli -PdLocate -start -PhysDrv[%s:%s] -a%s || exit 0" % (cid, did, aid)).data()
elif self.raidType == "arcconf2":
ret = os.popen(
"sudo nohup arcconf IDENTIFY %s DEVICE %s %s 2>/dev/null &" % (aid, cid, did)).read()
# print("%s 无法亮灯,请人工操作" % (acd))
# exit(0)
elif self.raidType == "arcconf":
ret = OsCmd("sudo arcconf IDENTIFY %s DEVICE %s %s TIME 120" %
(aid, cid, did)).data()
elif self.raidType == "sas2icu":
ret = OsCmd("sudo sas2ircu %s locate %s:%s on" %
(aid, cid, did)).data()
elif self.raidType == "ssacli":
ret = OsCmd("sudo ssacli ctrl slot=%s pd %sI:%s:%s modify led=on" %
(aid, cid, box, did)).data()
if not ret:
ret = "success"
else:
print("未适配自动亮灯")
if "uccess" in ret:
if pd and str(acd) == str(pd.get("ACD")):
print("\n故障磁盘已亮灯,磁盘信息如下:")
FormatOutput().pdout(pd)
else:
print("%s 盘, 已亮灯" % (acd))
else:
if pd and str(acd) == str(pd.get("ACD")) and pd["State"] not in statelist:
print("磁盘亮灯失败, 磁盘应该有故障灯,磁盘信息如下,麻烦确认后操作:")
FormatOutput().pdout(pd)
else:
print("亮灯失败,请人工操作")
def offBlink(self, acd=''):
if not acd:
raise RaidError("Please enter the correct slot number", "127")
elif not re.findall("/a\\d+/c\\d+/d\\d+", acd) and not re.findall("/a\\d+/c\\d+I\\d+/d\\d+", acd):
raise RaidError(
"Please enter the correct slot number format: /a0/c32/d1", "127")
aid = re.findall("/a\\d+", acd)[0].replace("/a", '').strip()
cid = re.findall("/c\\d+", acd)[0].replace("/c", '').strip()
did = re.findall("/d\\d+", acd)[0].replace("/d", '').strip()
try:
box = re.findall("I\\d+", acd)[0].replace("I", '').strip()
except Exception:
box = ""
acd = str(acd)
if self.raidType == "megacli":
ret = OsCmd(
"sudo megacli -PdLocate -stop -PhysDrv[%s:%s] -a%s || exit 0" % (cid, did, aid)).data()
elif self.raidType == "arcconf2":
ret = os.popen(
"echo ''|sudo arcconf IDENTIFY %s DEVICE %s %s 2>/dev/null " % (aid, cid, did)).read()
# print("%s 无法灭灯,请人工操作" % (acd))
# exit(0)
elif self.raidType == "arcconf":
ret = OsCmd("sudo arcconf IDENTIFY %s DEVICE %s %s TIME 1" %
(aid, cid, did)).data()
elif self.raidType == "sas2icu":
ret = OsCmd("sudo sas2ircu %s locate %s:%s off" %
(aid, cid, did)).data()
elif self.raidType == "ssacli":
ret = OsCmd("sudo ssacli ctrl slot=%s pd %sI:%s:%s modify led=off" %
(aid, cid, box, did)).data()
if not ret:
ret = "success"
else:
print("未适配自动灭灯")
if "uccess" in ret:
print("%s 盘, 已灭灯" % (acd))
else:
print(ret)
print("灭灯失败,请人工操作")
exit(0)
# 获取控制器信息,未使用
class Controller():
def getContPciAndId(self):
ControlleList = []
ControllerDict = self.SaveControllerInfo()
for raidcmd in ControllerDict:
if raidcmd == "updata_time":
continue
for cont in ControllerDict.get(raidcmd):
res = {}
res["PCI"] = cont.get("PCI")
res["ContId"] = cont.get("ContId")
ControlleList.append(res)
return ControlleList
def SaveControllerInfo(self):
f = config.get("Controllerjs")
# 获取系统启动时间
since = os.popen("who -b|awk '{print $(NF-1)}'").read().strip()
systemUpSinceTime = datetime.datetime.strptime(since, '%Y-%m-%d')
if os.path.exists(f):
# 文件存在
Controllerjs = open(f, "r")
ControllerDict = json.load(Controllerjs)
Controllerjs.close()
updata_time_str = ControllerDict.get("updata_time")
updata_time = datetime.datetime.strptime(
updata_time_str, '%Y-%m-%d')
if updata_time > systemUpSinceTime:
return ControllerDict
newTime = datetime.datetime.now().strftime('%Y-%m-%d')
ControllerDict = {"updata_time": newTime}
pciDict = self.PciInfo()
for raidcmd in pciDict.keys():
ControllerDict[raidcmd] = []
if raidcmd == "megacli":
Contid = self.MegaRAID()
elif raidcmd == "arcconf":
Contid = self.Adaptec()
elif raidcmd == "arcconf2":
Contid = self.Adaptec2()
elif raidcmd == "sas2ircu":
Contid = self.Sas()
ContInfoList = pciDict[raidcmd]
for cont in ContInfoList:
for c in Contid:
if c.get('pci') == cont.get('PCI'):
cont['ContId'] = c.get("contid")
ControllerDict[raidcmd].append(cont)
Controllerjs = open(f, "w")
json.dump(ControllerDict, Controllerjs)
Controllerjs.close()
return ControllerDict
def PciInfo(self):
ControllerDict = {}
cmd = "sudo lspci |grep -E 'Adaptec|MegaRAID|SAS'|awk '{print $1}'"
for pci in os.popen(cmd).readlines():
pci = str(pci).strip("\n")
res = {"PCI": pci}
cmd = "sudo lspci -v -s {} ".format(str(pci))
pciInfo = os.popen(cmd).readlines()
for line in pciInfo:
line = str(line).strip("\n")
if re.search("Subsystem: ", line):
res["Subsystem"] = line.split(
"Subsystem: ")[1].strip()
if re.search("Kernel driver in use:", line):
res["Kernel_driver"] = line.split(
"Kernel driver in use:")[1].strip()
if re.search("Flags:", line):
res["Flags"] = line.split("Flags: ")[1].strip()
if res["Kernel_driver"] == "megaraid_sas":
res["RaidCmd"] = "megacli"
elif res["Kernel_driver"] == "smartpqi":
res["RaidCmd"] = "arcconf"
elif res["Kernel_driver"] == "aacraid":
res["RaidCmd"] = "arcconf2"
elif res["Kernel_driver"] == "mpt2sas":
res["RaidCmd"] = "sas2ircu"
elif res["Kernel_driver"] == "mpt3sas":
res["RaidCmd"] = "storcli"
key = res["RaidCmd"]
if key in ControllerDict.keys():
ControllerDict[key].append(res)
else:
ControllerDict[key] = []
ControllerDict[key].append(res)
return ControllerDict
def MegaRAID(self):
ControllerDict = []
getcontlist = os.popen("sudo megacli -AdpGetPciInfo -aall").read()
for cont in getcontlist.strip().split("PCI information for"):
if cont and "Controller" in cont:
res = {}
for line in str(cont).split("\n"):
if re.search("Controller", line):
res["contid"] = line.split("Controller ")[1].strip()
elif re.search("Bus Number :", line):
bus_num = line.split("Bus Number : ")[1].strip()
if len(bus_num) == 1:
res["pci"] = "0{}:00.0".format(bus_num)
else:
res["pci"] = "{}:00.0".format(bus_num)
ControllerDict.append(res)
return ControllerDict
def Adaptec(self):
'''
[{"ContId":"0","PCI":"af:00.0"}]
'''
ContList = []
getcontlist = os.popen("sudo arcconf list").read()
for cont in re.findall("Controller \d+:", getcontlist):
ContId = re.findall("\d", cont)[0]
getcontinfo = os.popen(
"sudo arcconf getconfig %s ad" % (ContId)).read()
res = {"contid": ContId}
for line in str(getcontinfo).split("\n"):
if re.search("PCI Address", line):
PCI = line.split(":")[-3].strip()
# PCI = re.findall("PCI Address.*", getcontinfo)[0].split(":")[-3].strip()
if len(PCI) == 1:
res["pci"] = ("0%s:00.0" % (PCI))
else:
res["pci"] = ("%s:00.0" % (PCI))
ContList.append(res)
print(json.dumps(ContList))
return ContList
def Adaptec2(self):
ContList = []
ContId = 0
ret = os.popen("sudo lspci|grep -i Adaptec").read()
for cont in re.findall(".*SAS/PCIe 2.*", ret):
ContId = ContId + 1
PCI = re.split(":", cont)[0]
continfo = {}
continfo["contid"] = ContId
if len(PCI) == 1:
continfo["pci"] = ("0%s:00.0" % (PCI))
else:
continfo["pci"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
return ContList
def Sas(self):
ContList = []
try:
getcontlist = os.popen(
"sudo sas2ircu list|grep -i '^ *[0-9]'").read().strip()
for cont in re.split("\n", getcontlist):
continfo = {}
continfo["contid"] = cont.split()[0]
pciinfo = cont.split()[4]
PCI = re.split("h:", pciinfo)[1]
if len(PCI) == 1:
continfo["pci"] = ("0%s:00.0" % (PCI))
else:
continfo["pci"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
self.ContList = ContList
except Exception:
ContId = -1
ret = os.popen("sudo lspci|grep -i SAS").read()
for cont in re.findall(".*SAS.*", ret):
ContId = ContId + 1
PCI = re.split(":", cont)[0]
continfo = {}
continfo["contid"] = ContId
if len(PCI) == 1:
continfo["pci"] = ("0%s:00.0" % (PCI))
else:
continfo["pci"] = ("%s:00.0" % (PCI))
ContList.append(continfo)
return ContList
######################################################
# 数据获取
######################################################
# 数据记录
def saveFile(data, output=False):
PDList = data.get('PDList')
VDList = data.get('VDList')
if not os.path.exists(proc_dir):
os.mkdir(proc_dir)
OsCmd("sudo chmod 777 %s" % (proc_dir)).data()
OsCmd("sudo chmod 666 %s/*" % (proc_dir)).data()
# 保存vd pd 相关信息
diskinfofile = open(config["diskinfofilejs"], "w")
json.dump(data, diskinfofile)
diskinfofile.close()
# 保存pd和挂载点,磁盘信息
pdinfo = copy.deepcopy(PDList)
for vid in humanSort(VDList):
vd = VDList[vid]
pds = vd.get("PDs")
for p in pds:
pd = copy.deepcopy(p)
pd["Mount"] = vd["Mount"]
pd["diskName"] = vd["diskName"]
pd["VD"] = vid
pd["VDTYPE"] = vd["TYPE"]
pd["VDSIZE"] = vd["Size"]
pdinfo[pd["ACD"]] = pd
pdinfofile = open(config["pdinfofilejs"], "w")
json.dump(list(pdinfo.values()), pdinfofile)
pdinfofile.close()
if output:
print(json.dumps(list(pdinfo.values()), indent=4))
# 获取raid卡类型
def getRaidtype():
# 获取raid卡型号
try:
getPci = OsCmd(
'sudo lspci |grep -i -E " SAS|Adaptec|LSI|Gen9|raid"').data()
except Exception:
raise RaidError(
"The raid card model is not suitable, or there is no raid card", "127")
Kernel_drivers = []
pciList = getPci.split('\n')
for pci in pciList:
pci_id = pci.split(" ")[0]
kernel_driver = OsCmd(
"sudo lspci -v -s %s |awk -F ':' '/Kernel driver in use/{ print $NF }'" % (pci_id)).data()
Kernel_drivers.append(kernel_driver)
driver = list(set(Kernel_drivers))
if "MegaRAID" in getPci or "megaraid_sas" in driver:
raidType = "megacli"
elif ('Adaptec' in getPci and "PCIe 2" in getPci) or "aacraid" in driver:
raidType = "arcconf2"
elif 'Adaptec' in getPci or "smartpqi" in driver:
raidType = "arcconf"
elif 'LSI' in getPci or "mpt2sas" in driver:
raidType = "sas2icu"
elif 'Gen9' in getPci:
raidType = "ssacli"
elif "mpt3sas" in driver:
raidType = "storcli"
raise RaidError(
"storcli Unadapted", "127")
else:
raise RaidError("other err", "124")
return raidType
# 获取vd pd等输出信息
def get_vd_pd_info(output=False):
raidType = getRaidtype()
data = {}
if raidType == "megacli":
raid = MegaCli()
elif raidType == "arcconf2":
raid = Arcconf2()
elif raidType == "arcconf":
raid = Arcconf()
elif raidType == "sas2icu":
raid = Sas2icu()
elif raidType == "ssacli":
raid = Ssacli()
else:
raise RaidError(
"The raid card model is not suitable, or there is no raid card", "127")
# 获取信息
if not raid.VDList:
VDList = raid.get_VD_List()
else:
VDList = raid.VDList
if not raid.PDList:
PDList = raid.get_PD_List()
else:
PDList = raid.PDList
# 获取不在vd重点pd
OtherPdList = {}
vdpd = []
for vdinfo in humanSort(VDList):
vd = VDList[vdinfo]
for pd in vd["PDs"]:
vdpd.append(pd["ACD"])
for key in humanSort(PDList):
pd = PDList[key]
if pd["ACD"] not in vdpd:
OtherPdList[pd["ACD"]] = pd
data["VDList"] = VDList
data["PDList"] = PDList
data["OtherPdList"] = OtherPdList
data["raidType"] = raidType
saveFile(data, output=output)
return data
######################################################
# 功能
######################################################
# 故障盘亮灯
def faultOnBlink():
data = get_vd_pd_info()
PDList = data.get('PDList')
VDList = data.get('VDList')
OtherPdList = data.get('OtherPdList')
Blink = AutoBlink()
pdAutoBlinkList = Blink.pdAutoBlink(VDList, OtherPdList)
DropDiskAutoBlinkList = Blink.DropDiskAutoBlink(PDList)
pdBlinkNum = []
if pdAutoBlinkList:
print("以下《 %s 》块盘故障, 更换时请按照硬件变更工单进行更换。" % (len(pdAutoBlinkList)))
for pd in pdAutoBlinkList:
Blink.onBlink(acd=pd.get("ACD"), pd=pd)
pdBlinkNum.append(pd.get("ACD"))
# 判断其他pd报错,例如掉盘进行亮灯
if DropDiskAutoBlinkList:
print("以下盘, slot号不连续,中间有掉盘, 两侧灯已亮, 更换中间一块,更换前请灭灯确认")
for pd in DropDiskAutoBlinkList:
Blink.onBlink(pd["ACD"])
pdBlinkNum.append(pd.get("ACD"))
if not pdBlinkNum:
print("不满足自动亮灯要求,请人工进行亮灯")
# 记录自动亮灯信息
blinkfile = open("/tmp/diskerr/blink", "w")
json.dump(pdBlinkNum, blinkfile)
blinkfile.close()
OsCmd("sudo chmod 666 /tmp/diskerr/*").data()
# 自助亮灯
def onBlink(acd):
Blink = AutoBlink()
Blink.onBlink(acd)
# 故障盘灭灯
def faultOffBlink():
if os.path.exists("/tmp/diskerr/blink"):
blinkfile = open("/tmp/diskerr/blink", "r")
blink = json.load(blinkfile)
blinkfile.close()
if blink:
Blink = AutoBlink()
for pd in blink:
acd = str(pd)
Blink.offBlink(acd)
else:
print("无自动亮灯的盘, 无法进行自动灭灯")
else:
print("非自动亮灯, 无法自动灭灯")
exit(0)
# 自助灭灯
def offBlink(acd):
Blink = AutoBlink()
Blink.offBlink(acd)
# 记录可以更换的报错盘信息,用于判断更换了那块盘
def recordPdErr():
data = get_vd_pd_info()
PDList = data.get('PDList')
VDList = data.get('VDList')
OtherPdList = data.get('OtherPdList')
Blink = AutoBlink()
pdAutoBlinkList = Blink.pdAutoBlink(VDList, OtherPdList)
DropDiskAutoBlinkList = Blink.DropDiskAutoBlink(PDList)
model = ""
for pd in DropDiskAutoBlinkList:
if pd["Model"] == model:
pdAutoBlinkList.append(pd)
model == pd["Model"]
if os.path.exists(config["replacefile"]):
OsCmd("cp %s %s" % (config["replacefile"],
config["replaceagofile"])).data()
replacefile = open(config["replacefile"], "w")
json.dump(pdAutoBlinkList, replacefile)
replacefile.close()
# 日常巡检
class inspect():
def __init__(self, cmdtype="nss"):
self.inspect(cmdtype)
pass
# 巡检舒服报错信息
def inspect(self, cmdtype):
# 巡检
dict = get_vd_pd_info()
PDList = dict.get('PDList')
VDList = dict.get('VDList')
OtherPdList = dict.get('OtherPdList')
raidType = dict["raidType"]
msg = {"state": 0, "media_err": 0, "other_err": 0,
"failuer": 0, "wearout": 100, "dropDiskNum": 0, "erradd": 0, "errtotal": 0}
FaultDisk = FaultDiskInfo()
vd_msg, vd_data = FaultDisk.getFaultVirDisk(VDList)
pd_msg, pd_data = FaultDisk.getFailedPD(OtherPdList)
dD_msg, dD_data = FaultDisk.getDropDisk(PDList)
# errtotal
msg["errtotal"] = int(vd_msg["errtotal"]) + int(pd_msg["errtotal"])
# 状态
msg["state"] = int(vd_msg["state"]) + int(pd_msg["state"])
# media_err
if int(vd_msg["media_err"]) > int(pd_msg["media_err"]):
msg["media_err"] = int(vd_msg["media_err"])
else:
msg["media_err"] = int(pd_msg["media_err"])
# other_err
if int(vd_msg["other_err"]) > int(pd_msg["other_err"]):
msg["other_err"] = int(vd_msg["other_err"])
else:
msg["other_err"] = int(pd_msg["other_err"])
# failuer"
if int(vd_msg["failuer"]) > int(pd_msg["failuer"]):
msg["failuer"] = int(vd_msg["failuer"])
else:
msg["failuer"] = int(pd_msg["failuer"])
# wearout"
if int(vd_msg["wearout"]) < int(pd_msg["wearout"]):
msg["wearout"] = int(vd_msg["wearout"])
else:
msg["wearout"] = int(pd_msg["wearout"])
# 掉盘
msg["dropDiskNum"] = int(dD_msg["dropDiskNum"])
data = {"VD": vd_data, "PD": pd_data, "dropPD": dD_data, "msg": msg}
# 判断报错值是否进行增加
msg["erradd"] = self.errReport(data)
if cmdtype == "nss":
# 巡检输出报错信息
print("==check_disk")
print("state=%d,mediaErr=%d,otherErr=%d,failuer=%d,dropDiskNum=%d,erradd=%d,wearout=%d" % (
msg["state"], msg["media_err"], msg["other_err"], msg["failuer"], msg["dropDiskNum"], msg["erradd"], msg["wearout"]))
print("raid: %s" % (raidType))
if data.get("VD"):
for vid in data.get("VD"):
vd = data["VD"][vid]
print("\n%s %s Disk failure. The failure information is as follows:" % (
vd["diskName"], vd["Mount"]))
FormatOutput().vdout(vd)
if data.get("PD"):
for pid in data.get("PD"):
pd = data["PD"][pid]
print("\n%s 物理盘有报错,报错信息如下: " % (pd["ACD"]))
FormatOutput().pdout(pd)
if data.get("dropPD"):
print("\n以下盘槽位号不连续,中间可能有掉盘:")
for pid in data.get("dropPD"):
pd = data["dropPD"][pid]
FormatOutput().pdout(pd)
if cmdtype != "nss":
if data.get("VD") or data.get("VD") or data.get("dropPD"):
exit(1)
# 判断故障是否累加
def errReport(self, data):
# 保存故障盘信息
erradd = 0
try:
# 保存报错信息
new_pd_errf = config["pderrfile"] + "." + \
datetime.date.today().strftime('%Y%m%d')
pderrfile = open(new_pd_errf, "w")
json.dump(data, pderrfile)
pderrfile.close()
# 删除10天前的文件
deldate = (datetime.datetime.today() - datetime.timedelta(days=10))
fileDateList = OsCmd(
"ls %s*|awk -F '.' '/pderr/{print $2}'|sort -n" % (config["pderrfile"])).data().split("\n")
for d in fileDateList:
if parse_time(d) < deldate:
delfile = config["pderrfile"] + "."+d
os.remove(delfile)
else:
break
# 读取以前的报错pd
old_data_file = config["pderrfile"] + "." + (
datetime.date.today() - datetime.timedelta(days=7)).strftime("%Y%m%d")
if os.path.exists(old_data_file):
old_data_js = open(old_data_file, "r")
old_data = json.load(old_data_js)
old_data_js.close()
else:
old_data = {}
# 判断报错信息是否增加
if data.get("msg") and old_data.get("msg"):
# 如果以上都不为空
errtotal = data.get("msg").get("errtotal")
old_errtotal = old_data.get("msg").get("errtotal")
if int(errtotal) > int(old_errtotal):
erradd = int(errtotal) - int(old_errtotal)
return erradd
except Exception:
pass
# raise RaidError("{} command ERR".format(self.cmd), "125")
return erradd
# 查看所有盘数据
def checkDisk():
dict = get_vd_pd_info()
VDList = dict.get('VDList')
OtherPdList = dict.get('OtherPdList')
forOut = FormatOutput()
for vdinfo in humanSort(VDList):
vd = VDList[vdinfo]
forOut.vdout(vd, sign=True)
if OtherPdList:
print("== == == 未做raid的盘 == == ==")
for key in humanSort(OtherPdList):
pd = OtherPdList[key]
forOut.pdout(pd)
# 获取磁盘详细信息,输出json
def diskDetail():
get_vd_pd_info(output=True)
# 删除vd
def deleteVD(AV=''):
# print(re.findall("/a\\d+/c\\d+I\\d+/d\\d+", acd))
if not AV:
raise RaidError("Please enter the correct VD number", "127")
elif not re.findall("/a\\d+/v\\d+", AV):
raise RaidError(
"Please enter the correct VD number format: /a0/v1", "127")
raidType = getRaidtype()
aid = re.findall("/a\\d+", AV)[0].replace("/a", '').strip()
vid = re.findall("/v\\d+", AV)[0].replace("/v", '').strip()
VDList={}
if os.path.exists(config["diskinfofilejs"]):
oneDayAgo = (datetime.datetime.today() - datetime.timedelta(days=10))
fileModificationTime =datetime.datetime.fromtimestamp(os.stat(config["diskinfofilejs"]).st_mtime)
if fileModificationTime >= oneDayAgo :
f = open(config["diskinfofilejs"], "r")
diskinfo = humanJson.load(f)
f.close()
VDList = diskinfo.get("VDList", {})
else:
data = get_vd_pd_info()
VDList = data.get('VDList',{})
else:
data = get_vd_pd_info()
VDList = data.get('VDList',{})
if str(AV) not in VDList:
print("未找到此VD信息,请人工确认")
exit(0)
vdinfo = VDList.get(AV)
if vdinfo.get("Mount") is None:
if raidType == "megacli":
ret = OsCmd(" sudo megacli -cfglddel -l%s -a%s" % (vid, aid)).data()
print(ret)
else:
print("未适配自动亮灯")
exit(0)
else:
print("指定vd包含有挂载点")
if __name__ == "__main__":
try:
try:
import argparse
parser = argparse.ArgumentParser()
# 创建互斥组,是命令每次只能输入一个选项
group = parser.add_mutually_exclusive_group()
group.add_argument("-i", '--inspect', dest='inspect', required=False,
action='store_true', default="True", help="默认选项, 输出==check_disk故障信息")
group.add_argument("-I", '--inspecttype', dest='inspecttype',
action='store_true', help="输出故障信息")
group.add_argument("-c", '--checkdisk', dest='checkdisk',
action='store_true', help="输出所有的pd和vd信息")
group.add_argument("-o", '--onblink', metavar="/an/cn/dn", nargs="?",
default="False", type=str, help="进行亮灯, 当不指定参数时只进行故障盘亮灯, 指定参数时进行指定的盘亮灯.")
group.add_argument("-f", '--offblink', metavar="/an/cn/dn", nargs="?",
default="False", type=str, help="进行灭灯, 当不指定参数时只灭自动亮的灯, 指定参数时进行指定盘灭灯.")
group.add_argument("-r", '--recordpderr', dest='record',
action='store_true', help="记录报错盘信息")
group.add_argument("-d", '--diskdetail', dest='diskdetail',
action='store_true', help="格式化输出磁盘详细信息")
group.add_argument("-delvd", metavar="/an/vn", nargs="?", dest='deletevd',default="False", type=str, help="删除指定vd")
args = parser.parse_args()
# 选项参数执行的结果
if args.checkdisk: # -c 获取磁盘信息
checkDisk()
exit(0)
elif args.record: # -r 记录报错盘信息
recordPdErr()
exit(0)
elif args.inspecttype: # -r 记录报错盘信息
inspect(cmdtype="instruct")
elif args.onblink is None:
# print("故障盘亮灯")
faultOnBlink()
exit(0)
elif args.onblink != "False":
# print("指定的盘亮灯")
onBlink(args.onblink)
exit(0)
elif args.offblink is None:
# print("故障盘灭灯")
faultOffBlink()
elif args.offblink != "False":
# print("指定的盘灭灯")
offBlink(args.offblink)
elif args.diskdetail:
# 输出json
diskDetail()
elif args.deletevd != "False" and args.deletevd:
deleteVD(args.deletevd)
elif args.inspect:
inspect()
except Exception:
if len(sys.argv) == 1:
inspect()
elif len(sys.argv) == 2:
opt = sys.argv[1]
if opt == "-i":
inspect()
elif opt == "-I":
inspect(cmdtype="instruct")
elif opt == "-c":
checkDisk()
elif opt == "-r":
recordPdErr()
elif opt == "-o":
faultOnBlink()
elif opt == "-f":
faultOffBlink()
elif opt == "-d":
diskDetail()
elif len(sys.argv) == 3:
opt = sys.argv[1]
par = sys.argv[2]
print(par)
if opt == "-o":
onBlink(par)
if opt == "-f":
offBlink(par)
if opt == "-delvd":
deleteVD(par)
else:
raise RaidError("Please specify correct parameters", "127")
except Exception:
res = {
"code": 1,
"msg": traceback.format_exc(),
"data": []
}
print(traceback.format_exc())
TCP计数器
用法如下:
$ python nstat.py
{"tcpext": [{"name": "TcpExtSyncookiesSent", "value": 0}, {"name": "TcpExtListenOverflows", "value": 1211}, {"name": "TcpExtListenDrops", "value": 1211}, {"name": "TcpExtTCPTimeouts", "value": 76853}], "udp": [{"name": "UdpInDatagrams", "value": 321965497}, {"name": "UdpNoPorts", "value": 0}, {"name": "UdpOutDatagrams", "value": 322459373}], "tcp": [{"name": "TcpActiveOpens", "value": 3066741}, {"name": "TcpPassiveOpens", "value": 15037070}, {"name": "TcpAttemptFails", "value": 1189}, {"name": "TcpEstabResets", "value": 23215}, {"name": "TcpRetransSegs", "value": 126661}, {"name": "TcpInErrs", "value": 4}, {"name": "TcpOutRsts", "value": 10787}]}
完整代码如下:
#!/usr/bin/env python
# coding: utf-8
import subprocess, shlex
import re, json
from StringIO import StringIO
TCP_METRICS = ["TcpActiveOpens", "TcpPassiveOpens", "TcpAttemptFails", "TcpEstabResets",
"TcpRetransSegs", "TcpInErrs", "TcpOutRsts"]
TCPEXT_METRICS = ["TcpExtTCPTimeouts", "TcpExtListenDrops", "TcpExtListenOverflows", "TcpExtSyncookiesSent"]
UDP_METRICS = ["UdpInDatagrams", "UdpOutDatagrams", "UdpNoPorts"]
def get_nstat():
tcp_data = []
tcpext_data = []
udp_data = []
cmd = "nstat -z"
p = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
(output, err) = p.communicate()
f = StringIO(output)
for line in f.readlines():
if line.startswith("#kernel"):
continue
metric, value, placeholder = map(str.strip, re.split('\s+', line.strip()))
if metric in TCP_METRICS:
tcp_data.append({"name": metric, "value": int(value)})
elif metric in TCPEXT_METRICS:
tcpext_data.append({"name": metric, "value": int(value)})
elif metric in UDP_METRICS:
udp_data.append({"name": metric, "value": int(value)})
f.close()
return tcp_data, tcpext_data, udp_data
if __name__ == "__main__":
res_data = {}
tcp_data, tcpext_data, udp_data = get_nstat()
nss_data["tcp"] = tcp_data
nss_data["tcpext"] = tcpext_data
nss_data["udp"] = udp_data
print json.dumps(res_data)