summaryrefslogtreecommitdiffstats
path: root/src/spdk/scripts/gdb_macros.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/spdk/scripts/gdb_macros.py')
-rw-r--r--src/spdk/scripts/gdb_macros.py289
1 files changed, 289 insertions, 0 deletions
diff --git a/src/spdk/scripts/gdb_macros.py b/src/spdk/scripts/gdb_macros.py
new file mode 100644
index 000000000..74234de7b
--- /dev/null
+++ b/src/spdk/scripts/gdb_macros.py
@@ -0,0 +1,289 @@
+import gdb
+
+
+class SpdkTailqList(object):
+
+ def __init__(self, list_pointer, list_member, tailq_name_list):
+ self.list_pointer = list_pointer
+ self.tailq_name_list = tailq_name_list
+ self.list_member = list_member
+ self.list = gdb.parse_and_eval(self.list_pointer)
+
+ def __iter__(self):
+ curr = self.list['tqh_first']
+ while curr:
+ yield self.list_member(curr)
+ for tailq_name in self.tailq_name_list:
+ curr = curr[tailq_name]
+ curr = curr['tqe_next']
+
+
+class SpdkNormalTailqList(SpdkTailqList):
+
+ def __init__(self, list_pointer, list_member):
+ super(SpdkNormalTailqList, self).__init__(list_pointer, list_member,
+ ['tailq'])
+
+
+class SpdkArr(object):
+
+ def __init__(self, arr_pointer, num_elements, element_type):
+ self.arr_pointer = arr_pointer
+ self.num_elements = num_elements
+ self.element_type = element_type
+
+ def __iter__(self):
+ for i in range(0, self.num_elements):
+ curr = (self.arr_pointer + i).dereference()
+ if (curr == 0x0):
+ continue
+ yield self.element_type(curr)
+
+
+class SpdkPrintCommand(gdb.Command):
+
+ def __init__(self, name, element_list):
+ self.element_list = element_list
+ gdb.Command.__init__(self, name,
+ gdb.COMMAND_DATA,
+ gdb.COMPLETE_SYMBOL,
+ True)
+
+ def print_element_list(self, element_list):
+ first = True
+ for element in element_list:
+ if first:
+ first = False
+ else:
+ print("---------------")
+ print("\n" + str(element) + "\n")
+
+ def invoke(self, arg, from_tty):
+ self.print_element_list(self.element_list)
+
+
+class SpdkObject(object):
+
+ def __init__(self, gdb_obj):
+ self.obj = gdb_obj
+
+ def get_name(self):
+ return self.obj['name']
+
+ def __str__(self):
+ s = "SPDK object of type %s at %s" % (self.type_name, str(self.obj))
+ s += '\n((%s*) %s)' % (self.type_name, str(self.obj))
+ s += '\nname %s' % self.get_name()
+ return s
+
+
+class IoDevice(SpdkObject):
+
+ type_name = 'struct io_device'
+
+
+class IoDevices(SpdkTailqList):
+
+ def __init__(self):
+ super(IoDevices, self).__init__('g_io_devices', IoDevice, ['tailq'])
+
+
+class spdk_print_io_devices(SpdkPrintCommand):
+
+ def __init__(self):
+ io_devices = IoDevices()
+ name = 'spdk_print_io_devices'
+ super(spdk_print_io_devices, self).__init__(name, io_devices)
+
+
+class Bdev(SpdkObject):
+
+ type_name = 'struct spdk_bdev'
+
+
+class BdevMgrBdevs(SpdkTailqList):
+
+ def __init__(self):
+ tailq_name_list = ['internal', 'link']
+ super(BdevMgrBdevs, self).__init__('g_bdev_mgr->bdevs', Bdev, tailq_name_list)
+
+
+class spdk_print_bdevs(SpdkPrintCommand):
+ name = 'spdk_print_bdevs'
+
+ def __init__(self):
+ bdevs = BdevMgrBdevs()
+ super(spdk_print_bdevs, self).__init__(self.name, bdevs)
+
+
+class spdk_find_bdev(spdk_print_bdevs):
+
+ name = 'spdk_find_bdev'
+
+ def invoke(self, arg, from_tty):
+ print(arg)
+ bdev_query = [bdev for bdev in self.element_list
+ if str(bdev.get_name()).find(arg) != -1]
+ if bdev_query == []:
+ print("Cannot find bdev with name %s" % arg)
+ return
+
+ self.print_element_list(bdev_query)
+
+
+class NvmfSubsystem(SpdkObject):
+
+ type_name = 'struct spdk_nvmf_subsystem'
+
+ def __init__(self, ptr):
+ self.ptr = ptr
+ gdb_obj = self.ptr.cast(gdb.lookup_type(self.type_name).pointer())
+ super(NvmfSubsystem, self).__init__(gdb_obj)
+
+ def get_name(self):
+ return self.obj['subnqn']
+
+ def get_id(self):
+ return int(self.obj['id'])
+
+ def get_ns_list(self):
+ max_nsid = int(self.obj['max_nsid'])
+ ns_list = []
+ for i in range(0, max_nsid):
+ nsptr = (self.obj['ns'] + i).dereference()
+ if nsptr == 0x0:
+ continue
+ ns = nsptr.cast(gdb.lookup_type('struct spdk_nvmf_ns').pointer())
+ ns_list.append(ns)
+ return ns_list
+
+ def __str__(self):
+ s = super(NvmfSubsystem, self).__str__()
+ s += '\nnqn %s' % self.get_name()
+ s += '\nID %d' % self.get_id()
+ for ns in self.get_ns_list():
+ s + '\t%s' % str(ns)
+ return s
+
+
+class SpdkNvmfTgtSubsystems(SpdkArr):
+
+ def get_num_subsystems(self):
+ try: # version >= 18.11
+ return int(self.spdk_nvmf_tgt['max_subsystems'])
+ except RuntimeError: # version < 18.11
+ return int(self.spdk_nvmf_tgt['opts']['max_subsystems'])
+
+ def __init__(self):
+ self.spdk_nvmf_tgt = gdb.parse_and_eval("g_spdk_nvmf_tgt")
+ subsystems = gdb.parse_and_eval("g_spdk_nvmf_tgt->subsystems")
+ super(SpdkNvmfTgtSubsystems, self).__init__(subsystems,
+ self.get_num_subsystems(),
+ NvmfSubsystem)
+
+
+class spdk_print_nvmf_subsystems(SpdkPrintCommand):
+
+ def __init__(self):
+ name = 'spdk_print_nvmf_subsystems'
+ nvmf_tgt_subsystems = SpdkNvmfTgtSubsystems()
+ super(spdk_print_nvmf_subsystems, self).__init__(name, nvmf_tgt_subsystems)
+
+
+class IoChannel(SpdkObject):
+
+ type_name = 'struct spdk_io_channel'
+
+ def get_ref(self):
+
+ return int(self.obj['ref'])
+
+ def get_device(self):
+ return self.obj['dev']
+
+ def get_device_name(self):
+ return self.obj['dev']['name']
+
+ def get_name(self):
+ return ""
+
+ def __str__(self):
+ s = super(IoChannel, self).__str__() + '\n'
+ s += 'ref %d\n' % self.get_ref()
+ s += 'device %s (%s)\n' % (self.get_device(), self.get_device_name())
+ return s
+
+
+# TODO - create TailqList type that gets a gdb object instead of a pointer
+class IoChannels(SpdkTailqList):
+
+ def __init__(self, list_obj):
+ self.tailq_name_list = ['tailq']
+ self.list_member = IoChannel
+ self.list = list_obj
+
+
+class SpdkThread(SpdkObject):
+
+ type_name = 'struct spdk_thread'
+
+ def __init__(self, gdb_obj):
+ super(SpdkThread, self).__init__(gdb_obj)
+ self.io_channels = IoChannels(self.obj['io_channels'])
+
+ def __str__(self):
+ s = super(SpdkThread, self).__str__() + '\n'
+ s += "IO Channels:\n"
+ for io_channel in self.get_io_channels():
+ channel_lines = str(io_channel).split('\n')
+ s += '\n'.join('\t%s' % line for line in channel_lines if line is not '')
+ s += '\n'
+ s += '\t---------------\n'
+ s += '\n'
+ return s
+
+ def get_io_channels(self):
+ return self.io_channels
+
+
+class SpdkThreads(SpdkNormalTailqList):
+
+ def __init__(self):
+ super(SpdkThreads, self).__init__('g_threads', SpdkThread)
+
+
+class spdk_print_threads(SpdkPrintCommand):
+
+ def __init__(self):
+ name = "spdk_print_threads"
+ threads = SpdkThreads()
+ super(spdk_print_threads, self).__init__(name, threads)
+
+
+class spdk_load_macros(gdb.Command):
+
+ def __init__(self):
+ gdb.Command.__init__(self, 'spdk_load_macros',
+ gdb.COMMAND_DATA,
+ gdb.COMPLETE_SYMBOL,
+ True)
+ self.loaded = False
+
+ def invoke(self, arg, from_tty):
+ if arg == '--reload':
+ print('Reloading spdk information')
+ reload = True
+ else:
+ reload = False
+
+ if self.loaded and not reload:
+ return
+
+ spdk_print_threads()
+ spdk_print_bdevs()
+ spdk_print_io_devices()
+ spdk_print_nvmf_subsystems()
+ spdk_find_bdev()
+
+
+spdk_load_macros()