Whamcloud - gitweb
2d9c1353fcdeadde6cdb98db1a6b2750a62373c1
[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 os.popen(cmd).read()
21
22 # ---------------------------------------------------------------------------
23 # pfn: 2582e8c, physaddr: 2582e8c000, vaddr: ffff002582e8c000
24 def dump_dk_line(tmpfd, options, pfn, used):
25     """Dump the cfs debug messages in the dk format."""
26     physaddr = addrlib.pfn2phys(pfn)
27     vaddr = addrlib.ptov(physaddr)
28     hdr_size = getSizeOf("struct ptldebug_header")
29
30     while (used):
31         hdr = readSU('struct ptldebug_header', vaddr)
32         laddr = vaddr + hdr_size
33         try:
34             line = readmem(laddr, hdr.ph_len - hdr_size)
35         except:
36             print "Skipping pfn: %x, physaddr: %x, vaddr: %x, laddr: %x" % \
37                 (pfn, physaddr, vaddr, laddr)
38             return
39
40         (filename,function,text) = line.split('\0')
41         text = text.rstrip()
42
43         used -= hdr.ph_len
44         vaddr += hdr.ph_len
45
46         type = hdr.ph_type
47         prefix = "%08x:%08x:%u.%u%s:%u.%u" % \
48             (hdr.ph_subsys, hdr.ph_mask, hdr.ph_cpu_id, hdr.ph_type,
49             "F" if (hdr.ph_flags & 1) else "", hdr.ph_sec, hdr.ph_usec)
50
51         buf = "%s:%06u:%u:%u:(%s:%d:%s()) %s" % \
52             (prefix, hdr.ph_stack, hdr.ph_pid, hdr.ph_extern_pid, filename,
53             hdr.ph_line_num, function, text)
54
55         tmpfd.write(buf + '\n')
56
57 # ---------------------------------------------------------------------------
58 def walk_pages(tmpfd, options, cfs_page_head, trace_page_struct):
59
60     cfs_pages = readSUListFromHead(cfs_page_head, 'linkage',
61                                    trace_page_struct,
62                                    maxel=100000, inchead=False)
63
64     for p in cfs_pages:
65         dump_dk_line(tmpfd, options, page.pfn(p.page), p.used)
66
67 # ---------------------------------------------------------------------------
68 def walk_array(options):
69     """Walk the cfs_trace_data array of array pointers."""
70
71     fname = do_shell_cmd('mktemp .dklogXXXX').rstrip()
72     tmpfd = file(fname, 'w')
73
74     try:
75         cfs_trace_data = readSymbol('cfs_trace_data')
76         trace_page_struct = 'struct cfs_trace_page'
77     except TypeError:
78         try:
79             cfs_trace_data = readSymbol('trace_data')
80             trace_page_struct = 'struct trace_page'
81         except:
82             print "Ensure you have loaded the Lustre modules"
83             return 1
84
85     for cfstd_array in cfs_trace_data:
86         if not cfstd_array: continue
87
88         for i in xrange(sys_info.CPUS):
89             u = cfstd_array[i]
90             walk_pages(tmpfd, options, u.tcd.tcd_pages, trace_page_struct)
91             walk_pages(tmpfd, options, u.tcd.tcd_daemon_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()