Whamcloud - gitweb
New tag 2.15.91
[fs/lustre-release.git] / contrib / debug_tools / epython_scripts / lu_object.py
1 #!/usr/bin/env python
2
3 """
4 Copyright (c) 2019 Cray Inc. All Rights Reserved.
5 Utility to display contents of a Lustre lu_object
6 """
7
8 from pykdump.API import *
9 from struct import *
10 import argparse
11 import os
12
13 import lustrelib as ll
14 from crashlib.input import toint
15
16 description_short = "Prints contents of an lu_object"
17
18 LOHA_EXISTS = 1 << 0
19
20 LOV_MAGIC = 0x0BD10BD0
21 LOV_MAGIC_V3 = 0x0BD30BD0
22
23 DEPTH = 3
24 RULER = "........................................"
25
26 FID_SEQ_OST_MDT0 = 0
27 FID_SEQ_LOV_DEFAULT = 0xffffffffffffffff
28 FID_SEQ_IDIF = 0x100000000
29 FID_SEQ_IDIF_MAX = 0x1ffffffff
30 IDIF_OID_MAX_BITS = 48
31 IDIF_OID_MASK = ((1 << IDIF_OID_MAX_BITS) -1)
32
33 def lov_print_empty(obj, depth=0, ruler=RULER):
34     print("empty %d" % obj.lo_layout_invalid)
35
36 def lov_print_raid0(obj, depth=0, ruler=RULER):
37     r0 = None
38     lsm = obj.lo_lsm
39     try:
40         magic = lsm.lsm_magic
41         stripes = lsm.lsm_stripe_count
42         layout_gen = lsm.lsm_layout_gen
43         pattern = lsm.lsm_pattern
44     except Exception as e:
45         magic = lsm.lsm_wire.lw_magic
46         stripes = lsm.lsm_wire.lw_stripe_count
47         layout_gen = lsm.lsm_wire.lw_layout_gen
48         pattern = lsm.lsm_wire.lw_pattern
49     if magic==LOV_MAGIC or magic==LOV_MAGIC_V3:
50         r0 = obj.u.raid0
51     lli = readU32(Addr(obj) + member_offset('struct lov_object', 'lo_layout_invalid'))
52     invalid = "invalid" if lli else "valid"
53     if r0 and r0.lo_nr:
54         print("%*.*sstripes: %d, %s, lsm[0x%x 0x%X %d %d %d %d]:" % \
55              (depth, depth, ruler,
56              r0.lo_nr, invalid, Addr(lsm), magic,
57              lsm.lsm_refc.counter, stripes, layout_gen, pattern))
58         for i in range(r0.lo_nr):
59             los = r0.lo_sub[i]
60             if los:
61                 sub = los.lso_cl.co_lu
62                 lovsub_object_print(sub, depth+DEPTH, ruler)
63             else:
64                 print("sub %d absent" % i)
65
66 def lov_print_released(obj, depth=0, ruler=RULER):
67     lsm = obj.lo_lsm
68     magic = lsm.lsm_magic
69     entries = lsm.lsm_entry_count
70     layout_gen = lsm.lsm_layout_gen
71     lli = readU32(Addr(obj) + member_offset('struct lov_object', 'lo_layout_invalid'))
72     invalid = "invalid" if lli else "valid"
73     if magic==LOV_MAGIC or magic==LOV_MAGIC_V3:
74         print("%*.*sreleased: %s, lov_stripe_md: 0x%x [0x%X %d %u %u]:" % \
75              (depth, depth, ruler,
76              invalid, Addr(lsm), magic, lsm.lsm_refc.counter,
77              entries, layout_gen))
78
79 LOV_PRINT_TYPE = {
80                  0:lov_print_empty,
81                  1:lov_print_raid0,
82                  2:lov_print_released}
83
84 def vvp_object_print(o, depth=0, ruler=RULER):
85     obj = readSU('struct vvp_object', Addr(o) - member_offset('struct vvp_object', 'vob_cl.co_lu'))
86     print("%*.*s(trans:%s mmap:%d) inode: 0x%x " % \
87          (depth, depth, ruler,
88          obj.vob_transient_pages.counter,
89          obj.vob_mmap_cnt.counter,
90          Addr(obj.vob_inode)))
91
92 def lod_object_print(o, depth=0, ruler=RULER):
93     obj = readSU('struct lod_object', Addr(o) - member_offset('struct lod_object', 'ldo_obj.do_lu'))
94     print("%*.*slod_object@0x%x" % (depth, depth, ruler, Addr(obj)))
95
96 def lov_object_print(o, depth=0, ruler=RULER):
97     obj = readSU('struct lov_object', Addr(o) - member_offset('struct lov_object', 'lo_cl.co_lu'))
98     type = obj.lo_type
99     LOV_PRINT_TYPE[type](obj, depth, ruler)
100
101 def lovsub_object_print(o, depth=0, ruler=RULER):
102     obj = readSU('struct lovsub_object', Addr(o) - member_offset('struct lovsub_object', 'lso_cl.co_lu'))
103     print("%*.*slso_index: %d" % (depth, depth, ruler, obj.lso_index))
104
105 def mdd_object_print(o, depth=0, ruler=RULER):
106     obj = readSU('struct mdd_object', Addr(o) - member_offset('struct mdd_object', 'mod_obj.mo_lu'))
107     print("%*.*smdd_object@0x%x(open_count=%d, valid=%x, cltime=%u, flags=%x)" % \
108          (depth, depth, ruler, Addr(obj), obj.mod_count, obj.mod_valid,
109          obj.mod_cltime, obj.mod_flags))
110
111 def mdt_object_print(o, depth=0, ruler=RULER):
112     obj = readSU('struct mdt_object', Addr(o) - member_offset('struct mdt_object', 'mot_obj'))
113     print("%*.*smdt_object@0x%x(ioepoch=%u, flags=%x, epochcount=%d, writecount-%d" % \
114          (depth, depth, ruler, Addr(obj), obj.mot_ioepoch, obj.mot_flags,
115          obj.mot_ioepoch_count, obj.mot_writecount))
116
117 def mgs_object_print(o, depth=0, ruler=RULER):
118     obj = readSU('struct mgs_object', Addr(o) - member_offset('struct mgs_object', 'mgo_obj.do_lu'))
119     print("%*.*smgs_object@0x%x" % (depth, depth, ruler, Addr(obj)))
120
121 def echo_object_print(o, depth=0, ruler=RULER):
122     clo = readSU('struct cl_object', Addr(o) - member_offset('struct cl_object', 'co_lu'))
123     obj = readSU('struct echo_object', Addr(clo) - member_offset('struct echo_object', 'eo_cl'))
124     print("%*.*sechocl_object@0x%x" % (depth, depth, ruler, Addr(obj)))
125
126 def ofd_object_print(o, depth=0, ruler=RULER):
127     print("%*.*sofd_object@0x%x" % (depth, depth, ruler, Addr(o)))
128
129 def osc_object_print(o, depth=0, ruler=RULER):
130     obj = readSU('struct osc_object', Addr(o) - member_offset('struct osc_object', 'oo_cl.co_lu'))
131     oinfo = obj.oo_oinfo
132     ar = oinfo.loi_ar
133     ostid = oinfo.loi_oi
134     ostid_seq = 0
135     ostid_id = 0
136     if ostid.oi.oi_seq == FID_SEQ_OST_MDT0:
137         ostid_seq = FID_SEQ_OST_MDT0
138         ostid_id = ostid.oi.oi_id & IDIF_OID_MASK
139     elif ostid.oi.oi_seq == FID_SEQ_LOV_DEFAULT:
140         ostid_seq = FID_SEQ_LOV_DEFAULT
141         ostid_id = ostid.oi.oi_id
142     elif ostid.oi_fid.f_seq >= FID_SEQ_IDIF and \
143         ostid.oi_fid.f_seq <= FID_SEQ_IDIF_MAX:
144         ostid_seq = FID_SEQ_OST_MDT0
145         ostid_id = ((0 << 48) | (ostid.oi_fid.f_seq & 0xffff << 32) | (ostid.oi_fid.f_oid))
146     else:
147         ostid_seq = ostid.oi_fid.f_seq
148         ostid_id = ostid.oi_fid.f_oid
149     print("%*.*sid: 0x%x:%u idx: %d gen: %d kms_valid: %u kms: %u rc: %d force_sync: %d min_xid: %u" % \
150          (depth, depth, ruler, ostid_seq, ostid_id,
151          oinfo.loi_ost_idx, oinfo.loi_ost_gen, oinfo.loi_kms_valid,
152          oinfo.loi_kms, ar.ar_rc, ar.ar_force_sync, ar.ar_min_xid))
153
154 def osd_object_print(o, depth=0, ruler=RULER):
155     obj = readSU('struct osd_object', Addr(o) - member_offset('struct osd_object', 'oo_dt.do_lu'))
156     print("%*.*sosd_object@0x%x" % (depth, depth, ruler, Addr(obj)))
157
158 def osp_object_print(o, depth=0, ruler=RULER):
159     obj = readSU('struct osp_object', Addr(o) - member_offset('struct osp_object', 'opo_obj.do_lu'))
160     print("%*.*sosp_object@0x%x" % (depth, depth, ruler, Addr(o)))
161
162 OBJ_PRINT = {
163             "vvp":vvp_object_print,
164             "lod":lod_object_print,
165             "lov":lov_object_print,
166             "lovsub":lovsub_object_print,
167             "mdd":mdd_object_print,
168             "mdt":mdt_object_print,
169             "mgs":mgs_object_print,
170             "echo":echo_object_print,
171             "ofd":ofd_object_print,
172             "osc":osc_object_print,
173             "osd":osd_object_print,
174             "osp":osp_object_print}
175
176 def print_object_from_name(name, obj, depth=0, ruler=RULER):
177     if OBJ_PRINT[name]:
178         OBJ_PRINT[name](obj, depth, ruler)
179
180 def print_object(pos, depth=0, ruler=RULER):
181     print("%*.*s%s@0x%x" % (depth, depth, ruler, pos.lo_dev.ld_type.ldt_name, Addr(pos)))
182     if (pos.lo_ops.loo_object_print):
183         print_object_from_name(pos.lo_dev.ld_type.ldt_name, pos, depth+DEPTH, ruler)
184
185 def print_object_from_header(loh, depth=0, ruler=RULER):
186     head = loh.loh_layers
187     empty = "" if (loh.loh_lru.next == loh.loh_lru) else " lru"
188     exists = " exist" if loh.loh_attr & LOHA_EXISTS else ""
189     print("%*.*slu_object_header@0x%x[fl:0x%x, rc:%d, [0x%x:0x%x:0x%x]%s%s] {" % \
190          (depth, depth, ruler,
191          Addr(loh),
192          loh.loh_flags,
193          loh.loh_ref.counter,
194          loh.loh_fid.f_seq,
195          loh.loh_fid.f_oid,
196          loh.loh_fid.f_ver,
197          empty,
198          exists))
199     for obj in readSUListFromHead(head, 'lo_linkage', 'struct lu_object'):
200         print_object(obj, depth+DEPTH, ruler)
201     print("%*.*s} header@0x%x\n" % (depth, depth, ruler, Addr(loh)))
202
203 if __name__ == "__main__":
204     description = "Prints contents of an lu_object"
205     parser = argparse.ArgumentParser(description=description)
206     parser.add_argument("lu_object_header", default=False, type=toint,
207         help="address of an lu_object_header")
208
209     args = parser.parse_args()
210     loh = readSU('struct lu_object_header', args.lu_object_header)
211     print_object_from_header(loh)