Viewing: cfs_hashes.py
#!/usr/bin/env python
"""
Utility to display Lustre cfs_hash tables
Copyright (c) 2019 Cray Inc. All Rights Reserved.
"""
from pykdump.API import *
import argparse
import lustrelib as ll
description_short = 'Displays summary of cfs_hash tables'
CFS_HASH_THETA_BITS = 10
def cfs_hash_cur_theta(hs):
hs_cnt = readSU('atomic_t', hs.hs_count).counter
return ((hs_cnt << CFS_HASH_THETA_BITS) >> hs.hs_cur_bits)
def cfs_hash_theta_int(theta):
return (theta >> CFS_HASH_THETA_BITS)
def cfs_hash_theta_frac(theta):
frac = ((theta * 1000) >> CFS_HASH_THETA_BITS) - \
(cfs_hash_theta_int(theta) * 1000)
return frac
def cfs_hash_format_theta(theta):
val = str(cfs_hash_theta_int(theta)) + \
"." + \
str(cfs_hash_theta_frac(theta))
return val
def print_theta(hs):
theta = cfs_hash_cur_theta(hs)
print("Theta: %d %s" % (theta, cfs_hash_format_theta(theta)))
def print_thetas(name, hashtable):
hs = readSU('struct cfs_hash', hashtable)
if hs:
print_theta(hs)
def print_separator(count):
s = ""
for idx in xrange(count):
s += "="
print(s)
def print_hash_labels():
print("%-15s %-17s\t %-5s %-5s %-5s %-5s %-5s %-5s %-5s " \
"%-5s %-5s %-5s %-5s %-11s %-11s %-11s %-5s" % \
("name", "cfs_hash", "cnt", "rhcnt", "xtr", "cur", "min", "max", "rhash", \
"bkt", "nbkt", "nhlst", "flags", "theta", "minT", "maxT", "bktsz"))
def print_hash_summary(name, hashtable):
hs = readSU('struct cfs_hash', hashtable)
if hs:
hs_cnt = readSU('atomic_t', hs.hs_count).counter
hs_ref = readSU('atomic_t', hs.hs_refcount).counter
print("%-15s %-17x\t %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5d %-5x %-11s %-11s %-11s %-5d" % \
(name, (Addr(hs)), \
readSU('atomic_t', hs.hs_count).counter, \
hs.hs_rehash_count, \
hs.hs_extra_bytes, \
hs.hs_cur_bits, \
hs.hs_min_bits, \
hs.hs_max_bits, \
hs.hs_rehash_bits, \
hs.hs_bkt_bits, \
ll.CFS_HASH_NBKT(hs), \
ll.CFS_HASH_BKT_NHLIST(hs), \
hs.hs_flags, \
cfs_hash_format_theta(cfs_hash_cur_theta(hs)), \
cfs_hash_format_theta(hs.hs_min_theta), \
cfs_hash_format_theta(hs.hs_max_theta), \
ll.cfs_hash_bucket_size(hs)))
else:
print("%-15s %-17x" % \
(name, (Addr(hs))))
def obd_print_export_hashes(obd, exp_list, fld):
print("\nExport list head %x %s" % (exp_list, fld))
for exp in readSUListFromHead(exp_list, fld, 'struct obd_export'):
print_hash_summary('exp_lock', exp.exp_lock_hash)
print_hash_summary('exp_flock', exp.exp_flock_hash)
def obd_print_one_device_hashes(obd):
try:
nm = ll.obd2str(obd)
except Exception as e:
return 1
print("obd_device %-17x %-22s" % (Addr(obd), ll.obd2str(obd)))
print_hash_labels()
print_hash_summary("uuid", obd.obd_uuid_hash)
print_hash_summary("nid", obd.obd_nid_hash)
print_hash_summary("nid_stats", obd.obd_nid_stats_hash)
if "clilov" in nm:
print_hash_summary("lov_pools", obd.u.lov.lov_pools_hash_body)
elif "clilmv" in nm:
pass
else:
print_hash_summary("cl_quota0", obd.u.cli.cl_quota_hash[0])
print_hash_summary("cl_quota1", obd.u.cli.cl_quota_hash[1])
# obd_print_export_hashes(obd, obd.obd_exports, 'exp_obd_chain')
# obd_print_export_hashes(obd, obd.obd_exports_timed, 'exp_obd_chain_timed')
print("")
return 0
def obd_devs_hash():
devices = readSymbol('obd_devs')
for obd in devices:
if not obd_print_one_device_hashes(obd) == 0:
break
print_separator(150)
def ldlm_print_ns_hashes(ns, type):
ns_list = readSymbol(ns)
print("\n%s namespaces-resources" % type)
print_hash_labels()
for ns in readSUListFromHead(ns_list, 'ns_list_chain', 'struct ldlm_namespace'):
nm = ll.obd2str(ns.ns_obd)[0:20]
print_hash_summary(nm, ns.ns_rs_hash)
def ldlm_namespaces_hash():
ldlm_print_ns_hashes('ldlm_cli_active_namespace_list', "Client")
ldlm_print_ns_hashes('ldlm_cli_inactive_namespace_list', "Inactive")
ldlm_print_ns_hashes('ldlm_srv_namespace_list', "Server")
def lu_sites_hashes():
lu_sites = readSymbol('lu_sites')
print_hash_labels()
for site in readSUListFromHead(lu_sites, 'ls_linkage', 'struct lu_site'):
print_hash_summary("lu_site_vvp", site.ls_obj_hash)
print("")
def global_hashes():
print_hash_labels()
print_hash_summary("conn_hash", readSymbol('conn_hash'))
if symbol_exists('jobid_hash'):
print_hash_summary("jobid_hash", readSymbol('jobid_hash'))
if symbol_exists('cl_env_hash'):
print_hash_summary("cl_env_hash", readSymbol('cl_env_hash'))
print("")
if __name__ == "__main__":
description = "Displays summary of hash tables in 'obd_devs'"
parser = argparse.ArgumentParser(description=description)
args = parser.parse_args()
global_hashes()
lu_sites_hashes()
obd_devs_hash()
ldlm_namespaces_hash()