1716fd348SMartin Matuska#!/usr/bin/env @PYTHON_SHEBANG@ 2716fd348SMartin Matuska# 3716fd348SMartin Matuska# Print out statistics for all cached dmu buffers. This information 4716fd348SMartin Matuska# is available through the dbufs kstat and may be post-processed as 5716fd348SMartin Matuska# needed by the script. 6716fd348SMartin Matuska# 7716fd348SMartin Matuska# CDDL HEADER START 8716fd348SMartin Matuska# 9716fd348SMartin Matuska# The contents of this file are subject to the terms of the 10716fd348SMartin Matuska# Common Development and Distribution License, Version 1.0 only 11716fd348SMartin Matuska# (the "License"). You may not use this file except in compliance 12716fd348SMartin Matuska# with the License. 13716fd348SMartin Matuska# 14716fd348SMartin Matuska# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 15271171e0SMartin Matuska# or https://opensource.org/licenses/CDDL-1.0. 16716fd348SMartin Matuska# See the License for the specific language governing permissions 17716fd348SMartin Matuska# and limitations under the License. 18716fd348SMartin Matuska# 19716fd348SMartin Matuska# When distributing Covered Code, include this CDDL HEADER in each 20716fd348SMartin Matuska# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 21716fd348SMartin Matuska# If applicable, add the following below this CDDL HEADER, with the 22716fd348SMartin Matuska# fields enclosed by brackets "[]" replaced with your own identifying 23716fd348SMartin Matuska# information: Portions Copyright [yyyy] [name of copyright owner] 24716fd348SMartin Matuska# 25716fd348SMartin Matuska# CDDL HEADER END 26716fd348SMartin Matuska# 27716fd348SMartin Matuska# Copyright (C) 2013 Lawrence Livermore National Security, LLC. 28716fd348SMartin Matuska# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). 29716fd348SMartin Matuska# 30716fd348SMartin Matuska# This script must remain compatible with and Python 3.6+. 31716fd348SMartin Matuska# 32716fd348SMartin Matuska 33716fd348SMartin Matuskaimport sys 34716fd348SMartin Matuskaimport getopt 35716fd348SMartin Matuskaimport errno 36716fd348SMartin Matuskaimport re 37716fd348SMartin Matuska 38716fd348SMartin Matuskabhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"] 39716fd348SMartin Matuskabxhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize", 40*a2b560ccSMartin Matuska "usize", "meta", "state", "dbholds", "dbc", "list", "atype", "flags", 41716fd348SMartin Matuska "count", "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2", 42716fd348SMartin Matuska "l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype", 43716fd348SMartin Matuska "data_bs", "meta_bs", "bsize", "lvls", "dholds", "blocks", "dsize"] 44716fd348SMartin Matuskabincompat = ["cached", "direct", "indirect", "bonus", "spill"] 45716fd348SMartin Matuska 46716fd348SMartin Matuskadhdr = ["pool", "objset", "object", "dtype", "cached"] 47716fd348SMartin Matuskadxhdr = ["pool", "objset", "object", "dtype", "btype", "data_bs", "meta_bs", 48716fd348SMartin Matuska "bsize", "lvls", "dholds", "blocks", "dsize", "cached", "direct", 49716fd348SMartin Matuska "indirect", "bonus", "spill"] 50*a2b560ccSMartin Matuskadincompat = ["level", "blkid", "offset", "dbsize", "usize", "meta", "state", 51*a2b560ccSMartin Matuska "dbholds", "dbc", "list", "atype", "flags", "count", "asize", 52*a2b560ccSMartin Matuska "access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", 53*a2b560ccSMartin Matuska "l2_asize", "l2_comp", "aholds"] 54716fd348SMartin Matuska 55716fd348SMartin Matuskathdr = ["pool", "objset", "dtype", "cached"] 56716fd348SMartin Matuskatxhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect", 57716fd348SMartin Matuska "bonus", "spill"] 58*a2b560ccSMartin Matuskatincompat = ["object", "level", "blkid", "offset", "dbsize", "usize", "meta", 59*a2b560ccSMartin Matuska "state", "dbc", "dbholds", "list", "atype", "flags", "count", 60*a2b560ccSMartin Matuska "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", 61716fd348SMartin Matuska "l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs", 62716fd348SMartin Matuska "bsize", "lvls", "dholds", "blocks", "dsize"] 63716fd348SMartin Matuska 64716fd348SMartin Matuskacols = { 65716fd348SMartin Matuska # hdr: [size, scale, description] 66716fd348SMartin Matuska "pool": [15, -1, "pool name"], 67716fd348SMartin Matuska "objset": [6, -1, "dataset identification number"], 68716fd348SMartin Matuska "object": [10, -1, "object number"], 69716fd348SMartin Matuska "level": [5, -1, "indirection level of buffer"], 70716fd348SMartin Matuska "blkid": [8, -1, "block number of buffer"], 71716fd348SMartin Matuska "offset": [12, 1024, "offset in object of buffer"], 72716fd348SMartin Matuska "dbsize": [7, 1024, "size of buffer"], 73*a2b560ccSMartin Matuska "usize": [7, 1024, "size of attached user data"], 74716fd348SMartin Matuska "meta": [4, -1, "is this buffer metadata?"], 75716fd348SMartin Matuska "state": [5, -1, "state of buffer (read, cached, etc)"], 76716fd348SMartin Matuska "dbholds": [7, 1000, "number of holds on buffer"], 77716fd348SMartin Matuska "dbc": [3, -1, "in dbuf cache"], 78716fd348SMartin Matuska "list": [4, -1, "which ARC list contains this buffer"], 79716fd348SMartin Matuska "atype": [7, -1, "ARC header type (data or metadata)"], 80716fd348SMartin Matuska "flags": [9, -1, "ARC read flags"], 81716fd348SMartin Matuska "count": [5, -1, "ARC data count"], 82716fd348SMartin Matuska "asize": [7, 1024, "size of this ARC buffer"], 83716fd348SMartin Matuska "access": [10, -1, "time this ARC buffer was last accessed"], 84716fd348SMartin Matuska "mru": [5, 1000, "hits while on the ARC's MRU list"], 85716fd348SMartin Matuska "gmru": [5, 1000, "hits while on the ARC's MRU ghost list"], 86716fd348SMartin Matuska "mfu": [5, 1000, "hits while on the ARC's MFU list"], 87716fd348SMartin Matuska "gmfu": [5, 1000, "hits while on the ARC's MFU ghost list"], 88716fd348SMartin Matuska "l2": [5, 1000, "hits while on the L2ARC"], 89716fd348SMartin Matuska "l2_dattr": [8, -1, "L2ARC disk address/offset"], 90716fd348SMartin Matuska "l2_asize": [8, 1024, "L2ARC alloc'd size (depending on compression)"], 91716fd348SMartin Matuska "l2_comp": [21, -1, "L2ARC compression algorithm for buffer"], 92716fd348SMartin Matuska "aholds": [6, 1000, "number of holds on this ARC buffer"], 93716fd348SMartin Matuska "dtype": [27, -1, "dnode type"], 94716fd348SMartin Matuska "btype": [27, -1, "bonus buffer type"], 95716fd348SMartin Matuska "data_bs": [7, 1024, "data block size"], 96716fd348SMartin Matuska "meta_bs": [7, 1024, "metadata block size"], 97716fd348SMartin Matuska "bsize": [6, 1024, "bonus buffer size"], 98716fd348SMartin Matuska "lvls": [6, -1, "number of indirection levels"], 99716fd348SMartin Matuska "dholds": [6, 1000, "number of holds on dnode"], 100716fd348SMartin Matuska "blocks": [8, 1000, "number of allocated blocks"], 101716fd348SMartin Matuska "dsize": [12, 1024, "size of dnode"], 102716fd348SMartin Matuska "cached": [6, 1024, "bytes cached for all blocks"], 103716fd348SMartin Matuska "direct": [6, 1024, "bytes cached for direct blocks"], 104716fd348SMartin Matuska "indirect": [8, 1024, "bytes cached for indirect blocks"], 105716fd348SMartin Matuska "bonus": [5, 1024, "bytes cached for bonus buffer"], 106716fd348SMartin Matuska "spill": [5, 1024, "bytes cached for spill block"], 107716fd348SMartin Matuska} 108716fd348SMartin Matuska 109716fd348SMartin Matuskahdr = None 110716fd348SMartin Matuskaxhdr = None 111716fd348SMartin Matuskasep = " " # Default separator is 2 spaces 112716fd348SMartin Matuskacmd = ("Usage: dbufstat [-bdhnrtvx] [-i file] [-f fields] [-o file] " 113716fd348SMartin Matuska "[-s string] [-F filter]\n") 114716fd348SMartin Matuskaraw = 0 115716fd348SMartin Matuska 116716fd348SMartin Matuska 117716fd348SMartin Matuskaif sys.platform.startswith("freebsd"): 118716fd348SMartin Matuska import io 119716fd348SMartin Matuska # Requires py-sysctl on FreeBSD 120716fd348SMartin Matuska import sysctl 121716fd348SMartin Matuska 122716fd348SMartin Matuska def default_ifile(): 123716fd348SMartin Matuska dbufs = sysctl.filter("kstat.zfs.misc.dbufs")[0].value 124716fd348SMartin Matuska sys.stdin = io.StringIO(dbufs) 125716fd348SMartin Matuska return "-" 126716fd348SMartin Matuska 127716fd348SMartin Matuskaelif sys.platform.startswith("linux"): 128716fd348SMartin Matuska def default_ifile(): 129716fd348SMartin Matuska return "/proc/spl/kstat/zfs/dbufs" 130716fd348SMartin Matuska 131716fd348SMartin Matuska 132716fd348SMartin Matuskadef print_incompat_helper(incompat): 133716fd348SMartin Matuska cnt = 0 134716fd348SMartin Matuska for key in sorted(incompat): 135716fd348SMartin Matuska if cnt == 0: 136716fd348SMartin Matuska sys.stderr.write("\t") 137716fd348SMartin Matuska elif cnt > 8: 138716fd348SMartin Matuska sys.stderr.write(",\n\t") 139716fd348SMartin Matuska cnt = 0 140716fd348SMartin Matuska else: 141716fd348SMartin Matuska sys.stderr.write(", ") 142716fd348SMartin Matuska 143716fd348SMartin Matuska sys.stderr.write("%s" % key) 144716fd348SMartin Matuska cnt += 1 145716fd348SMartin Matuska 146716fd348SMartin Matuska sys.stderr.write("\n\n") 147716fd348SMartin Matuska 148716fd348SMartin Matuska 149716fd348SMartin Matuskadef detailed_usage(): 150716fd348SMartin Matuska sys.stderr.write("%s\n" % cmd) 151716fd348SMartin Matuska 152716fd348SMartin Matuska sys.stderr.write("Field definitions incompatible with '-b' option:\n") 153716fd348SMartin Matuska print_incompat_helper(bincompat) 154716fd348SMartin Matuska 155716fd348SMartin Matuska sys.stderr.write("Field definitions incompatible with '-d' option:\n") 156716fd348SMartin Matuska print_incompat_helper(dincompat) 157716fd348SMartin Matuska 158716fd348SMartin Matuska sys.stderr.write("Field definitions incompatible with '-t' option:\n") 159716fd348SMartin Matuska print_incompat_helper(tincompat) 160716fd348SMartin Matuska 161716fd348SMartin Matuska sys.stderr.write("Field definitions are as follows:\n") 162716fd348SMartin Matuska for key in sorted(cols.keys()): 163716fd348SMartin Matuska sys.stderr.write("%11s : %s\n" % (key, cols[key][2])) 164716fd348SMartin Matuska sys.stderr.write("\n") 165716fd348SMartin Matuska 166716fd348SMartin Matuska sys.exit(0) 167716fd348SMartin Matuska 168716fd348SMartin Matuska 169716fd348SMartin Matuskadef usage(): 170716fd348SMartin Matuska sys.stderr.write("%s\n" % cmd) 171716fd348SMartin Matuska sys.stderr.write("\t -b : Print table of information for each dbuf\n") 172716fd348SMartin Matuska sys.stderr.write("\t -d : Print table of information for each dnode\n") 173716fd348SMartin Matuska sys.stderr.write("\t -h : Print this help message\n") 174716fd348SMartin Matuska sys.stderr.write("\t -n : Exclude header from output\n") 175716fd348SMartin Matuska sys.stderr.write("\t -r : Print raw values\n") 176716fd348SMartin Matuska sys.stderr.write("\t -t : Print table of information for each dnode type" 177716fd348SMartin Matuska "\n") 178716fd348SMartin Matuska sys.stderr.write("\t -v : List all possible field headers and definitions" 179716fd348SMartin Matuska "\n") 180716fd348SMartin Matuska sys.stderr.write("\t -x : Print extended stats\n") 181716fd348SMartin Matuska sys.stderr.write("\t -i : Redirect input from the specified file\n") 182716fd348SMartin Matuska sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n") 183716fd348SMartin Matuska sys.stderr.write("\t -o : Redirect output to the specified file\n") 184716fd348SMartin Matuska sys.stderr.write("\t -s : Override default field separator with custom " 185716fd348SMartin Matuska "character or string\n") 186716fd348SMartin Matuska sys.stderr.write("\t -F : Filter output by value or regex\n") 187716fd348SMartin Matuska sys.stderr.write("\nExamples:\n") 188716fd348SMartin Matuska sys.stderr.write("\tdbufstat -d -o /tmp/d.log\n") 189716fd348SMartin Matuska sys.stderr.write("\tdbufstat -t -s \",\" -o /tmp/t.log\n") 190716fd348SMartin Matuska sys.stderr.write("\tdbufstat -v\n") 191716fd348SMartin Matuska sys.stderr.write("\tdbufstat -d -f pool,object,objset,dsize,cached\n") 192716fd348SMartin Matuska sys.stderr.write("\tdbufstat -bx -F dbc=1,objset=54,pool=testpool\n") 193716fd348SMartin Matuska sys.stderr.write("\n") 194716fd348SMartin Matuska 195716fd348SMartin Matuska sys.exit(1) 196716fd348SMartin Matuska 197716fd348SMartin Matuska 198716fd348SMartin Matuskadef prettynum(sz, scale, num=0): 199716fd348SMartin Matuska global raw 200716fd348SMartin Matuska 201716fd348SMartin Matuska suffix = [' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z'] 202716fd348SMartin Matuska index = 0 203716fd348SMartin Matuska save = 0 204716fd348SMartin Matuska 205716fd348SMartin Matuska if raw or scale == -1: 206716fd348SMartin Matuska return "%*s" % (sz, num) 207716fd348SMartin Matuska 208716fd348SMartin Matuska # Rounding error, return 0 209716fd348SMartin Matuska elif 0 < num < 1: 210716fd348SMartin Matuska num = 0 211716fd348SMartin Matuska 212716fd348SMartin Matuska while num > scale and index < 5: 213716fd348SMartin Matuska save = num 214716fd348SMartin Matuska num = num / scale 215716fd348SMartin Matuska index += 1 216716fd348SMartin Matuska 217716fd348SMartin Matuska if index == 0: 218716fd348SMartin Matuska return "%*d" % (sz, num) 219716fd348SMartin Matuska 220716fd348SMartin Matuska if (save / scale) < 10: 221716fd348SMartin Matuska return "%*.1f%s" % (sz - 1, num, suffix[index]) 222716fd348SMartin Matuska else: 223716fd348SMartin Matuska return "%*d%s" % (sz - 1, num, suffix[index]) 224716fd348SMartin Matuska 225716fd348SMartin Matuska 226716fd348SMartin Matuskadef print_values(v): 227716fd348SMartin Matuska global hdr 228716fd348SMartin Matuska global sep 229716fd348SMartin Matuska 230716fd348SMartin Matuska try: 231716fd348SMartin Matuska for col in hdr: 232716fd348SMartin Matuska sys.stdout.write("%s%s" % ( 233716fd348SMartin Matuska prettynum(cols[col][0], cols[col][1], v[col]), sep)) 234716fd348SMartin Matuska sys.stdout.write("\n") 235716fd348SMartin Matuska except IOError as e: 236716fd348SMartin Matuska if e.errno == errno.EPIPE: 237716fd348SMartin Matuska sys.exit(1) 238716fd348SMartin Matuska 239716fd348SMartin Matuska 240716fd348SMartin Matuskadef print_header(): 241716fd348SMartin Matuska global hdr 242716fd348SMartin Matuska global sep 243716fd348SMartin Matuska 244716fd348SMartin Matuska try: 245716fd348SMartin Matuska for col in hdr: 246716fd348SMartin Matuska sys.stdout.write("%*s%s" % (cols[col][0], col, sep)) 247716fd348SMartin Matuska sys.stdout.write("\n") 248716fd348SMartin Matuska except IOError as e: 249716fd348SMartin Matuska if e.errno == errno.EPIPE: 250716fd348SMartin Matuska sys.exit(1) 251716fd348SMartin Matuska 252716fd348SMartin Matuska 253716fd348SMartin Matuskadef get_typestring(t): 254716fd348SMartin Matuska ot_strings = [ 255716fd348SMartin Matuska "DMU_OT_NONE", 256716fd348SMartin Matuska # general: 257716fd348SMartin Matuska "DMU_OT_OBJECT_DIRECTORY", 258716fd348SMartin Matuska "DMU_OT_OBJECT_ARRAY", 259716fd348SMartin Matuska "DMU_OT_PACKED_NVLIST", 260716fd348SMartin Matuska "DMU_OT_PACKED_NVLIST_SIZE", 261716fd348SMartin Matuska "DMU_OT_BPOBJ", 262716fd348SMartin Matuska "DMU_OT_BPOBJ_HDR", 263716fd348SMartin Matuska # spa: 264716fd348SMartin Matuska "DMU_OT_SPACE_MAP_HEADER", 265716fd348SMartin Matuska "DMU_OT_SPACE_MAP", 266716fd348SMartin Matuska # zil: 267716fd348SMartin Matuska "DMU_OT_INTENT_LOG", 268716fd348SMartin Matuska # dmu: 269716fd348SMartin Matuska "DMU_OT_DNODE", 270716fd348SMartin Matuska "DMU_OT_OBJSET", 271716fd348SMartin Matuska # dsl: 272716fd348SMartin Matuska "DMU_OT_DSL_DIR", 273716fd348SMartin Matuska "DMU_OT_DSL_DIR_CHILD_MAP", 274716fd348SMartin Matuska "DMU_OT_DSL_DS_SNAP_MAP", 275716fd348SMartin Matuska "DMU_OT_DSL_PROPS", 276716fd348SMartin Matuska "DMU_OT_DSL_DATASET", 277716fd348SMartin Matuska # zpl: 278716fd348SMartin Matuska "DMU_OT_ZNODE", 279716fd348SMartin Matuska "DMU_OT_OLDACL", 280716fd348SMartin Matuska "DMU_OT_PLAIN_FILE_CONTENTS", 281716fd348SMartin Matuska "DMU_OT_DIRECTORY_CONTENTS", 282716fd348SMartin Matuska "DMU_OT_MASTER_NODE", 283716fd348SMartin Matuska "DMU_OT_UNLINKED_SET", 284716fd348SMartin Matuska # zvol: 285716fd348SMartin Matuska "DMU_OT_ZVOL", 286716fd348SMartin Matuska "DMU_OT_ZVOL_PROP", 287716fd348SMartin Matuska # other; for testing only! 288716fd348SMartin Matuska "DMU_OT_PLAIN_OTHER", 289716fd348SMartin Matuska "DMU_OT_UINT64_OTHER", 290716fd348SMartin Matuska "DMU_OT_ZAP_OTHER", 291716fd348SMartin Matuska # new object types: 292716fd348SMartin Matuska "DMU_OT_ERROR_LOG", 293716fd348SMartin Matuska "DMU_OT_SPA_HISTORY", 294716fd348SMartin Matuska "DMU_OT_SPA_HISTORY_OFFSETS", 295716fd348SMartin Matuska "DMU_OT_POOL_PROPS", 296716fd348SMartin Matuska "DMU_OT_DSL_PERMS", 297716fd348SMartin Matuska "DMU_OT_ACL", 298716fd348SMartin Matuska "DMU_OT_SYSACL", 299716fd348SMartin Matuska "DMU_OT_FUID", 300716fd348SMartin Matuska "DMU_OT_FUID_SIZE", 301716fd348SMartin Matuska "DMU_OT_NEXT_CLONES", 302716fd348SMartin Matuska "DMU_OT_SCAN_QUEUE", 303716fd348SMartin Matuska "DMU_OT_USERGROUP_USED", 304716fd348SMartin Matuska "DMU_OT_USERGROUP_QUOTA", 305716fd348SMartin Matuska "DMU_OT_USERREFS", 306716fd348SMartin Matuska "DMU_OT_DDT_ZAP", 307716fd348SMartin Matuska "DMU_OT_DDT_STATS", 308716fd348SMartin Matuska "DMU_OT_SA", 309716fd348SMartin Matuska "DMU_OT_SA_MASTER_NODE", 310716fd348SMartin Matuska "DMU_OT_SA_ATTR_REGISTRATION", 311716fd348SMartin Matuska "DMU_OT_SA_ATTR_LAYOUTS", 312716fd348SMartin Matuska "DMU_OT_SCAN_XLATE", 313716fd348SMartin Matuska "DMU_OT_DEDUP", 314716fd348SMartin Matuska "DMU_OT_DEADLIST", 315716fd348SMartin Matuska "DMU_OT_DEADLIST_HDR", 316716fd348SMartin Matuska "DMU_OT_DSL_CLONES", 317716fd348SMartin Matuska "DMU_OT_BPOBJ_SUBOBJ"] 318716fd348SMartin Matuska otn_strings = { 319716fd348SMartin Matuska 0x80: "DMU_OTN_UINT8_DATA", 320716fd348SMartin Matuska 0xc0: "DMU_OTN_UINT8_METADATA", 321716fd348SMartin Matuska 0x81: "DMU_OTN_UINT16_DATA", 322716fd348SMartin Matuska 0xc1: "DMU_OTN_UINT16_METADATA", 323716fd348SMartin Matuska 0x82: "DMU_OTN_UINT32_DATA", 324716fd348SMartin Matuska 0xc2: "DMU_OTN_UINT32_METADATA", 325716fd348SMartin Matuska 0x83: "DMU_OTN_UINT64_DATA", 326716fd348SMartin Matuska 0xc3: "DMU_OTN_UINT64_METADATA", 327716fd348SMartin Matuska 0x84: "DMU_OTN_ZAP_DATA", 328716fd348SMartin Matuska 0xc4: "DMU_OTN_ZAP_METADATA", 329716fd348SMartin Matuska 0xa0: "DMU_OTN_UINT8_ENC_DATA", 330716fd348SMartin Matuska 0xe0: "DMU_OTN_UINT8_ENC_METADATA", 331716fd348SMartin Matuska 0xa1: "DMU_OTN_UINT16_ENC_DATA", 332716fd348SMartin Matuska 0xe1: "DMU_OTN_UINT16_ENC_METADATA", 333716fd348SMartin Matuska 0xa2: "DMU_OTN_UINT32_ENC_DATA", 334716fd348SMartin Matuska 0xe2: "DMU_OTN_UINT32_ENC_METADATA", 335716fd348SMartin Matuska 0xa3: "DMU_OTN_UINT64_ENC_DATA", 336716fd348SMartin Matuska 0xe3: "DMU_OTN_UINT64_ENC_METADATA", 337716fd348SMartin Matuska 0xa4: "DMU_OTN_ZAP_ENC_DATA", 338716fd348SMartin Matuska 0xe4: "DMU_OTN_ZAP_ENC_METADATA"} 339716fd348SMartin Matuska 340716fd348SMartin Matuska # If "-rr" option is used, don't convert to string representation 341716fd348SMartin Matuska if raw > 1: 342716fd348SMartin Matuska return "%i" % t 343716fd348SMartin Matuska 344716fd348SMartin Matuska try: 345716fd348SMartin Matuska if t < len(ot_strings): 346716fd348SMartin Matuska return ot_strings[t] 347716fd348SMartin Matuska else: 348716fd348SMartin Matuska return otn_strings[t] 349716fd348SMartin Matuska except (IndexError, KeyError): 350716fd348SMartin Matuska return "(UNKNOWN)" 351716fd348SMartin Matuska 352716fd348SMartin Matuska 353716fd348SMartin Matuskadef get_compstring(c): 354716fd348SMartin Matuska comp_strings = ["ZIO_COMPRESS_INHERIT", "ZIO_COMPRESS_ON", 355716fd348SMartin Matuska "ZIO_COMPRESS_OFF", "ZIO_COMPRESS_LZJB", 356716fd348SMartin Matuska "ZIO_COMPRESS_EMPTY", "ZIO_COMPRESS_GZIP_1", 357716fd348SMartin Matuska "ZIO_COMPRESS_GZIP_2", "ZIO_COMPRESS_GZIP_3", 358716fd348SMartin Matuska "ZIO_COMPRESS_GZIP_4", "ZIO_COMPRESS_GZIP_5", 359716fd348SMartin Matuska "ZIO_COMPRESS_GZIP_6", "ZIO_COMPRESS_GZIP_7", 360716fd348SMartin Matuska "ZIO_COMPRESS_GZIP_8", "ZIO_COMPRESS_GZIP_9", 361716fd348SMartin Matuska "ZIO_COMPRESS_ZLE", "ZIO_COMPRESS_LZ4", 362716fd348SMartin Matuska "ZIO_COMPRESS_ZSTD", "ZIO_COMPRESS_FUNCTION"] 363716fd348SMartin Matuska 364716fd348SMartin Matuska # If "-rr" option is used, don't convert to string representation 365716fd348SMartin Matuska if raw > 1: 366716fd348SMartin Matuska return "%i" % c 367716fd348SMartin Matuska 368716fd348SMartin Matuska try: 369716fd348SMartin Matuska return comp_strings[c] 370716fd348SMartin Matuska except IndexError: 371716fd348SMartin Matuska return "%i" % c 372716fd348SMartin Matuska 373716fd348SMartin Matuska 374716fd348SMartin Matuskadef parse_line(line, labels): 375716fd348SMartin Matuska global hdr 376716fd348SMartin Matuska 377716fd348SMartin Matuska new = dict() 378716fd348SMartin Matuska val = None 379716fd348SMartin Matuska for col in hdr: 380716fd348SMartin Matuska # These are "special" fields computed in the update_dict 381716fd348SMartin Matuska # function, prevent KeyError exception on labels[col] for these. 382716fd348SMartin Matuska if col not in ['bonus', 'cached', 'direct', 'indirect', 'spill']: 383716fd348SMartin Matuska val = line[labels[col]] 384716fd348SMartin Matuska 385716fd348SMartin Matuska if col in ['pool', 'flags']: 386716fd348SMartin Matuska new[col] = str(val) 387716fd348SMartin Matuska elif col in ['dtype', 'btype']: 388716fd348SMartin Matuska new[col] = get_typestring(int(val)) 389716fd348SMartin Matuska elif col in ['l2_comp']: 390716fd348SMartin Matuska new[col] = get_compstring(int(val)) 391716fd348SMartin Matuska else: 392716fd348SMartin Matuska new[col] = int(val) 393716fd348SMartin Matuska 394716fd348SMartin Matuska return new 395716fd348SMartin Matuska 396716fd348SMartin Matuska 397716fd348SMartin Matuskadef update_dict(d, k, line, labels): 398716fd348SMartin Matuska pool = line[labels['pool']] 399716fd348SMartin Matuska objset = line[labels['objset']] 400716fd348SMartin Matuska key = line[labels[k]] 401716fd348SMartin Matuska 402716fd348SMartin Matuska dbsize = int(line[labels['dbsize']]) 403*a2b560ccSMartin Matuska usize = int(line[labels['usize']]) 404716fd348SMartin Matuska blkid = int(line[labels['blkid']]) 405716fd348SMartin Matuska level = int(line[labels['level']]) 406716fd348SMartin Matuska 407716fd348SMartin Matuska if pool not in d: 408716fd348SMartin Matuska d[pool] = dict() 409716fd348SMartin Matuska 410716fd348SMartin Matuska if objset not in d[pool]: 411716fd348SMartin Matuska d[pool][objset] = dict() 412716fd348SMartin Matuska 413716fd348SMartin Matuska if key not in d[pool][objset]: 414716fd348SMartin Matuska d[pool][objset][key] = parse_line(line, labels) 415716fd348SMartin Matuska d[pool][objset][key]['bonus'] = 0 416716fd348SMartin Matuska d[pool][objset][key]['cached'] = 0 417716fd348SMartin Matuska d[pool][objset][key]['direct'] = 0 418716fd348SMartin Matuska d[pool][objset][key]['indirect'] = 0 419716fd348SMartin Matuska d[pool][objset][key]['spill'] = 0 420716fd348SMartin Matuska 421*a2b560ccSMartin Matuska d[pool][objset][key]['cached'] += dbsize + usize 422716fd348SMartin Matuska 423716fd348SMartin Matuska if blkid == -1: 424716fd348SMartin Matuska d[pool][objset][key]['bonus'] += dbsize 425716fd348SMartin Matuska elif blkid == -2: 426716fd348SMartin Matuska d[pool][objset][key]['spill'] += dbsize 427716fd348SMartin Matuska else: 428716fd348SMartin Matuska if level == 0: 429716fd348SMartin Matuska d[pool][objset][key]['direct'] += dbsize 430716fd348SMartin Matuska else: 431716fd348SMartin Matuska d[pool][objset][key]['indirect'] += dbsize 432716fd348SMartin Matuska 433716fd348SMartin Matuska return d 434716fd348SMartin Matuska 435716fd348SMartin Matuska 436716fd348SMartin Matuskadef skip_line(vals, filters): 437716fd348SMartin Matuska ''' 438716fd348SMartin Matuska Determines if a line should be skipped during printing 439716fd348SMartin Matuska based on a set of filters 440716fd348SMartin Matuska ''' 441716fd348SMartin Matuska if len(filters) == 0: 442716fd348SMartin Matuska return False 443716fd348SMartin Matuska 444716fd348SMartin Matuska for key in vals: 445716fd348SMartin Matuska if key in filters: 446716fd348SMartin Matuska val = prettynum(cols[key][0], cols[key][1], vals[key]).strip() 447716fd348SMartin Matuska # we want a full match here 448716fd348SMartin Matuska if re.match("(?:" + filters[key] + r")\Z", val) is None: 449716fd348SMartin Matuska return True 450716fd348SMartin Matuska 451716fd348SMartin Matuska return False 452716fd348SMartin Matuska 453716fd348SMartin Matuska 454716fd348SMartin Matuskadef print_dict(d, filters, noheader): 455716fd348SMartin Matuska if not noheader: 456716fd348SMartin Matuska print_header() 457716fd348SMartin Matuska for pool in list(d.keys()): 458716fd348SMartin Matuska for objset in list(d[pool].keys()): 459716fd348SMartin Matuska for v in list(d[pool][objset].values()): 460716fd348SMartin Matuska if not skip_line(v, filters): 461716fd348SMartin Matuska print_values(v) 462716fd348SMartin Matuska 463716fd348SMartin Matuska 464716fd348SMartin Matuskadef dnodes_build_dict(filehandle): 465716fd348SMartin Matuska labels = dict() 466716fd348SMartin Matuska dnodes = dict() 467716fd348SMartin Matuska 468716fd348SMartin Matuska # First 3 lines are header information, skip the first two 469716fd348SMartin Matuska for i in range(2): 470716fd348SMartin Matuska next(filehandle) 471716fd348SMartin Matuska 472716fd348SMartin Matuska # The third line contains the labels and index locations 473716fd348SMartin Matuska for i, v in enumerate(next(filehandle).split()): 474716fd348SMartin Matuska labels[v] = i 475716fd348SMartin Matuska 476716fd348SMartin Matuska # The rest of the file is buffer information 477716fd348SMartin Matuska for line in filehandle: 478716fd348SMartin Matuska update_dict(dnodes, 'object', line.split(), labels) 479716fd348SMartin Matuska 480716fd348SMartin Matuska return dnodes 481716fd348SMartin Matuska 482716fd348SMartin Matuska 483716fd348SMartin Matuskadef types_build_dict(filehandle): 484716fd348SMartin Matuska labels = dict() 485716fd348SMartin Matuska types = dict() 486716fd348SMartin Matuska 487716fd348SMartin Matuska # First 3 lines are header information, skip the first two 488716fd348SMartin Matuska for i in range(2): 489716fd348SMartin Matuska next(filehandle) 490716fd348SMartin Matuska 491716fd348SMartin Matuska # The third line contains the labels and index locations 492716fd348SMartin Matuska for i, v in enumerate(next(filehandle).split()): 493716fd348SMartin Matuska labels[v] = i 494716fd348SMartin Matuska 495716fd348SMartin Matuska # The rest of the file is buffer information 496716fd348SMartin Matuska for line in filehandle: 497716fd348SMartin Matuska update_dict(types, 'dtype', line.split(), labels) 498716fd348SMartin Matuska 499716fd348SMartin Matuska return types 500716fd348SMartin Matuska 501716fd348SMartin Matuska 502716fd348SMartin Matuskadef buffers_print_all(filehandle, filters, noheader): 503716fd348SMartin Matuska labels = dict() 504716fd348SMartin Matuska 505716fd348SMartin Matuska # First 3 lines are header information, skip the first two 506716fd348SMartin Matuska for i in range(2): 507716fd348SMartin Matuska next(filehandle) 508716fd348SMartin Matuska 509716fd348SMartin Matuska # The third line contains the labels and index locations 510716fd348SMartin Matuska for i, v in enumerate(next(filehandle).split()): 511716fd348SMartin Matuska labels[v] = i 512716fd348SMartin Matuska 513716fd348SMartin Matuska if not noheader: 514716fd348SMartin Matuska print_header() 515716fd348SMartin Matuska 516716fd348SMartin Matuska # The rest of the file is buffer information 517716fd348SMartin Matuska for line in filehandle: 518716fd348SMartin Matuska vals = parse_line(line.split(), labels) 519716fd348SMartin Matuska if not skip_line(vals, filters): 520716fd348SMartin Matuska print_values(vals) 521716fd348SMartin Matuska 522716fd348SMartin Matuska 523716fd348SMartin Matuskadef main(): 524716fd348SMartin Matuska global hdr 525716fd348SMartin Matuska global sep 526716fd348SMartin Matuska global raw 527716fd348SMartin Matuska 528716fd348SMartin Matuska desired_cols = None 529716fd348SMartin Matuska bflag = False 530716fd348SMartin Matuska dflag = False 531716fd348SMartin Matuska hflag = False 532716fd348SMartin Matuska ifile = None 533716fd348SMartin Matuska ofile = None 534716fd348SMartin Matuska tflag = False 535716fd348SMartin Matuska vflag = False 536716fd348SMartin Matuska xflag = False 537716fd348SMartin Matuska nflag = False 538716fd348SMartin Matuska filters = dict() 539716fd348SMartin Matuska 540716fd348SMartin Matuska try: 541716fd348SMartin Matuska opts, args = getopt.getopt( 542716fd348SMartin Matuska sys.argv[1:], 543716fd348SMartin Matuska "bdf:hi:o:rs:tvxF:n", 544716fd348SMartin Matuska [ 545716fd348SMartin Matuska "buffers", 546716fd348SMartin Matuska "dnodes", 547716fd348SMartin Matuska "columns", 548716fd348SMartin Matuska "help", 549716fd348SMartin Matuska "infile", 550716fd348SMartin Matuska "outfile", 551716fd348SMartin Matuska "separator", 552716fd348SMartin Matuska "types", 553716fd348SMartin Matuska "verbose", 554716fd348SMartin Matuska "extended", 555716fd348SMartin Matuska "filter" 556716fd348SMartin Matuska ] 557716fd348SMartin Matuska ) 558716fd348SMartin Matuska except getopt.error: 559716fd348SMartin Matuska usage() 560716fd348SMartin Matuska opts = None 561716fd348SMartin Matuska 562716fd348SMartin Matuska for opt, arg in opts: 563716fd348SMartin Matuska if opt in ('-b', '--buffers'): 564716fd348SMartin Matuska bflag = True 565716fd348SMartin Matuska if opt in ('-d', '--dnodes'): 566716fd348SMartin Matuska dflag = True 567716fd348SMartin Matuska if opt in ('-f', '--columns'): 568716fd348SMartin Matuska desired_cols = arg 569716fd348SMartin Matuska if opt in ('-h', '--help'): 570716fd348SMartin Matuska hflag = True 571716fd348SMartin Matuska if opt in ('-i', '--infile'): 572716fd348SMartin Matuska ifile = arg 573716fd348SMartin Matuska if opt in ('-o', '--outfile'): 574716fd348SMartin Matuska ofile = arg 575716fd348SMartin Matuska if opt in ('-r', '--raw'): 576716fd348SMartin Matuska raw += 1 577716fd348SMartin Matuska if opt in ('-s', '--separator'): 578716fd348SMartin Matuska sep = arg 579716fd348SMartin Matuska if opt in ('-t', '--types'): 580716fd348SMartin Matuska tflag = True 581716fd348SMartin Matuska if opt in ('-v', '--verbose'): 582716fd348SMartin Matuska vflag = True 583716fd348SMartin Matuska if opt in ('-x', '--extended'): 584716fd348SMartin Matuska xflag = True 585716fd348SMartin Matuska if opt in ('-n', '--noheader'): 586716fd348SMartin Matuska nflag = True 587716fd348SMartin Matuska if opt in ('-F', '--filter'): 588716fd348SMartin Matuska fils = [x.strip() for x in arg.split(",")] 589716fd348SMartin Matuska 590716fd348SMartin Matuska for fil in fils: 591716fd348SMartin Matuska f = [x.strip() for x in fil.split("=")] 592716fd348SMartin Matuska 593716fd348SMartin Matuska if len(f) != 2: 594716fd348SMartin Matuska sys.stderr.write("Invalid filter '%s'.\n" % fil) 595716fd348SMartin Matuska sys.exit(1) 596716fd348SMartin Matuska 597716fd348SMartin Matuska if f[0] not in cols: 598716fd348SMartin Matuska sys.stderr.write("Invalid field '%s' in filter.\n" % f[0]) 599716fd348SMartin Matuska sys.exit(1) 600716fd348SMartin Matuska 601716fd348SMartin Matuska if f[0] in filters: 602716fd348SMartin Matuska sys.stderr.write("Field '%s' specified multiple times in " 603716fd348SMartin Matuska "filter.\n" % f[0]) 604716fd348SMartin Matuska sys.exit(1) 605716fd348SMartin Matuska 606716fd348SMartin Matuska try: 607716fd348SMartin Matuska re.compile("(?:" + f[1] + r")\Z") 608716fd348SMartin Matuska except re.error: 609716fd348SMartin Matuska sys.stderr.write("Invalid regex for field '%s' in " 610716fd348SMartin Matuska "filter.\n" % f[0]) 611716fd348SMartin Matuska sys.exit(1) 612716fd348SMartin Matuska 613716fd348SMartin Matuska filters[f[0]] = f[1] 614716fd348SMartin Matuska 615716fd348SMartin Matuska if hflag or (xflag and desired_cols): 616716fd348SMartin Matuska usage() 617716fd348SMartin Matuska 618716fd348SMartin Matuska if vflag: 619716fd348SMartin Matuska detailed_usage() 620716fd348SMartin Matuska 621716fd348SMartin Matuska # Ensure at most only one of b, d, or t flags are set 622716fd348SMartin Matuska if (bflag and dflag) or (bflag and tflag) or (dflag and tflag): 623716fd348SMartin Matuska usage() 624716fd348SMartin Matuska 625716fd348SMartin Matuska if bflag: 626716fd348SMartin Matuska hdr = bxhdr if xflag else bhdr 627716fd348SMartin Matuska elif tflag: 628716fd348SMartin Matuska hdr = txhdr if xflag else thdr 629716fd348SMartin Matuska else: # Even if dflag is False, it's the default if none set 630716fd348SMartin Matuska dflag = True 631716fd348SMartin Matuska hdr = dxhdr if xflag else dhdr 632716fd348SMartin Matuska 633716fd348SMartin Matuska if desired_cols: 634716fd348SMartin Matuska hdr = desired_cols.split(",") 635716fd348SMartin Matuska 636716fd348SMartin Matuska invalid = [] 637716fd348SMartin Matuska incompat = [] 638716fd348SMartin Matuska for ele in hdr: 639716fd348SMartin Matuska if ele not in cols: 640716fd348SMartin Matuska invalid.append(ele) 641716fd348SMartin Matuska elif ((bflag and bincompat and ele in bincompat) or 642716fd348SMartin Matuska (dflag and dincompat and ele in dincompat) or 643716fd348SMartin Matuska (tflag and tincompat and ele in tincompat)): 644716fd348SMartin Matuska incompat.append(ele) 645716fd348SMartin Matuska 646716fd348SMartin Matuska if len(invalid) > 0: 647716fd348SMartin Matuska sys.stderr.write("Invalid column definition! -- %s\n" % invalid) 648716fd348SMartin Matuska usage() 649716fd348SMartin Matuska 650716fd348SMartin Matuska if len(incompat) > 0: 651716fd348SMartin Matuska sys.stderr.write("Incompatible field specified! -- %s\n" % 652716fd348SMartin Matuska incompat) 653716fd348SMartin Matuska usage() 654716fd348SMartin Matuska 655716fd348SMartin Matuska if ofile: 656716fd348SMartin Matuska try: 657716fd348SMartin Matuska tmp = open(ofile, "w") 658716fd348SMartin Matuska sys.stdout = tmp 659716fd348SMartin Matuska 660716fd348SMartin Matuska except IOError: 661716fd348SMartin Matuska sys.stderr.write("Cannot open %s for writing\n" % ofile) 662716fd348SMartin Matuska sys.exit(1) 663716fd348SMartin Matuska 664716fd348SMartin Matuska if not ifile: 665716fd348SMartin Matuska ifile = default_ifile() 666716fd348SMartin Matuska 667716fd348SMartin Matuska if ifile != "-": 668716fd348SMartin Matuska try: 669716fd348SMartin Matuska tmp = open(ifile, "r") 670716fd348SMartin Matuska sys.stdin = tmp 671716fd348SMartin Matuska except IOError: 672716fd348SMartin Matuska sys.stderr.write("Cannot open %s for reading\n" % ifile) 673716fd348SMartin Matuska sys.exit(1) 674716fd348SMartin Matuska 675716fd348SMartin Matuska if bflag: 676716fd348SMartin Matuska buffers_print_all(sys.stdin, filters, nflag) 677716fd348SMartin Matuska 678716fd348SMartin Matuska if dflag: 679716fd348SMartin Matuska print_dict(dnodes_build_dict(sys.stdin), filters, nflag) 680716fd348SMartin Matuska 681716fd348SMartin Matuska if tflag: 682716fd348SMartin Matuska print_dict(types_build_dict(sys.stdin), filters, nflag) 683716fd348SMartin Matuska 684716fd348SMartin Matuska 685716fd348SMartin Matuskaif __name__ == '__main__': 686716fd348SMartin Matuska main() 687