]> git.proxmox.com Git - mirror_zfs.git/blob - cmd/arcstat.in
ddt: reduce DDT_NAMELEN
[mirror_zfs.git] / cmd / arcstat.in
1 #!/usr/bin/env @PYTHON_SHEBANG@
2 #
3 # Print out ZFS ARC Statistics exported via kstat(1)
4 # For a definition of fields, or usage, use arcstat -v
5 #
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
8 # 09/18/2007
9 # http://blogs.sun.com/realneel/entry/zfs_arc_statistics
10 #
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
15 #
16 # but has since moved to the illumos-gate repository.
17 #
18 # This Python port was written by John Hixson for FreeNAS, introduced
19 # in commit e2c29f:
20 # https://github.com/freenas/freenas
21 #
22 # and has been improved by many people since.
23 #
24 # CDDL HEADER START
25 #
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
29 # with the License.
30 #
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.
35 #
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]
41 #
42 # CDDL HEADER END
43 #
44 #
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.
49 #
50 # This script must remain compatible with Python 3.6+.
51 #
52
53 import sys
54 import time
55 import getopt
56 import re
57 import copy
58
59 from signal import signal, SIGINT, SIGWINCH, SIG_DFL
60
61
62 cols = {
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 "grow": [4, 1000, "ARC grow disabled"],
156 "need": [5, 1024, "ARC reclaim need"],
157 "free": [5, 1024, "ARC free memory"],
158 "avail": [5, 1024, "ARC available memory"],
159 "waste": [5, 1024, "Wasted memory due to round up to pagesize"],
160 }
161
162 v = {}
163 hdr = ["time", "read", "ddread", "ddh%", "dmread", "dmh%", "pread", "ph%",
164 "size", "c", "avail"]
165 xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis",
166 "dread", "pread", "read"]
167 sint = 1 # Default interval is 1 second
168 count = 1 # Default count is 1
169 hdr_intr = 20 # Print header every 20 lines of output
170 opfile = None
171 sep = " " # Default separator is 2 spaces
172 l2exist = False
173 cmd = ("Usage: arcstat [-havxp] [-f fields] [-o file] [-s string] [interval "
174 "[count]]\n")
175 cur = {}
176 d = {}
177 out = None
178 kstat = None
179 pretty_print = True
180
181
182 if sys.platform.startswith('freebsd'):
183 # Requires py-sysctl on FreeBSD
184 import sysctl
185
186 def kstat_update():
187 global kstat
188
189 k = [ctl for ctl in sysctl.filter('kstat.zfs.misc.arcstats')
190 if ctl.type != sysctl.CTLTYPE_NODE]
191
192 if not k:
193 sys.exit(1)
194
195 kstat = {}
196
197 for s in k:
198 if not s:
199 continue
200
201 name, value = s.name, s.value
202 # Trims 'kstat.zfs.misc.arcstats' from the name
203 kstat[name[24:]] = int(value)
204
205 elif sys.platform.startswith('linux'):
206 def kstat_update():
207 global kstat
208
209 k = [line.strip() for line in open('/proc/spl/kstat/zfs/arcstats')]
210
211 if not k:
212 sys.exit(1)
213
214 del k[0:2]
215 kstat = {}
216
217 for s in k:
218 if not s:
219 continue
220
221 name, unused, value = s.split()
222 kstat[name] = int(value)
223
224
225 def detailed_usage():
226 sys.stderr.write("%s\n" % cmd)
227 sys.stderr.write("Field definitions are as follows:\n")
228 for key in cols:
229 sys.stderr.write("%11s : %s\n" % (key, cols[key][2]))
230 sys.stderr.write("\n")
231
232 sys.exit(0)
233
234
235 def usage():
236 sys.stderr.write("%s\n" % cmd)
237 sys.stderr.write("\t -h : Print this help message\n")
238 sys.stderr.write("\t -a : Print all possible stats\n")
239 sys.stderr.write("\t -v : List all possible field headers and definitions"
240 "\n")
241 sys.stderr.write("\t -x : Print extended stats\n")
242 sys.stderr.write("\t -f : Specify specific fields to print (see -v)\n")
243 sys.stderr.write("\t -o : Redirect output to the specified file\n")
244 sys.stderr.write("\t -s : Override default field separator with custom "
245 "character or string\n")
246 sys.stderr.write("\t -p : Disable auto-scaling of numerical fields\n")
247 sys.stderr.write("\nExamples:\n")
248 sys.stderr.write("\tarcstat -o /tmp/a.log 2 10\n")
249 sys.stderr.write("\tarcstat -s \",\" -o /tmp/a.log 2 10\n")
250 sys.stderr.write("\tarcstat -v\n")
251 sys.stderr.write("\tarcstat -f time,hit%,dh%,ph%,mh% 1\n")
252 sys.stderr.write("\n")
253
254 sys.exit(1)
255
256
257 def snap_stats():
258 global cur
259 global kstat
260
261 prev = copy.deepcopy(cur)
262 kstat_update()
263
264 cur = kstat
265 for key in cur:
266 if re.match(key, "class"):
267 continue
268 if key in prev:
269 d[key] = cur[key] - prev[key]
270 else:
271 d[key] = cur[key]
272
273
274 def prettynum(sz, scale, num=0):
275 suffix = [' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']
276 index = 0
277 save = 0
278
279 # Special case for date field
280 if scale == -1:
281 return "%s" % num
282
283 # Rounding error, return 0
284 elif 0 < num < 1:
285 num = 0
286
287 while abs(num) > scale and index < 5:
288 save = num
289 num = num / scale
290 index += 1
291
292 if index == 0:
293 return "%*d" % (sz, num)
294
295 if abs(save / scale) < 10:
296 return "%*.1f%s" % (sz - 1, num, suffix[index])
297 else:
298 return "%*d%s" % (sz - 1, num, suffix[index])
299
300
301 def print_values():
302 global hdr
303 global sep
304 global v
305 global pretty_print
306
307 if pretty_print:
308 fmt = lambda col: prettynum(cols[col][0], cols[col][1], v[col])
309 else:
310 fmt = lambda col: str(v[col])
311
312 sys.stdout.write(sep.join(fmt(col) for col in hdr))
313 sys.stdout.write("\n")
314 sys.stdout.flush()
315
316
317 def print_header():
318 global hdr
319 global sep
320 global pretty_print
321
322 if pretty_print:
323 fmt = lambda col: "%*s" % (cols[col][0], col)
324 else:
325 fmt = lambda col: col
326
327 sys.stdout.write(sep.join(fmt(col) for col in hdr))
328 sys.stdout.write("\n")
329
330
331 def get_terminal_lines():
332 try:
333 import fcntl
334 import termios
335 import struct
336 data = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, '1234')
337 sz = struct.unpack('hh', data)
338 return sz[0]
339 except Exception:
340 pass
341
342
343 def update_hdr_intr():
344 global hdr_intr
345
346 lines = get_terminal_lines()
347 if lines and lines > 3:
348 hdr_intr = lines - 3
349
350
351 def resize_handler(signum, frame):
352 update_hdr_intr()
353
354
355 def init():
356 global sint
357 global count
358 global hdr
359 global xhdr
360 global opfile
361 global sep
362 global out
363 global l2exist
364 global pretty_print
365
366 desired_cols = None
367 aflag = False
368 xflag = False
369 hflag = False
370 vflag = False
371 i = 1
372
373 try:
374 opts, args = getopt.getopt(
375 sys.argv[1:],
376 "axo:hvs:f:p",
377 [
378 "all",
379 "extended",
380 "outfile",
381 "help",
382 "verbose",
383 "separator",
384 "columns",
385 "parsable"
386 ]
387 )
388 except getopt.error as msg:
389 sys.stderr.write("Error: %s\n" % str(msg))
390 usage()
391 opts = None
392
393 for opt, arg in opts:
394 if opt in ('-a', '--all'):
395 aflag = True
396 if opt in ('-x', '--extended'):
397 xflag = True
398 if opt in ('-o', '--outfile'):
399 opfile = arg
400 i += 1
401 if opt in ('-h', '--help'):
402 hflag = True
403 if opt in ('-v', '--verbose'):
404 vflag = True
405 if opt in ('-s', '--separator'):
406 sep = arg
407 i += 1
408 if opt in ('-f', '--columns'):
409 desired_cols = arg
410 i += 1
411 if opt in ('-p', '--parsable'):
412 pretty_print = False
413 i += 1
414
415 argv = sys.argv[i:]
416 sint = int(argv[0]) if argv else sint
417 count = int(argv[1]) if len(argv) > 1 else (0 if len(argv) > 0 else 1)
418
419 if hflag or (xflag and desired_cols):
420 usage()
421
422 if vflag:
423 detailed_usage()
424
425 if xflag:
426 hdr = xhdr
427
428 update_hdr_intr()
429
430 # check if L2ARC exists
431 snap_stats()
432 l2_size = cur.get("l2_size")
433 if l2_size:
434 l2exist = True
435
436 if desired_cols:
437 hdr = desired_cols.split(",")
438
439 invalid = []
440 incompat = []
441 for ele in hdr:
442 if ele not in cols:
443 invalid.append(ele)
444 elif not l2exist and ele.startswith("l2"):
445 sys.stdout.write("No L2ARC Here\n%s\n" % ele)
446 incompat.append(ele)
447
448 if len(invalid) > 0:
449 sys.stderr.write("Invalid column definition! -- %s\n" % invalid)
450 usage()
451
452 if len(incompat) > 0:
453 sys.stderr.write("Incompatible field specified! -- %s\n" %
454 incompat)
455 usage()
456
457 if aflag:
458 if l2exist:
459 hdr = cols.keys()
460 else:
461 hdr = [col for col in cols.keys() if not col.startswith("l2")]
462
463 if opfile:
464 try:
465 out = open(opfile, "w")
466 sys.stdout = out
467
468 except IOError:
469 sys.stderr.write("Cannot open %s for writing\n" % opfile)
470 sys.exit(1)
471
472
473 def calculate():
474 global d
475 global v
476 global l2exist
477
478 v = dict()
479 v["time"] = time.strftime("%H:%M:%S", time.localtime())
480 v["hits"] = d["hits"] // sint
481 v["iohs"] = d["iohits"] // sint
482 v["miss"] = d["misses"] // sint
483 v["read"] = v["hits"] + v["iohs"] + v["miss"]
484 v["hit%"] = 100 * v["hits"] // v["read"] if v["read"] > 0 else 0
485 v["ioh%"] = 100 * v["iohs"] // v["read"] if v["read"] > 0 else 0
486 v["miss%"] = 100 - v["hit%"] - v["ioh%"] if v["read"] > 0 else 0
487
488 v["dhit"] = (d["demand_data_hits"] + d["demand_metadata_hits"]) // sint
489 v["dioh"] = (d["demand_data_iohits"] + d["demand_metadata_iohits"]) // sint
490 v["dmis"] = (d["demand_data_misses"] + d["demand_metadata_misses"]) // sint
491
492 v["dread"] = v["dhit"] + v["dioh"] + v["dmis"]
493 v["dh%"] = 100 * v["dhit"] // v["dread"] if v["dread"] > 0 else 0
494 v["di%"] = 100 * v["dioh"] // v["dread"] if v["dread"] > 0 else 0
495 v["dm%"] = 100 - v["dh%"] - v["di%"] if v["dread"] > 0 else 0
496
497 v["ddhit"] = d["demand_data_hits"] // sint
498 v["ddioh"] = d["demand_data_iohits"] // sint
499 v["ddmis"] = d["demand_data_misses"] // sint
500
501 v["ddread"] = v["ddhit"] + v["ddioh"] + v["ddmis"]
502 v["ddh%"] = 100 * v["ddhit"] // v["ddread"] if v["ddread"] > 0 else 0
503 v["ddi%"] = 100 * v["ddioh"] // v["ddread"] if v["ddread"] > 0 else 0
504 v["ddm%"] = 100 - v["ddh%"] - v["ddi%"] if v["ddread"] > 0 else 0
505
506 v["dmhit"] = d["demand_metadata_hits"] // sint
507 v["dmioh"] = d["demand_metadata_iohits"] // sint
508 v["dmmis"] = d["demand_metadata_misses"] // sint
509
510 v["dmread"] = v["dmhit"] + v["dmioh"] + v["dmmis"]
511 v["dmh%"] = 100 * v["dmhit"] // v["dmread"] if v["dmread"] > 0 else 0
512 v["dmi%"] = 100 * v["dmioh"] // v["dmread"] if v["dmread"] > 0 else 0
513 v["dmm%"] = 100 - v["dmh%"] - v["dmi%"] if v["dmread"] > 0 else 0
514
515 v["phit"] = (d["prefetch_data_hits"] + d["prefetch_metadata_hits"]) // sint
516 v["pioh"] = (d["prefetch_data_iohits"] +
517 d["prefetch_metadata_iohits"]) // sint
518 v["pmis"] = (d["prefetch_data_misses"] +
519 d["prefetch_metadata_misses"]) // sint
520
521 v["pread"] = v["phit"] + v["pioh"] + v["pmis"]
522 v["ph%"] = 100 * v["phit"] // v["pread"] if v["pread"] > 0 else 0
523 v["pi%"] = 100 * v["pioh"] // v["pread"] if v["pread"] > 0 else 0
524 v["pm%"] = 100 - v["ph%"] - v["pi%"] if v["pread"] > 0 else 0
525
526 v["pdhit"] = d["prefetch_data_hits"] // sint
527 v["pdioh"] = d["prefetch_data_iohits"] // sint
528 v["pdmis"] = d["prefetch_data_misses"] // sint
529
530 v["pdread"] = v["pdhit"] + v["pdioh"] + v["pdmis"]
531 v["pdh%"] = 100 * v["pdhit"] // v["pdread"] if v["pdread"] > 0 else 0
532 v["pdi%"] = 100 * v["pdioh"] // v["pdread"] if v["pdread"] > 0 else 0
533 v["pdm%"] = 100 - v["pdh%"] - v["pdi%"] if v["pdread"] > 0 else 0
534
535 v["pmhit"] = d["prefetch_metadata_hits"] // sint
536 v["pmioh"] = d["prefetch_metadata_iohits"] // sint
537 v["pmmis"] = d["prefetch_metadata_misses"] // sint
538
539 v["pmread"] = v["pmhit"] + v["pmioh"] + v["pmmis"]
540 v["pmh%"] = 100 * v["pmhit"] // v["pmread"] if v["pmread"] > 0 else 0
541 v["pmi%"] = 100 * v["pmioh"] // v["pmread"] if v["pmread"] > 0 else 0
542 v["pmm%"] = 100 - v["pmh%"] - v["pmi%"] if v["pmread"] > 0 else 0
543
544 v["mhit"] = (d["prefetch_metadata_hits"] +
545 d["demand_metadata_hits"]) // sint
546 v["mioh"] = (d["prefetch_metadata_iohits"] +
547 d["demand_metadata_iohits"]) // sint
548 v["mmis"] = (d["prefetch_metadata_misses"] +
549 d["demand_metadata_misses"]) // sint
550
551 v["mread"] = v["mhit"] + v["mioh"] + v["mmis"]
552 v["mh%"] = 100 * v["mhit"] // v["mread"] if v["mread"] > 0 else 0
553 v["mi%"] = 100 * v["mioh"] // v["mread"] if v["mread"] > 0 else 0
554 v["mm%"] = 100 - v["mh%"] - v["mi%"] if v["mread"] > 0 else 0
555
556 v["arcsz"] = cur["size"]
557 v["size"] = cur["size"]
558 v["c"] = cur["c"]
559 v["mfu"] = d["mfu_hits"] // sint
560 v["mru"] = d["mru_hits"] // sint
561 v["mrug"] = d["mru_ghost_hits"] // sint
562 v["mfug"] = d["mfu_ghost_hits"] // sint
563 v["unc"] = d["uncached_hits"] // sint
564 v["eskip"] = d["evict_skip"] // sint
565 v["el2skip"] = d["evict_l2_skip"] // sint
566 v["el2cach"] = d["evict_l2_cached"] // sint
567 v["el2el"] = d["evict_l2_eligible"] // sint
568 v["el2mfu"] = d["evict_l2_eligible_mfu"] // sint
569 v["el2mru"] = d["evict_l2_eligible_mru"] // sint
570 v["el2inel"] = d["evict_l2_ineligible"] // sint
571 v["mtxmis"] = d["mutex_miss"] // sint
572
573 if l2exist:
574 v["l2hits"] = d["l2_hits"] // sint
575 v["l2miss"] = d["l2_misses"] // sint
576 v["l2read"] = v["l2hits"] + v["l2miss"]
577 v["l2hit%"] = 100 * v["l2hits"] // v["l2read"] if v["l2read"] > 0 else 0
578
579 v["l2miss%"] = 100 - v["l2hit%"] if v["l2read"] > 0 else 0
580 v["l2asize"] = cur["l2_asize"]
581 v["l2size"] = cur["l2_size"]
582 v["l2bytes"] = d["l2_read_bytes"] // sint
583
584 v["l2pref"] = cur["l2_prefetch_asize"]
585 v["l2mfu"] = cur["l2_mfu_asize"]
586 v["l2mru"] = cur["l2_mru_asize"]
587 v["l2data"] = cur["l2_bufc_data_asize"]
588 v["l2meta"] = cur["l2_bufc_metadata_asize"]
589 v["l2pref%"] = 100 * v["l2pref"] // v["l2asize"]
590 v["l2mfu%"] = 100 * v["l2mfu"] // v["l2asize"]
591 v["l2mru%"] = 100 * v["l2mru"] // v["l2asize"]
592 v["l2data%"] = 100 * v["l2data"] // v["l2asize"]
593 v["l2meta%"] = 100 * v["l2meta"] // v["l2asize"]
594
595 v["grow"] = 0 if cur["arc_no_grow"] else 1
596 v["need"] = cur["arc_need_free"]
597 v["free"] = cur["memory_free_bytes"]
598 v["avail"] = cur["memory_available_bytes"]
599 v["waste"] = cur["abd_chunk_waste_size"]
600
601
602 def main():
603 global sint
604 global count
605 global hdr_intr
606
607 i = 0
608 count_flag = 0
609
610 init()
611 if count > 0:
612 count_flag = 1
613
614 signal(SIGINT, SIG_DFL)
615 signal(SIGWINCH, resize_handler)
616 while True:
617 if i == 0:
618 print_header()
619
620 snap_stats()
621 calculate()
622 print_values()
623
624 if count_flag == 1:
625 if count <= 1:
626 break
627 count -= 1
628
629 i = 0 if i >= hdr_intr else i + 1
630 time.sleep(sint)
631
632 if out:
633 out.close()
634
635
636 if __name__ == '__main__':
637 main()