-
Notifications
You must be signed in to change notification settings - Fork 0
/
lsbackplane
executable file
·162 lines (118 loc) · 4.26 KB
/
lsbackplane
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env python
"""
Enumerate_Backplanes - create an easy-to-use table to reference backplanes
"""
import re
import os
import sys
import math
import time
from subprocess import Popen, PIPE, STDOUT
from prettytable import PrettyTable
# Cache info
CacheDataArray = {}
CacheTimeArray = {}
# Enable/disable debugging messages
Print_Debug = False
def Debug(text):
"""
A wrapper to print debugging info on a single line.
"""
if Print_Debug:
print("DEBUG: " + text)
return
def SysExec(cmd):
"""
Run the given command and return the output
"""
Debug("SysExec:: cmd = " + str(cmd))
# Cache the output of the command for 20 seconds
Cache_Expires = 20
# Computed once, used twice
Cache_Keys = list(CacheDataArray.keys())
if cmd in Cache_Keys:
Cache_Age = time.time() - CacheTimeArray[cmd]
else:
Cache_Age = 0
Return_Val = "ERROR"
# If we have valid data cached, return it
if cmd in Cache_Keys and Cache_Age < Cache_Expires:
Return_Val = CacheDataArray[cmd]
# If the cmd is "cat", use fopen/fread/fclose to open it and
# cache it as we go
elif not cmd in Cache_Keys and cmd.split()[0] == "cat":
f = open(cmd.split()[1], "r")
CacheDataArray[cmd] = f.read()
CacheTimeArray[cmd] = time.time()
f.close()
Return_Val = CacheDataArray[cmd]
# If we don't have cached data, or it's too old, regenerate it
elif not cmd in Cache_Keys or Cache_Age > Cache_Expires:
CacheDataArray[cmd] = Popen(cmd.split(), stdout=PIPE, stderr=STDOUT).communicate()[0]
CacheTimeArray[cmd] = time.time()
Return_Val = CacheDataArray[cmd]
if str(type(Return_Val)) == "<class 'bytes'>":
Return_Val = Return_Val.decode("utf-8")
return Return_Val
def List_Enclosures():
"""
List enclosures.
"""
# Our current depots have 24 slots on the Front backplane and 12 on the Rear
# In a more complex setup, we might need a more cumbersome way to alias backplanes
Alias_by_NumSlots = {}
Alias_by_NumSlots["30"] = "Valiant"
Alias_by_NumSlots["36"] = "Unified"
Alias_by_NumSlots["24"] = "Front"
Alias_by_NumSlots["12"] = "Back"
# Array to hold the output for pretty printing
Output = []
Enclosure_Raw = SysExec("lsscsi -g")
for line in Enclosure_Raw.splitlines():
if not re.search("enclosu", line):
continue
if re.search("VirtualSES", line):
continue
Debug("line = " + line)
SG_Dev = line.split()[-1]
Debug("List_Enclosures:: SG_Dev = " + str(SG_Dev))
HCTL = line.split()[0]
HCTL = re.sub("\[", "", HCTL)
HCTL = re.sub("\]", "", HCTL)
Debug("List_Enclosures:: HCTL = " + str(HCTL))
SAS_Addr = "UNKNOWN_SAS"
SAS_Addr_Raw = SysExec("sg_ses --page=aes " + SG_Dev)
for text in SAS_Addr_Raw.splitlines():
if re.search("Primary enclosure logical identifier", text):
SAS_Addr = text.split(":")[1]
SAS_Addr = re.sub(" ", "", SAS_Addr)
Debug("List_Enclosures:: SAS_Addr = " + str(SAS_Addr))
Num_Slots = "UNKNOWN_SLOTS"
Num_Slots_Raw = SysExec("sg_ses --page=cf " + SG_Dev).splitlines()
for index, line in enumerate(Num_Slots_Raw):
if re.search("Array device slot", line):
raw = Num_Slots_Raw[index + 1].split(":")[-1]
Num_Slots = re.sub(" ", "", raw)
Debug("List_Enclosures:: Num_Slots = " + str(Num_Slots))
Alias = "UNKNOWN_ALIAS"
if Num_Slots in Alias_by_NumSlots:
Alias = Alias_by_NumSlots[Num_Slots]
if Alias == "Valiant":
Alias = "Valiant_" + HCTL.split(":")[0]
Output.append([SG_Dev, Num_Slots, HCTL, SAS_Addr, Alias])
Debug("List_Enclosures::Output = " + str(Output))
return(Output)
Enclosures = List_Enclosures()
### At least until I change my mind, I only want to print each backplane
### once. So look at HCTL and only print info on the lowest SCSI host adapter
min_host = 99999
for row in Enclosures:
min_host = min(min_host, int(row[2].split(":")[0]))
x = PrettyTable(["SG_Dev", "Num_Slots", "HCTL", "SAS_Addr", "Alias"])
x.padding_width = 1
for row in Enclosures:
# h = int(row[2].split(":")[0])
# if min_host == h:
# x.add_row(row)
x.add_row(row)
print(x)