1 #!/usr/bin/env @PYTHON_SHEBANG@
3 # Print out ZFS ARC Statistics exported via kstat(1)
4 # For a definition of fields, or usage, use arcstat -v
6 # This script was originally a fork of the original arcstat.pl (0.1)
7 # by Neelakanth Nadgir, originally published on his Sun blog on
9 # http://blogs.sun.com/realneel/entry/zfs_arc_statistics
11 # A new version aimed to improve upon the original by adding features
12 # and fixing bugs as needed. This version was maintained by Mike
13 # Harsch and was hosted in a public open source repository:
14 # http://github.com/mharsch/arcstat
16 # but has since moved to the illumos-gate repository.
18 # This Python port was written by John Hixson for FreeNAS, introduced
20 # https://github.com/freenas/freenas
22 # and has been improved by many people since.
26 # The contents of this file are subject to the terms of the
27 # Common Development and Distribution License, Version 1.0 only
28 # (the "License"). You may not use this file except in compliance
31 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
32 # or https://opensource.org/licenses/CDDL-1.0.
33 # See the License for the specific language governing permissions
34 # and limitations under the License.
36 # When distributing Covered Code, include this CDDL HEADER in each
37 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
38 # If applicable, add the following below this CDDL HEADER, with the
39 # fields enclosed by brackets "[]" replaced with your own identifying
40 # information: Portions Copyright [yyyy] [name of copyright owner]
45 # Fields have a fixed width. Every interval, we fill the "v"
46 # hash with its corresponding value (v[field]=value) using calculate().
47 # @hdr is the array of fields that needs to be printed, so we
48 # just iterate over this array and print the values using our pretty printer.
50 # This script must remain compatible with Python 3.6+.
59 from signal import signal, SIGINT, SIGWINCH, SIG_DFL
63 # HDR: [Size, Scale, Description]
64 "time": [8, -1, "Time"],
65 "hits": [4, 1000, "ARC hits per second"],
66 "iohs": [4, 1000, "ARC I/O hits per second"],
67 "miss": [4, 1000, "ARC misses per second"],
68 "read": [4, 1000, "Total ARC accesses per second"],
69 "hit%": [4, 100, "ARC hit percentage"],
70 "ioh%": [4, 100, "ARC I/O hit percentage"],
71 "miss%": [5, 100, "ARC miss percentage"],
72 "dhit": [4, 1000, "Demand hits per second"],
73 "dioh": [4, 1000, "Demand I/O hits per second"],
74 "dmis": [4, 1000, "Demand misses per second"],
75 "dh%": [3, 100, "Demand hit percentage"],
76 "di%": [3, 100, "Demand I/O hit percentage"],
77 "dm%": [3, 100, "Demand miss percentage"],
78 "ddhit": [5, 1000, "Demand data hits per second"],
79 "ddioh": [5, 1000, "Demand data I/O hits per second"],
80 "ddmis": [5, 1000, "Demand data misses per second"],
81 "ddh%": [4, 100, "Demand data hit percentage"],
82 "ddi%": [4, 100, "Demand data I/O hit percentage"],
83 "ddm%": [4, 100, "Demand data miss percentage"],
84 "dmhit": [5, 1000, "Demand metadata hits per second"],
85 "dmioh": [5, 1000, "Demand metadata I/O hits per second"],
86 "dmmis": [5, 1000, "Demand metadata misses per second"],
87 "dmh%": [4, 100, "Demand metadata hit percentage"],
88 "dmi%": [4, 100, "Demand metadata I/O hit percentage"],
89 "dmm%": [4, 100, "Demand metadata miss percentage"],
90 "phit": [4, 1000, "Prefetch hits per second"],
91 "pioh": [4, 1000, "Prefetch I/O hits per second"],
92 "pmis": [4, 1000, "Prefetch misses per second"],
93 "ph%": [3, 100, "Prefetch hits percentage"],
94 "pi%": [3, 100, "Prefetch I/O hits percentage"],
95 "pm%": [3, 100, "Prefetch miss percentage"],
96 "pdhit": [5, 1000, "Prefetch data hits per second"],
97 "pdioh": [5, 1000, "Prefetch data I/O hits per second"],
98 "pdmis": [5, 1000, "Prefetch data misses per second"],
99 "pdh%": [4, 100, "Prefetch data hits percentage"],
100 "pdi%": [4, 100, "Prefetch data I/O hits percentage"],
101 "pdm%": [4, 100, "Prefetch data miss percentage"],
102 "pmhit": [5, 1000, "Prefetch metadata hits per second"],
103 "pmioh": [5, 1000, "Prefetch metadata I/O hits per second"],
104 "pmmis": [5, 1000, "Prefetch metadata misses per second"],
105 "pmh%": [4, 100, "Prefetch metadata hits percentage"],
106 "pmi%": [4, 100, "Prefetch metadata I/O hits percentage"],
107 "pmm%": [4, 100, "Prefetch metadata miss percentage"],
108 "mhit": [4, 1000, "Metadata hits per second"],
109 "mioh": [4, 1000, "Metadata I/O hits per second"],
110 "mmis": [4, 1000, "Metadata misses per second"],
111 "mread": [5, 1000, "Metadata accesses per second"],
112 "mh%": [3, 100, "Metadata hit percentage"],
113 "mi%": [3, 100, "Metadata I/O hit percentage"],
114 "mm%": [3, 100, "Metadata miss percentage"],
115 "arcsz": [5, 1024, "ARC size"],
116 "size": [5, 1024, "ARC size"],
117 "c": [5, 1024, "ARC target size"],
118 "mfu": [4, 1000, "MFU list hits per second"],
119 "mru": [4, 1000, "MRU list hits per second"],
120 "mfug": [4, 1000, "MFU ghost list hits per second"],
121 "mrug": [4, 1000, "MRU ghost list hits per second"],
122 "unc": [4, 1000, "Uncached list hits per second"],
123 "eskip": [5, 1000, "evict_skip per second"],
124 "el2skip": [7, 1000, "evict skip, due to l2 writes, per second"],
125 "el2cach": [7, 1024, "Size of L2 cached evictions per second"],
126 "el2el": [5, 1024, "Size of L2 eligible evictions per second"],
127 "el2mfu": [6, 1024, "Size of L2 eligible MFU evictions per second"],
128 "el2mru": [6, 1024, "Size of L2 eligible MRU evictions per second"],
129 "el2inel": [7, 1024, "Size of L2 ineligible evictions per second"],
130 "mtxmis": [6, 1000, "mutex_miss per second"],
131 "dread": [5, 1000, "Demand accesses per second"],
132 "ddread": [6, 1000, "Demand data accesses per second"],
133 "dmread": [6, 1000, "Demand metadata accesses per second"],
134 "pread": [5, 1000, "Prefetch accesses per second"],
135 "pdread": [6, 1000, "Prefetch data accesses per second"],
136 "pmread": [6, 1000, "Prefetch metadata accesses per second"],
137 "l2hits": [6, 1000, "L2ARC hits per second"],
138 "l2miss": [6, 1000, "L2ARC misses per second"],
139 "l2read": [6, 1000, "Total L2ARC accesses per second"],
140 "l2hit%": [6, 100, "L2ARC access hit percentage"],
141 "l2miss%": [7, 100, "L2ARC access miss percentage"],
142 "l2pref": [6, 1024, "L2ARC prefetch allocated size"],
143 "l2mfu": [5, 1024, "L2ARC MFU allocated size"],
144 "l2mru": [5, 1024, "L2ARC MRU allocated size"],
145 "l2data": [6, 1024, "L2ARC data allocated size"],
146 "l2meta": [6, 1024, "L2ARC metadata allocated size"],
147 "l2pref%": [7, 100, "L2ARC prefetch percentage"],
148 "l2mfu%": [6, 100, "L2ARC MFU percentage"],
149 "l2mru%": [6, 100, "L2ARC MRU percentage"],
150 "l2data%": [7, 100, "L2ARC data percentage"],
151 "l2meta%": [7, 100, "L2ARC metadata percentage"],
152 "l2asize": [7, 1024, "Actual (compressed) size of the L2ARC"],
153 "l2size": [6, 1024, "Size of the L2ARC"],
154 "l2bytes": [7, 1024, "Bytes read per second from the L2ARC"],
155 "l2wbytes": [8, 1024, "Bytes written per second to the L2ARC"],
156 "grow": [4, 1000, "ARC grow disabled"],
157 "need": [5, 1024, "ARC reclaim need"],
158 "free": [5, 1024, "ARC free memory"],
159 "avail": [5, 1024, "ARC available memory"],
160 "waste": [5, 1024, "Wasted memory due to round up to pagesize"],
161 "ztotal": [6, 1000, "zfetch total prefetcher calls per second"],
162 "zhits": [5, 1000, "zfetch stream hits per second"],
163 "zahead": [6, 1000, "zfetch hits ahead of streams per second"],
164 "zpast": [5, 1000, "zfetch hits behind streams per second"],
165 "zmisses": [7, 1000, "zfetch stream misses per second"],
166 "zmax": [4, 1000, "zfetch limit reached per second"],
167 "zfuture": [7, 1000, "zfetch stream future per second"],
168 "zstride": [7, 1000, "zfetch stream strides per second"],
169 "zissued": [7, 1000, "zfetch prefetches issued per second"],
170 "zactive": [7, 1000, "zfetch prefetches active per second"],
173 # ARC structural breakdown from arc_summary
175 "cmp": ["compressed", "Compressed"],
176 "ovh": ["overhead", "Overhead"],
177 "bon": ["bonus", "Bonus"],
178 "dno": ["dnode", "Dnode"],
179 "dbu": ["dbuf", "Dbuf"],
180 "hdr": ["hdr", "Header"],
181 "l2h": ["l2_hdr", "L2 header"],
182 "abd": ["abd_chunk_waste", "ABD chunk waste"],
184 structstats = { # size stats
185 "percent": "size", # percentage of this value
186 "sz": ["_size", "size"],
189 # ARC types breakdown from arc_summary
191 "data": ["data", "ARC data"],
192 "meta": ["metadata", "ARC metadata"],
194 typestats = { # size stats
195 "percent": "cachessz", # percentage of this value
196 "tg": ["_target", "target"],
197 "sz": ["_size", "size"],
200 # ARC states breakdown from arc_summary
202 "ano": ["anon", "Anonymous"],
203 "mfu": ["mfu", "MFU"],
204 "mru": ["mru", "MRU"],
205 "unc": ["uncached", "Uncached"],
208 "percent": "cachessz", # percentage of this value
209 "fields": ["mfu", "mru"], # only applicable to these fields
210 "tg": ["_target", "target"],
211 "dt": ["_data_target", "data target"],
212 "mt": ["_metadata_target", "metadata target"],
214 statestats = { # size stats
215 "percent": "cachessz", # percentage of this value
216 "sz": ["_size", "size"],
217 "da": ["_data", "data size"],
218 "me": ["_metadata", "metadata size"],
219 "ed": ["_evictable_data", "evictable data size"],
220 "em": ["_evictable_metadata", "evictable metadata size"],
223 "fields": ["mfu", "mru"], # only applicable to these fields
224 "gsz": ["_ghost_size", "ghost size"],
225 "gd": ["_ghost_data", "ghost data size"],
226 "gm": ["_ghost_metadata", "ghost metadata size"],
231 [structfields, structstats],
232 [typefields, typestats],
233 [statefields, targetstats, statestats, ghoststats],
235 for fs in fieldstats:
236 fields, stats = fs[0], fs[1:]
237 for field, fieldval in fields.items():
239 for stat, statval in group.items():
240 if stat in ["fields", "percent"] or \
241 ("fields" in group and field not in group["fields"]):
243 colname = field + stat
244 coldesc = fieldval[1] + " " + statval[1]
245 cols[colname] = [len(colname), 1024, coldesc]
246 if "percent" in group:
247 cols[colname + "%"] = [len(colname) + 1, 100, \
248 coldesc + " percentage"]
251 hdr = ["time", "read", "ddread", "ddh%", "dmread", "dmh%", "pread", "ph%",
252 "size", "c", "avail"]
253 xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis",
254 "dread", "pread", "read"]
255 zhdr = ["time", "ztotal", "zhits", "zahead", "zpast", "zmisses", "zmax",
256 "zfuture", "zstride", "zissued", "zactive"]
257 sint = 1 # Default interval is 1 second
258 count = 1 # Default count is 1
259 hdr_intr = 20 # Print header every 20 lines of output
261 sep = " " # Default separator is 2 spaces
263 cmd = ("Usage: arcstat [-havxp] [-f fields] [-o file] [-s string] [interval "
272 if sys.platform.startswith('freebsd'):
273 # Requires py-sysctl on FreeBSD
279 k = [ctl for ctl in sysctl.filter('kstat.zfs.misc.arcstats')
280 if ctl.type != sysctl.CTLTYPE_NODE]
281 k += [ctl for ctl in sysctl.filter('kstat.zfs.misc.zfetchstats')
282 if ctl.type != sysctl.CTLTYPE_NODE]
293 name, value = s.name, s.value
295 if "arcstats" in name:
296 # Trims 'kstat.zfs.misc.arcstats' from the name
297 kstat[name[24:]] = int(value)
299 kstat["zfetch_" + name[27:]] = int(value)
301 elif sys.platform.startswith('linux'):
305 k1 = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')]
307 k2 = ["zfetch_" + line.strip() for line in
308 open('/proc/spl/kstat/zfs/zfetchstats')]
310 if k1 is None or k2 is None:
322 name, unused, value = s.split()
323 kstat[name] = int(value)
326 def detailed_usage():
327 sys.stderr.write("%s\n" % cmd)
328 sys.stderr.write("Field definitions are as follows:\n")
330 sys.stderr.write("%11s : %s\n" % (key, cols[key][2]))
331 sys.stderr.write("\n")
337 sys.stderr.write("%s\n" % cmd)
338 sys.stderr.write("\t -h : Print this help message\n")
339 sys.stderr.write("\t -a : Print all possible stats\n")
340 sys.stderr.write("\t -v : List all possible field headers and definitions"
342 sys.stderr.write("\t -x : Print extended stats\n")
343 sys.stderr.write("\t -z : Print zfetch stats\n")
344 sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n")
345 sys.stderr.write("\t -o : Redirect output to the specified file\n")
346 sys.stderr.write("\t -s : Override default field separator with custom "
347 "character or string\n")
348 sys.stderr.write("\t -p : Disable auto-scaling of numerical fields\n")
349 sys.stderr.write("\nExamples:\n")
350 sys.stderr.write("\tarcstat -o /tmp/a.log 2 10\n")
351 sys.stderr.write("\tarcstat -s \",\" -o /tmp/a.log 2 10\n")
352 sys.stderr.write("\tarcstat -v\n")
353 sys.stderr.write("\tarcstat -f time,hit%,dh%,ph%,mh% 1\n")
354 sys.stderr.write("\n")
363 prev = copy.deepcopy(cur)
368 # fill in additional values from arc_summary
369 cur["caches_size"] = caches_size = cur["anon_data"]+cur["anon_metadata"]+\
370 cur["mfu_data"]+cur["mfu_metadata"]+cur["mru_data"]+cur["mru_metadata"]+\
371 cur["uncached_data"]+cur["uncached_metadata"]
376 v = (s-int(pd))*(s-int(meta))/s
377 cur["mfu_data_target"] = v / 65536 * caches_size / 65536
378 v = (s-int(pm))*int(meta)/s
379 cur["mfu_metadata_target"] = v / 65536 * caches_size / 65536
380 v = int(pd)*(s-int(meta))/s
381 cur["mru_data_target"] = v / 65536 * caches_size / 65536
382 v = int(pm)*int(meta)/s
383 cur["mru_metadata_target"] = v / 65536 * caches_size / 65536
385 cur["data_target"] = cur["mfu_data_target"] + cur["mru_data_target"]
386 cur["metadata_target"] = cur["mfu_metadata_target"] + cur["mru_metadata_target"]
387 cur["mfu_target"] = cur["mfu_data_target"] + cur["mfu_metadata_target"]
388 cur["mru_target"] = cur["mru_data_target"] + cur["mru_metadata_target"]
391 if re.match(key, "class"):
394 d[key] = cur[key] - prev[key]
400 if isinstance(num, float):
401 return num.is_integer()
402 if isinstance(num, int):
407 def prettynum(sz, scale, num=0):
408 suffix = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']
411 # Special case for date field
416 while abs(num) > scale and index < 5:
420 width = sz - (0 if index == 0 else 1)
421 intlen = len("%.0f" % num) # %.0f rounds to nearest int
422 if sint == 1 and isint(num) or width < intlen + 2:
426 return "%*.*f%s" % (width, decimal, num, suffix[index])
436 fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col])
438 fmt = lambda col: str(v[col])
440 sys.stdout.write(sep.join(fmt(col) for col in hdr))
441 sys.stdout.write("\n")
451 fmt = lambda col: "%*s" % (cols[col][0], col)
453 fmt = lambda col: col
455 sys.stdout.write(sep.join(fmt(col) for col in hdr))
456 sys.stdout.write("\n")
459 def get_terminal_lines():
464 data = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, '1234')
465 sz = struct.unpack('hh', data)
471 def update_hdr_intr():
474 lines = get_terminal_lines()
475 if lines and lines > 3:
479 def resize_handler(signum, frame):
504 opts, args = getopt.getopt(
519 except getopt.error as msg:
520 sys.stderr.write("Error: %s\n" % str(msg))
524 for opt, arg in opts:
525 if opt in ('-a', '--all'):
527 if opt in ('-x', '--extended'):
529 if opt in ('-o', '--outfile'):
532 if opt in ('-h', '--help'):
534 if opt in ('-v', '--verbose'):
536 if opt in ('-s', '--separator'):
539 if opt in ('-f', '--columns'):
542 if opt in ('-p', '--parsable'):
544 if opt in ('-z', '--zfetch'):
549 sint = int(argv[0]) if argv else sint
550 count = int(argv[1]) if len(argv) > 1 else (0 if len(argv) > 0 else 1)
552 if hflag or (xflag and zflag) or ((zflag or xflag) and desired_cols):
566 # check if L2ARC exists
568 l2_size = cur.get("l2_size")
573 hdr = desired_cols.split(",")
580 elif not l2exist and ele.startswith("l2"):
581 sys.stdout.write("No L2ARC Here\n%s\n" % ele)
585 sys.stderr.write("Invalid column definition! -- %s\n" % invalid)
588 if len(incompat) > 0:
589 sys.stderr.write("Incompatible field specified! -- %s\n" %
597 hdr = [col for col in cols.keys() if not col.startswith("l2")]
601 out = open(opfile, "w")
605 sys.stderr.write("Cannot open %s for writing\n" % opfile)
615 v["time"] = time.strftime("%H:%M:%S", time.localtime())
616 v["hits"] = d["hits"] / sint
617 v["iohs"] = d["iohits"] / sint
618 v["miss"] = d["misses"] / sint
619 v["read"] = v["hits"] + v["iohs"] + v["miss"]
620 v["hit%"] = 100 * v["hits"] / v["read"] if v["read"] > 0 else 0
621 v["ioh%"] = 100 * v["iohs"] / v["read"] if v["read"] > 0 else 0
622 v["miss%"] = 100 - v["hit%"] - v["ioh%"] if v["read"] > 0 else 0
624 v["dhit"] = (d["demand_data_hits"] + d["demand_metadata_hits"]) / sint
625 v["dioh"] = (d["demand_data_iohits"] + d["demand_metadata_iohits"]) / sint
626 v["dmis"] = (d["demand_data_misses"] + d["demand_metadata_misses"]) / sint
628 v["dread"] = v["dhit"] + v["dioh"] + v["dmis"]
629 v["dh%"] = 100 * v["dhit"] / v["dread"] if v["dread"] > 0 else 0
630 v["di%"] = 100 * v["dioh"] / v["dread"] if v["dread"] > 0 else 0
631 v["dm%"] = 100 - v["dh%"] - v["di%"] if v["dread"] > 0 else 0
633 v["ddhit"] = d["demand_data_hits"] / sint
634 v["ddioh"] = d["demand_data_iohits"] / sint
635 v["ddmis"] = d["demand_data_misses"] / sint
637 v["ddread"] = v["ddhit"] + v["ddioh"] + v["ddmis"]
638 v["ddh%"] = 100 * v["ddhit"] / v["ddread"] if v["ddread"] > 0 else 0
639 v["ddi%"] = 100 * v["ddioh"] / v["ddread"] if v["ddread"] > 0 else 0
640 v["ddm%"] = 100 - v["ddh%"] - v["ddi%"] if v["ddread"] > 0 else 0
642 v["dmhit"] = d["demand_metadata_hits"] / sint
643 v["dmioh"] = d["demand_metadata_iohits"] / sint
644 v["dmmis"] = d["demand_metadata_misses"] / sint
646 v["dmread"] = v["dmhit"] + v["dmioh"] + v["dmmis"]
647 v["dmh%"] = 100 * v["dmhit"] / v["dmread"] if v["dmread"] > 0 else 0
648 v["dmi%"] = 100 * v["dmioh"] / v["dmread"] if v["dmread"] > 0 else 0
649 v["dmm%"] = 100 - v["dmh%"] - v["dmi%"] if v["dmread"] > 0 else 0
651 v["phit"] = (d["prefetch_data_hits"] + d["prefetch_metadata_hits"]) / sint
652 v["pioh"] = (d["prefetch_data_iohits"] +
653 d["prefetch_metadata_iohits"]) / sint
654 v["pmis"] = (d["prefetch_data_misses"] +
655 d["prefetch_metadata_misses"]) / sint
657 v["pread"] = v["phit"] + v["pioh"] + v["pmis"]
658 v["ph%"] = 100 * v["phit"] / v["pread"] if v["pread"] > 0 else 0
659 v["pi%"] = 100 * v["pioh"] / v["pread"] if v["pread"] > 0 else 0
660 v["pm%"] = 100 - v["ph%"] - v["pi%"] if v["pread"] > 0 else 0
662 v["pdhit"] = d["prefetch_data_hits"] / sint
663 v["pdioh"] = d["prefetch_data_iohits"] / sint
664 v["pdmis"] = d["prefetch_data_misses"] / sint
666 v["pdread"] = v["pdhit"] + v["pdioh"] + v["pdmis"]
667 v["pdh%"] = 100 * v["pdhit"] / v["pdread"] if v["pdread"] > 0 else 0
668 v["pdi%"] = 100 * v["pdioh"] / v["pdread"] if v["pdread"] > 0 else 0
669 v["pdm%"] = 100 - v["pdh%"] - v["pdi%"] if v["pdread"] > 0 else 0
671 v["pmhit"] = d["prefetch_metadata_hits"] / sint
672 v["pmioh"] = d["prefetch_metadata_iohits"] / sint
673 v["pmmis"] = d["prefetch_metadata_misses"] / sint
675 v["pmread"] = v["pmhit"] + v["pmioh"] + v["pmmis"]
676 v["pmh%"] = 100 * v["pmhit"] / v["pmread"] if v["pmread"] > 0 else 0
677 v["pmi%"] = 100 * v["pmioh"] / v["pmread"] if v["pmread"] > 0 else 0
678 v["pmm%"] = 100 - v["pmh%"] - v["pmi%"] if v["pmread"] > 0 else 0
680 v["mhit"] = (d["prefetch_metadata_hits"] +
681 d["demand_metadata_hits"]) / sint
682 v["mioh"] = (d["prefetch_metadata_iohits"] +
683 d["demand_metadata_iohits"]) / sint
684 v["mmis"] = (d["prefetch_metadata_misses"] +
685 d["demand_metadata_misses"]) / sint
687 v["mread"] = v["mhit"] + v["mioh"] + v["mmis"]
688 v["mh%"] = 100 * v["mhit"] / v["mread"] if v["mread"] > 0 else 0
689 v["mi%"] = 100 * v["mioh"] / v["mread"] if v["mread"] > 0 else 0
690 v["mm%"] = 100 - v["mh%"] - v["mi%"] if v["mread"] > 0 else 0
692 v["arcsz"] = cur["size"]
693 v["size"] = cur["size"]
695 v["mfu"] = d["mfu_hits"] / sint
696 v["mru"] = d["mru_hits"] / sint
697 v["mrug"] = d["mru_ghost_hits"] / sint
698 v["mfug"] = d["mfu_ghost_hits"] / sint
699 v["unc"] = d["uncached_hits"] / sint
700 v["eskip"] = d["evict_skip"] / sint
701 v["el2skip"] = d["evict_l2_skip"] / sint
702 v["el2cach"] = d["evict_l2_cached"] / sint
703 v["el2el"] = d["evict_l2_eligible"] / sint
704 v["el2mfu"] = d["evict_l2_eligible_mfu"] / sint
705 v["el2mru"] = d["evict_l2_eligible_mru"] / sint
706 v["el2inel"] = d["evict_l2_ineligible"] / sint
707 v["mtxmis"] = d["mutex_miss"] / sint
708 v["ztotal"] = (d["zfetch_hits"] + d["zfetch_future"] + d["zfetch_stride"] +
709 d["zfetch_past"] + d["zfetch_misses"]) / sint
710 v["zhits"] = d["zfetch_hits"] / sint
711 v["zahead"] = (d["zfetch_future"] + d["zfetch_stride"]) / sint
712 v["zpast"] = d["zfetch_past"] / sint
713 v["zmisses"] = d["zfetch_misses"] / sint
714 v["zmax"] = d["zfetch_max_streams"] / sint
715 v["zfuture"] = d["zfetch_future"] / sint
716 v["zstride"] = d["zfetch_stride"] / sint
717 v["zissued"] = d["zfetch_io_issued"] / sint
718 v["zactive"] = d["zfetch_io_active"] / sint
720 # ARC structural breakdown, ARC types breakdown, ARC states breakdown
721 v["cachessz"] = cur["caches_size"]
722 for fs in fieldstats:
723 fields, stats = fs[0], fs[1:]
724 for field, fieldval in fields.items():
726 for stat, statval in group.items():
727 if stat in ["fields", "percent"] or \
728 ("fields" in group and field not in group["fields"]):
730 colname = field + stat
731 v[colname] = cur[fieldval[0] + statval[0]]
732 if "percent" in group:
733 v[colname + "%"] = 100 * v[colname] / \
734 v[group["percent"]] if v[group["percent"]] > 0 else 0
737 v["l2hits"] = d["l2_hits"] / sint
738 v["l2miss"] = d["l2_misses"] / sint
739 v["l2read"] = v["l2hits"] + v["l2miss"]
740 v["l2hit%"] = 100 * v["l2hits"] / v["l2read"] if v["l2read"] > 0 else 0
742 v["l2miss%"] = 100 - v["l2hit%"] if v["l2read"] > 0 else 0
743 v["l2asize"] = cur["l2_asize"]
744 v["l2size"] = cur["l2_size"]
745 v["l2bytes"] = d["l2_read_bytes"] / sint
746 v["l2wbytes"] = d["l2_write_bytes"] / sint
748 v["l2pref"] = cur["l2_prefetch_asize"]
749 v["l2mfu"] = cur["l2_mfu_asize"]
750 v["l2mru"] = cur["l2_mru_asize"]
751 v["l2data"] = cur["l2_bufc_data_asize"]
752 v["l2meta"] = cur["l2_bufc_metadata_asize"]
753 v["l2pref%"] = 100 * v["l2pref"] / v["l2asize"]
754 v["l2mfu%"] = 100 * v["l2mfu"] / v["l2asize"]
755 v["l2mru%"] = 100 * v["l2mru"] / v["l2asize"]
756 v["l2data%"] = 100 * v["l2data"] / v["l2asize"]
757 v["l2meta%"] = 100 * v["l2meta"] / v["l2asize"]
759 v["grow"] = 0 if cur["arc_no_grow"] else 1
760 v["need"] = cur["arc_need_free"]
761 v["free"] = cur["memory_free_bytes"]
762 v["avail"] = cur["memory_available_bytes"]
763 v["waste"] = cur["abd_chunk_waste_size"]
778 signal(SIGINT, SIG_DFL)
779 signal(SIGWINCH, resize_handler)
793 i = 0 if i >= hdr_intr else i + 1
800 if __name__ == '__main__':