]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/scripts/gdb_macros.py
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / scripts / gdb_macros.py
1 import gdb
2
3
4 class SpdkTailqList(object):
5
6 def __init__(self, list_pointer, list_member, tailq_name_list):
7 self.list_pointer = list_pointer
8 self.tailq_name_list = tailq_name_list
9 self.list_member = list_member
10 self.list = gdb.parse_and_eval(self.list_pointer)
11
12 def __iter__(self):
13 curr = self.list['tqh_first']
14 while curr:
15 yield self.list_member(curr)
16 for tailq_name in self.tailq_name_list:
17 curr = curr[tailq_name]
18 curr = curr['tqe_next']
19
20
21 class SpdkNormalTailqList(SpdkTailqList):
22
23 def __init__(self, list_pointer, list_member):
24 super(SpdkNormalTailqList, self).__init__(list_pointer, list_member,
25 ['tailq'])
26
27
28 class SpdkArr(object):
29
30 def __init__(self, arr_pointer, num_elements, element_type):
31 self.arr_pointer = arr_pointer
32 self.num_elements = num_elements
33 self.element_type = element_type
34
35 def __iter__(self):
36 for i in range(0, self.num_elements):
37 curr = (self.arr_pointer + i).dereference()
38 if (curr == 0x0):
39 continue
40 yield self.element_type(curr)
41
42
43 class SpdkPrintCommand(gdb.Command):
44
45 def __init__(self, name, element_list):
46 self.element_list = element_list
47 gdb.Command.__init__(self, name,
48 gdb.COMMAND_DATA,
49 gdb.COMPLETE_SYMBOL,
50 True)
51
52 def print_element_list(self, element_list):
53 first = True
54 for element in element_list:
55 if first:
56 first = False
57 else:
58 print("---------------")
59 print("\n" + str(element) + "\n")
60
61 def invoke(self, arg, from_tty):
62 self.print_element_list(self.element_list)
63
64
65 class SpdkObject(object):
66
67 def __init__(self, gdb_obj):
68 self.obj = gdb_obj
69
70 def get_name(self):
71 return self.obj['name']
72
73 def __str__(self):
74 s = "SPDK object of type %s at %s" % (self.type_name, str(self.obj))
75 s += '\n((%s*) %s)' % (self.type_name, str(self.obj))
76 s += '\nname %s' % self.get_name()
77 return s
78
79
80 class IoDevice(SpdkObject):
81
82 type_name = 'struct io_device'
83
84
85 class IoDevices(SpdkTailqList):
86
87 def __init__(self):
88 super(IoDevices, self).__init__('g_io_devices', IoDevice, ['tailq'])
89
90
91 class spdk_print_io_devices(SpdkPrintCommand):
92
93 def __init__(self):
94 io_devices = IoDevices()
95 name = 'spdk_print_io_devices'
96 super(spdk_print_io_devices, self).__init__(name, io_devices)
97
98
99 class Bdev(SpdkObject):
100
101 type_name = 'struct spdk_bdev'
102
103
104 class BdevMgrBdevs(SpdkTailqList):
105
106 def __init__(self):
107 tailq_name_list = ['internal', 'link']
108 super(BdevMgrBdevs, self).__init__('g_bdev_mgr->bdevs', Bdev, tailq_name_list)
109
110
111 class spdk_print_bdevs(SpdkPrintCommand):
112 name = 'spdk_print_bdevs'
113
114 def __init__(self):
115 bdevs = BdevMgrBdevs()
116 super(spdk_print_bdevs, self).__init__(self.name, bdevs)
117
118
119 class spdk_find_bdev(spdk_print_bdevs):
120
121 name = 'spdk_find_bdev'
122
123 def invoke(self, arg, from_tty):
124 print(arg)
125 bdev_query = [bdev for bdev in self.element_list
126 if str(bdev.get_name()).find(arg) != -1]
127 if bdev_query == []:
128 print("Cannot find bdev with name %s" % arg)
129 return
130
131 self.print_element_list(bdev_query)
132
133
134 class NvmfSubsystem(SpdkObject):
135
136 type_name = 'struct spdk_nvmf_subsystem'
137
138 def __init__(self, ptr):
139 self.ptr = ptr
140 gdb_obj = self.ptr.cast(gdb.lookup_type(self.type_name).pointer())
141 super(NvmfSubsystem, self).__init__(gdb_obj)
142
143 def get_name(self):
144 return self.obj['subnqn']
145
146 def get_id(self):
147 return int(self.obj['id'])
148
149 def get_ns_list(self):
150 max_nsid = int(self.obj['max_nsid'])
151 ns_list = []
152 for i in range(0, max_nsid):
153 nsptr = (self.obj['ns'] + i).dereference()
154 if nsptr == 0x0:
155 continue
156 ns = nsptr.cast(gdb.lookup_type('struct spdk_nvmf_ns').pointer())
157 ns_list.append(ns)
158 return ns_list
159
160 def __str__(self):
161 s = super(NvmfSubsystem, self).__str__()
162 s += '\nnqn %s' % self.get_name()
163 s += '\nID %d' % self.get_id()
164 for ns in self.get_ns_list():
165 s + '\t%s' % str(ns)
166 return s
167
168
169 class SpdkNvmfTgtSubsystems(SpdkArr):
170
171 def get_num_subsystems(self):
172 try: # version >= 18.11
173 return int(self.spdk_nvmf_tgt['max_subsystems'])
174 except RuntimeError: # version < 18.11
175 return int(self.spdk_nvmf_tgt['opts']['max_subsystems'])
176
177 def __init__(self):
178 self.spdk_nvmf_tgt = gdb.parse_and_eval("g_spdk_nvmf_tgt")
179 subsystems = gdb.parse_and_eval("g_spdk_nvmf_tgt->subsystems")
180 super(SpdkNvmfTgtSubsystems, self).__init__(subsystems,
181 self.get_num_subsystems(),
182 NvmfSubsystem)
183
184
185 class spdk_print_nvmf_subsystems(SpdkPrintCommand):
186
187 def __init__(self):
188 name = 'spdk_print_nvmf_subsystems'
189 nvmf_tgt_subsystems = SpdkNvmfTgtSubsystems()
190 super(spdk_print_nvmf_subsystems, self).__init__(name, nvmf_tgt_subsystems)
191
192
193 class IoChannel(SpdkObject):
194
195 type_name = 'struct spdk_io_channel'
196
197 def get_ref(self):
198
199 return int(self.obj['ref'])
200
201 def get_device(self):
202 return self.obj['dev']
203
204 def get_device_name(self):
205 return self.obj['dev']['name']
206
207 def get_name(self):
208 return ""
209
210 def __str__(self):
211 s = super(IoChannel, self).__str__() + '\n'
212 s += 'ref %d\n' % self.get_ref()
213 s += 'device %s (%s)\n' % (self.get_device(), self.get_device_name())
214 return s
215
216
217 # TODO - create TailqList type that gets a gdb object instead of a pointer
218 class IoChannels(SpdkTailqList):
219
220 def __init__(self, list_obj):
221 self.tailq_name_list = ['tailq']
222 self.list_member = IoChannel
223 self.list = list_obj
224
225
226 class SpdkThread(SpdkObject):
227
228 type_name = 'struct spdk_thread'
229
230 def __init__(self, gdb_obj):
231 super(SpdkThread, self).__init__(gdb_obj)
232 self.io_channels = IoChannels(self.obj['io_channels'])
233
234 def __str__(self):
235 s = super(SpdkThread, self).__str__() + '\n'
236 s += "IO Channels:\n"
237 for io_channel in self.get_io_channels():
238 channel_lines = str(io_channel).split('\n')
239 s += '\n'.join('\t%s' % line for line in channel_lines if line is not '')
240 s += '\n'
241 s += '\t---------------\n'
242 s += '\n'
243 return s
244
245 def get_io_channels(self):
246 return self.io_channels
247
248
249 class SpdkThreads(SpdkNormalTailqList):
250
251 def __init__(self):
252 super(SpdkThreads, self).__init__('g_threads', SpdkThread)
253
254
255 class spdk_print_threads(SpdkPrintCommand):
256
257 def __init__(self):
258 name = "spdk_print_threads"
259 threads = SpdkThreads()
260 super(spdk_print_threads, self).__init__(name, threads)
261
262
263 class spdk_load_macros(gdb.Command):
264
265 def __init__(self):
266 gdb.Command.__init__(self, 'spdk_load_macros',
267 gdb.COMMAND_DATA,
268 gdb.COMPLETE_SYMBOL,
269 True)
270 self.loaded = False
271
272 def invoke(self, arg, from_tty):
273 if arg == '--reload':
274 print('Reloading spdk information')
275 reload = True
276 else:
277 reload = False
278
279 if self.loaded and not reload:
280 return
281
282 spdk_print_threads()
283 spdk_print_bdevs()
284 spdk_print_io_devices()
285 spdk_print_nvmf_subsystems()
286 spdk_find_bdev()
287
288
289 spdk_load_macros()