Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[fs/lustre-release.git] / contrib / debug_tools / epython_scripts / cfs_hashes.py
1 #!/usr/bin/env python
2
3 """
4 Utility to display Lustre cfs_hash tables
5 Copyright (c) 2019 Cray Inc. All Rights Reserved.
6 """
7
8 from pykdump.API import *
9 import argparse
10
11 import lustrelib as ll
12
13 description_short = 'Displays summary of cfs_hash tables'
14
15 CFS_HASH_THETA_BITS = 10
16
17 def cfs_hash_cur_theta(hs):
18     hs_cnt = readSU('atomic_t', hs.hs_count).counter
19     return ((hs_cnt << CFS_HASH_THETA_BITS) >> hs.hs_cur_bits)
20
21 def cfs_hash_theta_int(theta):
22     return (theta >> CFS_HASH_THETA_BITS)
23
24 def cfs_hash_theta_frac(theta):
25     frac = ((theta * 1000) >> CFS_HASH_THETA_BITS) - \
26            (cfs_hash_theta_int(theta) * 1000)
27     return frac
28
29 def cfs_hash_format_theta(theta):
30     val = str(cfs_hash_theta_int(theta)) + \
31           "." + \
32           str(cfs_hash_theta_frac(theta))
33     return val
34
35 def print_theta(hs):
36     theta = cfs_hash_cur_theta(hs)
37     print("Theta: %d %s" % (theta, cfs_hash_format_theta(theta)))
38
39 def print_thetas(name, hashtable):
40     hs = readSU('struct cfs_hash', hashtable)
41     if hs:
42         print_theta(hs)
43
44 def print_separator(count):
45     s = ""
46     for idx in xrange(count):
47         s += "="
48     print(s)
49
50 def print_hash_labels():
51     print("%-15s %-17s\t %-5s %-5s %-5s %-5s %-5s %-5s %-5s " \
52           "%-5s %-5s %-5s %-5s %-11s %-11s %-11s %-5s" % \
53           ("name", "cfs_hash", "cnt", "rhcnt", "xtr", "cur", "min", "max", "rhash", \
54            "bkt", "nbkt", "nhlst", "flags", "theta", "minT", "maxT", "bktsz"))
55
56 def print_hash_summary(name, hashtable):
57     hs = readSU('struct cfs_hash', hashtable)
58     if hs:
59         hs_cnt = readSU('atomic_t', hs.hs_count).counter
60         hs_ref = readSU('atomic_t', hs.hs_refcount).counter
61         print("%-15s %-17x\t %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5x %-11s %-11s %-11s %-5d" % \
62               (name, (Addr(hs)), \
63                readSU('atomic_t', hs.hs_count).counter, \
64                hs.hs_rehash_count, \
65                hs.hs_extra_bytes, \
66                hs.hs_cur_bits, \
67                hs.hs_min_bits, \
68                hs.hs_max_bits, \
69                hs.hs_rehash_bits, \
70                hs.hs_bkt_bits, \
71                ll.CFS_HASH_NBKT(hs), \
72                ll.CFS_HASH_BKT_NHLIST(hs), \
73                hs.hs_flags, \
74                cfs_hash_format_theta(cfs_hash_cur_theta(hs)), \
75                cfs_hash_format_theta(hs.hs_min_theta), \
76                cfs_hash_format_theta(hs.hs_max_theta), \
77                ll.cfs_hash_bucket_size(hs)))
78     else:
79         print("%-15s %-17x" % \
80               (name, (Addr(hs))))
81
82 def obd_print_export_hashes(obd, exp_list, fld):
83     print("\nExport list head %x %s" % (exp_list, fld))
84     for exp in readSUListFromHead(exp_list, fld, 'struct obd_export'):
85         print_hash_summary('exp_lock', exp.exp_lock_hash)
86         print_hash_summary('exp_flock', exp.exp_flock_hash)
87
88 def obd_print_one_device_hashes(obd):
89     try:
90         nm = ll.obd2str(obd)
91     except Exception as e:
92         return 1
93
94     print("obd_device %-17x %-22s" % (Addr(obd), ll.obd2str(obd)))
95     print_hash_labels()
96
97     print_hash_summary("uuid", obd.obd_uuid_hash)
98     print_hash_summary("nid", obd.obd_nid_hash)
99     print_hash_summary("nid_stats", obd.obd_nid_stats_hash)
100
101     if "clilov" in nm:
102         print_hash_summary("lov_pools", obd.u.lov.lov_pools_hash_body)
103     elif "clilmv" in nm:
104         pass
105     else:
106         print_hash_summary("cl_quota0", obd.u.cli.cl_quota_hash[0])
107         print_hash_summary("cl_quota1", obd.u.cli.cl_quota_hash[1])
108
109 #    obd_print_export_hashes(obd, obd.obd_exports, 'exp_obd_chain')
110 #    obd_print_export_hashes(obd, obd.obd_exports_timed, 'exp_obd_chain_timed')
111     print("")
112     return 0
113
114 def obd_devs_hash():
115     devices = readSymbol('obd_devs')
116
117     for obd in devices:
118        if not obd_print_one_device_hashes(obd) == 0:
119            break
120     print_separator(150)
121
122 def ldlm_print_ns_hashes(ns, type):
123     ns_list = readSymbol(ns)
124     print("\n%s namespaces-resources" % type)
125     print_hash_labels()
126     for ns in readSUListFromHead(ns_list, 'ns_list_chain', 'struct ldlm_namespace'):
127         nm = ll.obd2str(ns.ns_obd)[0:20]
128         print_hash_summary(nm, ns.ns_rs_hash)
129
130 def ldlm_namespaces_hash():
131     ldlm_print_ns_hashes('ldlm_cli_active_namespace_list', "Client")
132     ldlm_print_ns_hashes('ldlm_cli_inactive_namespace_list', "Inactive")
133     ldlm_print_ns_hashes('ldlm_srv_namespace_list', "Server")
134
135 def lu_sites_hashes():
136     lu_sites = readSymbol('lu_sites')
137     print_hash_labels()
138     for site in readSUListFromHead(lu_sites, 'ls_linkage', 'struct lu_site'):
139         print_hash_summary("lu_site_vvp", site.ls_obj_hash)
140     print("")
141
142
143 def global_hashes():
144     print_hash_labels()
145     print_hash_summary("conn_hash", readSymbol('conn_hash'))
146     if symbol_exists('jobid_hash'):
147         print_hash_summary("jobid_hash", readSymbol('jobid_hash'))
148     if symbol_exists('cl_env_hash'):
149         print_hash_summary("cl_env_hash", readSymbol('cl_env_hash'))
150     print("")
151
152 if __name__ == "__main__":
153     description = "Displays summary of hash tables in 'obd_devs'"
154     parser = argparse.ArgumentParser(description=description)
155     args = parser.parse_args()
156
157     global_hashes()
158     lu_sites_hashes()
159     obd_devs_hash()
160     ldlm_namespaces_hash()