-
Notifications
You must be signed in to change notification settings - Fork 4
/
storcli.py
93 lines (78 loc) · 4.65 KB
/
storcli.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
import subprocess as sp
import os
import json
from typing import Dict
STORCLI_EXEC = "/opt/MegaRAID/storcli/storcli64"
if not os.path.exists(STORCLI_EXEC):
STORCLI_EXEC = "storcli"
class StorCliBase:
def __init__(self):
# self check
output = self.run(["/c0", "show", "nolog"])
status = output["Controllers"][0]["Command Status"]["Status"]
if status != "Success":
raise RuntimeError(
"Self-check failed. Did you run this script with root? (Controller status gets {} rather than 'Success')".format(
status
)
)
def run(self, args: list):
# Get JSON output
ret = sp.run([STORCLI_EXEC, *args, "J"], stdout=sp.PIPE)
if ret.returncode != 0:
raise RuntimeError("storcli returns a non-zero value.")
return json.loads(ret.stdout)
def get_physical_disk_info(self):
return self.run(["/call", "/eall", "/sall", "show", "all", "nolog"])
storcli = StorCliBase()
def update_dict(dict: Dict, key, value_dict) -> None:
if key not in dict:
dict[key] = value_dict
else:
dict[key].update(value_dict)
def get_disk_errors() -> dict:
pdinfo = storcli.get_physical_disk_info()["Controllers"]
info = {}
for adapter in pdinfo:
adapter_id = adapter["Command Status"]["Controller"]
adapter_info: Dict[str, Dict] = {}
adapter_response = adapter["Response Data"]
for key in adapter_response:
if "Detailed Information" in key:
disk = key.split("-")[0].strip()
state = adapter_response[key][disk + " State"]
media_error = int(state["Media Error Count"])
other_error = int(state["Other Error Count"])
predictive_failure = int(state["Predictive Failure Count"])
smart = state["S.M.A.R.T alert flagged by drive"]
update_dict(
adapter_info,
disk,
{
"media_error": media_error,
"other_error": other_error,
"predictive_failure": predictive_failure,
"smart_alert": smart,
},
)
else:
drive_info = adapter_response[key][0] # WHY THIS IS A LIST???
state = drive_info["State"]
spin = drive_info["Sp"]
firmware_state = "{state}, Spun {spin}".format(
state=state, spin="Up" if spin == "U" else "Down"
)
update_dict(
adapter_info,
key,
{
"firmware": firmware_state,
},
)
info[adapter_id] = adapter_info
return info
if __name__ == "__main__":
print(get_disk_errors())
# Return example:
# {0: {'Drive /c0/e252/s0': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c0/e252/s1': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c0/e252/s4': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c0/e252/s5': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c0/e252/s6': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c0/e252/s7': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}}, 1: {'Drive /c1/e252/s0': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c1/e252/s1': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c1/e252/s2': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c1/e252/s3': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c1/e252/s4': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c1/e252/s5': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}, 'Drive /c1/e252/s6': {'firmware': 'Onln, Spun Up', 'media_error': 0, 'other_error': 0, 'predictive_failure': 0, 'smart_alert': 'No'}}}