4 class SpdkTailqList(object):
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
)
13 curr
= self
.list['tqh_first']
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']
21 class SpdkNormalTailqList(SpdkTailqList
):
23 def __init__(self
, list_pointer
, list_member
):
24 super(SpdkNormalTailqList
, self
).__init
__(list_pointer
, list_member
,
28 class SpdkArr(object):
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
36 for i
in range(0, self
.num_elements
):
37 curr
= (self
.arr_pointer
+ i
).dereference()
40 yield self
.element_type(curr
)
43 class SpdkPrintCommand(gdb
.Command
):
45 def __init__(self
, name
, element_list
):
46 self
.element_list
= element_list
47 gdb
.Command
.__init
__(self
, name
,
52 def print_element_list(self
, element_list
):
54 for element
in element_list
:
58 print("---------------")
59 print("\n" + str(element
) + "\n")
61 def invoke(self
, arg
, from_tty
):
62 self
.print_element_list(self
.element_list
)
65 class SpdkObject(object):
67 def __init__(self
, gdb_obj
):
71 return self
.obj
['name']
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()
80 class IoDevice(SpdkObject
):
82 type_name
= 'struct io_device'
85 class IoDevices(SpdkTailqList
):
88 super(IoDevices
, self
).__init
__('g_io_devices', IoDevice
, ['tailq'])
91 class spdk_print_io_devices(SpdkPrintCommand
):
94 io_devices
= IoDevices()
95 name
= 'spdk_print_io_devices'
96 super(spdk_print_io_devices
, self
).__init
__(name
, io_devices
)
99 class Bdev(SpdkObject
):
101 type_name
= 'struct spdk_bdev'
104 class BdevMgrBdevs(SpdkTailqList
):
107 tailq_name_list
= ['internal', 'link']
108 super(BdevMgrBdevs
, self
).__init
__('g_bdev_mgr->bdevs', Bdev
, tailq_name_list
)
111 class spdk_print_bdevs(SpdkPrintCommand
):
112 name
= 'spdk_print_bdevs'
115 bdevs
= BdevMgrBdevs()
116 super(spdk_print_bdevs
, self
).__init
__(self
.name
, bdevs
)
119 class spdk_find_bdev(spdk_print_bdevs
):
121 name
= 'spdk_find_bdev'
123 def invoke(self
, arg
, from_tty
):
125 bdev_query
= [bdev
for bdev
in self
.element_list
126 if str(bdev
.get_name()).find(arg
) != -1]
128 print("Cannot find bdev with name %s" % arg
)
131 self
.print_element_list(bdev_query
)
134 class NvmfSubsystem(SpdkObject
):
136 type_name
= 'struct spdk_nvmf_subsystem'
138 def __init__(self
, ptr
):
140 gdb_obj
= self
.ptr
.cast(gdb
.lookup_type(self
.type_name
).pointer())
141 super(NvmfSubsystem
, self
).__init
__(gdb_obj
)
144 return self
.obj
['subnqn']
147 return int(self
.obj
['id'])
149 def get_ns_list(self
):
150 max_nsid
= int(self
.obj
['max_nsid'])
152 for i
in range(0, max_nsid
):
153 nsptr
= (self
.obj
['ns'] + i
).dereference()
156 ns
= nsptr
.cast(gdb
.lookup_type('struct spdk_nvmf_ns').pointer())
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():
169 class SpdkNvmfTgtSubsystems(SpdkArr
):
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'])
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(),
185 class spdk_print_nvmf_subsystems(SpdkPrintCommand
):
188 name
= 'spdk_print_nvmf_subsystems'
189 nvmf_tgt_subsystems
= SpdkNvmfTgtSubsystems()
190 super(spdk_print_nvmf_subsystems
, self
).__init
__(name
, nvmf_tgt_subsystems
)
193 class IoChannel(SpdkObject
):
195 type_name
= 'struct spdk_io_channel'
199 return int(self
.obj
['ref'])
201 def get_device(self
):
202 return self
.obj
['dev']
204 def get_device_name(self
):
205 return self
.obj
['dev']['name']
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())
217 # TODO - create TailqList type that gets a gdb object instead of a pointer
218 class IoChannels(SpdkTailqList
):
220 def __init__(self
, list_obj
):
221 self
.tailq_name_list
= ['tailq']
222 self
.list_member
= IoChannel
226 class SpdkThread(SpdkObject
):
228 type_name
= 'struct spdk_thread'
230 def __init__(self
, gdb_obj
):
231 super(SpdkThread
, self
).__init
__(gdb_obj
)
232 self
.io_channels
= IoChannels(self
.obj
['io_channels'])
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 '')
241 s
+= '\t---------------\n'
245 def get_io_channels(self
):
246 return self
.io_channels
249 class SpdkThreads(SpdkNormalTailqList
):
252 super(SpdkThreads
, self
).__init
__('g_threads', SpdkThread
)
255 class spdk_print_threads(SpdkPrintCommand
):
258 name
= "spdk_print_threads"
259 threads
= SpdkThreads()
260 super(spdk_print_threads
, self
).__init
__(name
, threads
)
263 class spdk_load_macros(gdb
.Command
):
266 gdb
.Command
.__init
__(self
, 'spdk_load_macros',
272 def invoke(self
, arg
, from_tty
):
273 if arg
== '--reload':
274 print('Reloading spdk information')
279 if self
.loaded
and not reload:
284 spdk_print_io_devices()
285 spdk_print_nvmf_subsystems()