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):
86 except (crash.error, IndexError):
90 def cfs_hash_get_nodes(hsh):
92 for bd_bkt in cfs_hash_get_buckets(hsh):
93 for bd_offset in range(CFS_HASH_BKT_NHLIST(hsh)):
94 for hnode in cfs_hash_get_hlist_nodes(hsh, bd_bkt, bd_offset):
95 hs_nodes.append(hnode)
100 def LNET_NIDADDR(nid):
101 return (nid & 0xffffffff)
103 def LNET_NIDNET(nid):
104 return ((nid >> 32) & 0xffffffff)
106 def LNET_NETTYP(net):
107 return ((net >> 16) & 0xffff)
109 def LNET_NETNUM(net):
110 return ((net) & 0xffff)
112 LNET_NID_ANY = 0xffffffffffffffff
113 LNET_NIDSTR_SIZE = 32
120 LP_POISON = 0x5a5a5a5a5a5a5a5a
123 if nid == LNET_NID_ANY:
124 return 'LNET_NID_ANY'
125 addr = LNET_NIDADDR(nid)
126 net = LNET_NIDNET(nid)
127 lnd = LNET_NETTYP(net)
128 nnum = LNET_NETNUM(net)
131 s = "%d.%d.%d.%d@o2ib" % \
132 ((addr >> 24) & 0xff, (addr >> 16) & 0xff,
133 (addr >> 8) & 0xff, addr & 0xff)
139 s = "%d.%d.%d.%d@tcp" % ((addr >> 24) & 0xff, (addr >> 16) & 0xff,
140 (addr >> 8) & 0xff, addr & 0xff)
144 s = "%s%d" % (s, nnum)
148 obd_import = readSU('struct obd_import', obd.u.cli.cl_import)
151 if obd_import and obd_import != 0xffffffffffffffff and \
152 obd_import != LP_POISON:
153 imp_invalid = obd_import.imp_invalid
155 if not imp_invalid and obd_import.imp_connection:
156 if Addr(obd_import.imp_obd) == Addr(obd):
157 nid = obd_import.imp_connection.c_peer.nid
162 def obd2str(obd, partitions=2):
163 name = obd.obd_name.split('-', partitions)[:partitions]
164 return '-'.join(name)
166 def list_empty(head):
167 return head.next == head
187 def rb_parent_color(node):
188 return readU64(Addr(node))
191 addr = rb_parent_color(node) & ~3
192 return readSU('struct rb_node', addr)
194 #The color of the rb_node; 0 denotes red, 1 denotes black
196 return rb_parent_color(node) & 1
199 if rb_parent(node) == node:
208 parent = rb_parent(node)
209 while(parent and node == parent.rb_right):
211 parent = rb_parent(node)
215 if rb_parent(node) == node:
220 while(node.rb_right):
224 parent = rb_parent(node)
225 while(parent.rb_left and node == parent.rb_left):
227 parent = rb_parent(node)
231 the_lnet = readSymbol('the_lnet')
235 LNET_CPT_BITS = the_lnet.ln_cpt_bits
236 LNET_PROC_CPT_BITS = LNET_CPT_BITS + 1
237 LNET_LOFFT_BITS = getSizeOf('loff_t') * 8
238 LNET_PROC_VER_BITS = int(max((min(LNET_LOFFT_BITS, 64) / 4), 8))
239 LNET_PROC_HASH_BITS = 9
240 LNET_PROC_HOFF_BITS = LNET_LOFFT_BITS - LNET_PROC_CPT_BITS - LNET_PROC_VER_BITS - LNET_PROC_HASH_BITS -1
241 LNET_PROC_HPOS_BITS = LNET_PROC_HASH_BITS + LNET_PROC_HOFF_BITS
242 LNET_PROC_VPOS_BITS = LNET_PROC_HPOS_BITS + LNET_PROC_VER_BITS
244 LNET_PROC_CPT_MASK = (1 << LNET_PROC_CPT_BITS) - 1
245 LNET_PROC_VER_MASK = (1 << LNET_PROC_VER_BITS) - 1
246 LNET_PROC_HASH_MASK = (1 << LNET_PROC_HASH_BITS) - 1
247 LNET_PROC_HOFF_MASK = (1 << LNET_PROC_HASH_BITS) - 1
249 LNET_PING_FEAT_NI_STATUS = 1 << 1