2 from pykdump.API import *
5 Copyright (c) 2015-2019 Cray Inc. All Rights Reserved.
6 Library of helper functions for Lustre scripts
8 # hide this file from the output of 'epython scripts'.
11 """Lustre Hash Table Utilities"""
13 CFS_HASH_ADD_TAIL = 1 << 4
14 CFS_HASH_DEPTH = 1 << 12
15 CFS_HASH_TYPE_MASK = CFS_HASH_ADD_TAIL | CFS_HASH_DEPTH
19 DH = CFS_HASH_ADD_TAIL
20 DD = CFS_HASH_DEPTH | CFS_HASH_ADD_TAIL
23 return hsh.hs_flags & CFS_HASH_TYPE_MASK
26 return type('Enum', (), enums)
28 HS_INFO_FLDS = enum(dtfld=0, hdfld=1,)
30 # The type to struct changes and jobid_hash addition were released
31 # in the same version, so use existence of jobid_hash as a substitute
32 # for cfs_hash type changes.
33 if symbol_exists('jobid_hash'): # 2.11 and later
35 HH: ['struct cfs_hash_head', 'hh_head'],
36 HD: ['struct cfs_hash_head_dep', 'hd_head'],
37 DH: ['struct cfs_hash_dhead', 'dh_head'],
38 DD: ['struct cfs_hash_dhead_dep', 'dd_head'],
42 HH: ['cfs_hash_head_t', 'hh_head'],
43 HD: ['cfs_hash_head_dep_t', 'hd_head'],
44 DH: ['cfs_hash_dhead_t', 'dh_head'],
45 DD: ['cfs_hash_dhead_dep_t', 'dd_head'],
48 def CFS_HASH_NBKT(hsh):
49 return (1 << (hsh.hs_cur_bits - hsh.hs_bkt_bits))
51 def CFS_HASH_BKT_NHLIST(hsh):
52 return (1 << (hsh.hs_bkt_bits))
54 def cfs_hash_head_size(hsh):
55 size = getSizeOf(HS_INFO[hs_get_type(hsh)][HS_INFO_FLDS.dtfld])
58 def cfs_hash_bucket_size(hsh):
59 size = member_offset('struct cfs_hash_bucket', 'hsb_head')
60 size += cfs_hash_head_size(hsh) * CFS_HASH_BKT_NHLIST(hsh) + \
64 def cfs_hash_hhead(hsh, bd_bkt, bd_offset):
65 info = HS_INFO[hs_get_type(hsh)]
66 bkt = Addr(bd_bkt) + member_offset('struct cfs_hash_bucket', 'hsb_head')
67 head = readSU(info[HS_INFO_FLDS.dtfld], bkt)
68 offset = member_offset(info[HS_INFO_FLDS.dtfld], info[HS_INFO_FLDS.hdfld])
69 return readSU('struct hlist_head', (Addr(head[bd_offset]) + offset))
71 def cfs_hash_get_buckets(hsh):
73 for idx in range(CFS_HASH_NBKT(hsh)):
74 if hsh.hs_buckets[idx]:
75 hbuckets.append(hsh.hs_buckets[idx])
78 def cfs_hash_get_hlist_nodes(hsh, bd_bkt, bd_offset):
79 hlist = readSU('struct hlist_head', cfs_hash_hhead(hsh, bd_bkt, bd_offset))
82 while (hnode and hnode != hlist):
87 def cfs_hash_get_nodes(hsh):
89 for bd_bkt in cfs_hash_get_buckets(hsh):
90 for bd_offset in range(CFS_HASH_BKT_NHLIST(hsh)):
91 for hnode in cfs_hash_get_hlist_nodes(hsh, bd_bkt, bd_offset):
92 hs_nodes.append(hnode)
97 def LNET_NIDADDR(nid):
98 return (nid & 0xffffffff)
100 def LNET_NIDNET(nid):
101 return ((nid >> 32) & 0xffffffff)
103 def LNET_NETTYP(net):
104 return ((net >> 16) & 0xffff)
106 def LNET_NETNUM(net):
107 return ((net) & 0xffff)
109 LNET_NID_ANY = 0xffffffffffffffff
110 LNET_NIDSTR_SIZE = 32
116 LP_POISON = 0x5a5a5a5a5a5a5a5a
119 if nid == LNET_NID_ANY:
120 return 'LNET_NID_ANY'
121 addr = LNET_NIDADDR(nid)
122 net = LNET_NIDNET(nid)
123 lnd = LNET_NETTYP(net)
124 nnum = LNET_NETNUM(net)
127 s = "%d.%d.%d.%d@o2ib" % \
128 ((addr >> 24) & 0xff, (addr >> 16) & 0xff,
129 (addr >> 8) & 0xff, addr & 0xff)
137 s = "%s%d" % (s, nnum)
141 obd_import = readSU('struct obd_import', obd.u.cli.cl_import)
144 if obd_import and obd_import != 0xffffffffffffffff and \
145 obd_import != LP_POISON:
146 imp_invalid = obd_import.imp_invalid
148 if not imp_invalid and obd_import.imp_connection:
149 if Addr(obd_import.imp_obd) == Addr(obd):
150 nid = obd_import.imp_connection.c_peer.nid
155 def obd2str(obd, partitions=2):
156 name = obd.obd_name.split('-', partitions)[:partitions]
157 return '-'.join(name)
159 def list_empty(head):
160 return head.next == head
180 def rb_parent_color(node):
181 return readU64(Addr(node))
184 addr = rb_parent_color(node) & ~3
185 return readSU('struct rb_node', addr)
187 #The color of the rb_node; 0 denotes red, 1 denotes black
189 return rb_parent_color(node) & 1
192 if rb_parent(node) == node:
201 parent = rb_parent(node)
202 while(parent and node == parent.rb_right):
204 parent = rb_parent(node)
208 if rb_parent(node) == node:
213 while(node.rb_right):
217 parent = rb_parent(node)
218 while(parent.rb_left and node == parent.rb_left):
220 parent = rb_parent(node)
224 the_lnet = readSymbol('the_lnet')
228 LNET_CPT_BITS = the_lnet.ln_cpt_bits
229 LNET_PROC_CPT_BITS = LNET_CPT_BITS + 1
230 LNET_LOFFT_BITS = getSizeOf('loff_t') * 8
231 LNET_PROC_VER_BITS = max((min(LNET_LOFFT_BITS, 64) / 4), 8)
232 LNET_PROC_HASH_BITS = 9
233 LNET_PROC_HOFF_BITS = LNET_LOFFT_BITS - LNET_PROC_CPT_BITS - LNET_PROC_VER_BITS - LNET_PROC_HASH_BITS -1
234 LNET_PROC_HPOS_BITS = LNET_PROC_HASH_BITS + LNET_PROC_HOFF_BITS
235 LNET_PROC_VPOS_BITS = LNET_PROC_HPOS_BITS + LNET_PROC_VER_BITS
237 LNET_PROC_CPT_MASK = (1 << LNET_PROC_CPT_BITS) - 1
238 LNET_PROC_VER_MASK = (1 << LNET_PROC_VER_BITS) - 1
239 LNET_PROC_HASH_MASK = (1 << LNET_PROC_HASH_BITS) - 1
240 LNET_PROC_HOFF_MASK = (1 << LNET_PROC_HASH_BITS) - 1
242 LNET_PING_FEAT_NI_STATUS = 1 << 1