Whamcloud - gitweb
New tag 2.15.91
[fs/lustre-release.git] / contrib / debug_tools / epython_scripts / dk.py
1 #!/usr/bin/env python
2 """
3 Copyright 2015-2019 Cray Inc.  All Rights Reserved
4 Utility to dump the Lustre dk logs.
5 Based on dump_cfs_trace_data.py
6 """
7
8 import sys
9 import crash
10 import argparse
11 from time import localtime
12 from operator import itemgetter
13 from pykdump.API import getSizeOf, readSU, readmem, readSUListFromHead, readSymbol, sys_info
14 from crashlib import page, addrlib
15 import os
16
17 description_short = 'Dump and sort the Lustre dk logs.'
18
19 def do_shell_cmd(cmd):
20     return "done"
21     #return os.popen(cmd).read()
22
23 # ---------------------------------------------------------------------------
24 # pfn: 2582e8c, physaddr: 2582e8c000, vaddr: ffff002582e8c000
25 def dump_dk_line(tmpfd, options, pfn, used):
26     """Dump the cfs debug messages in the dk format."""
27     physaddr = addrlib.pfn2phys(pfn)
28     vaddr = addrlib.ptov(physaddr)
29     hdr_size = getSizeOf("struct ptldebug_header")
30
31     while (used):
32         hdr = readSU('struct ptldebug_header', vaddr)
33         laddr = vaddr + hdr_size
34         try:
35             line = readmem(laddr, hdr.ph_len - hdr_size)
36         except:
37             print("Skipping pfn: %x, physaddr: %x, vaddr: %x, laddr: %x" % \
38                 (pfn, physaddr, vaddr, laddr))
39             return
40
41         (filename,function,text) = line.decode().split('\0')
42         text = text.rstrip()
43
44         used -= hdr.ph_len
45         vaddr += hdr.ph_len
46
47         type = hdr.ph_type
48         prefix = "%08x:%08x:%u.%u%s:%u.%u" % \
49             (hdr.ph_subsys, hdr.ph_mask, hdr.ph_cpu_id, hdr.ph_type,
50             "F" if (hdr.ph_flags & 1) else "", hdr.ph_sec, hdr.ph_usec)
51
52         buf = "%s:%06u:%u:%u:(%s:%d:%s()) %s" % \
53             (prefix, hdr.ph_stack, hdr.ph_pid, hdr.ph_extern_pid, filename,
54             hdr.ph_line_num, function, text)
55
56         tmpfd.write(buf + '\n')
57
58 # ---------------------------------------------------------------------------
59 def walk_pages(tmpfd, options, cfs_page_head, trace_page_struct):
60
61     cfs_pages = readSUListFromHead(cfs_page_head, 'linkage',
62                                    trace_page_struct,
63                                    maxel=100000, inchead=False)
64
65     for p in cfs_pages:
66         dump_dk_line(tmpfd, options, page.pfn(p.page), p.used)
67
68 # ---------------------------------------------------------------------------
69 def walk_array(options):
70     """Walk the cfs_trace_data array of array pointers."""
71
72     #fname = do_shell_cmd('mktemp .dklogXXXX').rstrip()
73     tmpfd = open("/tmp/log.bin", 'w')
74
75     try:
76         cfs_trace_data = readSymbol('cfs_trace_data')
77         trace_page_struct = 'struct cfs_trace_page'
78     except TypeError:
79         try:
80             cfs_trace_data = readSymbol('trace_data')
81             trace_page_struct = 'struct trace_page'
82         except:
83             print("Ensure you have loaded the Lustre modules")
84             return 1
85
86     for cfstd_array in cfs_trace_data:
87         if not cfstd_array: continue
88
89         for i in range(sys_info.CPUS):
90             u = cfstd_array[i]
91             walk_pages(tmpfd, options, u.tcd.tcd_pages, trace_page_struct)
92             walk_pages(tmpfd, options, u.tcd.tcd_stock_pages, trace_page_struct)
93
94     tmpfd.close()
95     print(do_shell_cmd('sort -n -s -t: -k4,4 ' + fname))
96     print(do_shell_cmd('rm ' + fname))
97
98 # ---------------------------------------------------------------------------
99 def dump_dk_log():
100     parser = argparse.ArgumentParser(
101         description= "Dump and sort the Lustre dk logs.",
102         epilog= "NOTE: the Lustre kernel modules must be loaded.")
103     args = parser.parse_args()
104     return walk_array(args)
105
106 if __name__ == '__main__':
107     dump_dk_log()