1235368Sgnn#!/usr/bin/sh
2235368Sgnn#
3235368Sgnn# dnlcstat - DNLC statistics.
4235368Sgnn#            Written in DTrace (Solaris 10 3/05).
5235368Sgnn#
6235368Sgnn# The DNLC is the Directory Name Lookup Cache. Filename lookups often
7235368Sgnn# return a hit from here, before needing to traverse the regular file
8235368Sgnn# system cache or go to disk.
9235368Sgnn#
10235368Sgnn# $Id: dnlcstat 3 2007-08-01 10:50:08Z brendan $
11235368Sgnn#
12235368Sgnn# USAGE:	dnlcstat [interval [count]]
13235368Sgnn#
14235368Sgnn# FIELDS:
15235368Sgnn#
16235368Sgnn#		%hit	hit percentage for this sample
17235368Sgnn#		hit	number of DNLC hits in this sample
18235368Sgnn#		miss	number of DNLC misses in this sample
19235368Sgnn#
20235368Sgnn# SEE ALSO: 	CacheKit, http://www.brendangregg.com/cachekit.html
21235368Sgnn#		(contains a dnlcstat written in Perl, which uses less CPU)
22235368Sgnn#
23235368Sgnn# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
24235368Sgnn#
25235368Sgnn# CDDL HEADER START
26235368Sgnn#
27235368Sgnn#  The contents of this file are subject to the terms of the
28235368Sgnn#  Common Development and Distribution License, Version 1.0 only
29235368Sgnn#  (the "License").  You may not use this file except in compliance
30235368Sgnn#  with the License.
31235368Sgnn#
32235368Sgnn#  You can obtain a copy of the license at Docs/cddl1.txt
33235368Sgnn#  or http://www.opensolaris.org/os/licensing.
34235368Sgnn#  See the License for the specific language governing permissions
35235368Sgnn#  and limitations under the License.
36235368Sgnn#
37235368Sgnn# CDDL HEADER END
38235368Sgnn#
39235368Sgnn# 27-Mar-2004	Brendan Gregg	Created this.
40235368Sgnn# 14-Jun-2005	   "      "  	Updated style.
41235368Sgnn# 14-Jun-2005	   "      "  	Last update.
42235368Sgnn#
43235368Sgnn
44235368Sgnn##############################
45235368Sgnn# --- Process Arguments ---
46235368Sgnn#
47235368Sgnn
48235368Sgnn### default values
49235368Sgnninterval=1; count=-1
50235368Sgnn
51235368Sgnn### check arguments
52235368Sgnnif [ "$1" = "-h" -o "$1" = "--help" ]; then
53235368Sgnn	cat <<-END >&2
54235368Sgnn	USAGE: dnlcstat [interval [count]]
55235368Sgnn	       dnlcstat          # 1 second samples, infinite
56235368Sgnn	  eg,
57235368Sgnn	       dnlcstat 1        # print every 1 second
58235368Sgnn	       dnlcstat 5 6      # print every 5 seconds, 6 times
59235368Sgnn	END
60235368Sgnn        exit 1
61235368Sgnnfi
62235368Sgnn
63235368Sgnn### argument logic
64235368Sgnnif [ "$1" -gt 0 ]; then
65235368Sgnn        interval=$1; count=-1; shift
66235368Sgnnfi
67235368Sgnnif [ "$1" -gt 0 ]; then
68235368Sgnn        count=$1; shift
69235368Sgnnfi
70235368Sgnnif [ $interval -eq 0 ]; then
71235368Sgnn        interval=1
72235368Sgnnfi
73235368Sgnn
74235368Sgnn
75235368Sgnn#################################
76235368Sgnn# --- Main Program, DTrace ---
77235368Sgnn#
78235368Sgnn/usr/sbin/dtrace -n '
79235368Sgnn #pragma D option quiet
80235368Sgnn
81235368Sgnn /*
82235368Sgnn  * Command line arguments
83235368Sgnn  */
84235368Sgnn inline int INTERVAL   = '$interval';
85235368Sgnn inline int COUNTER    = '$count';
86235368Sgnn inline int SCREEN = 21;
87235368Sgnn
88235368Sgnn int hits;			/* hits */
89235368Sgnn int misses;			/* misses */
90235368Sgnn
91235368Sgnn /*
92235368Sgnn  * Initialise variables
93235368Sgnn  */
94235368Sgnn dtrace:::BEGIN
95235368Sgnn {
96235368Sgnn	lines = SCREEN + 1;
97235368Sgnn	counts = COUNTER;
98235368Sgnn	secs = INTERVAL;
99235368Sgnn	first = 1;
100235368Sgnn }
101235368Sgnn
102235368Sgnn /*
103235368Sgnn  * Print header
104235368Sgnn  */
105235368Sgnn dtrace:::BEGIN,
106235368Sgnn tick-1sec
107235368Sgnn /first || (secs == 0 && lines > SCREEN)/
108235368Sgnn { 
109235368Sgnn	printf("%10s %8s %8s\n","dnlc  %hit","hit","miss");
110235368Sgnn	lines = 0;
111235368Sgnn	first = 0;
112235368Sgnn }
113235368Sgnn
114235368Sgnn /*
115235368Sgnn  * Probe DNLC lookups
116235368Sgnn  */
117235368Sgnn fbt:genunix:dnlc_lookup:return
118235368Sgnn {
119235368Sgnn	hits   += arg1 == 0 ? 0 : 1;
120235368Sgnn	misses += arg1 == 0 ? 1 : 0;
121235368Sgnn }
122235368Sgnn
123235368Sgnn profile:::tick-1sec
124235368Sgnn {
125235368Sgnn        secs--;
126235368Sgnn }
127235368Sgnn
128235368Sgnn
129235368Sgnn /*
130235368Sgnn  * Print output line
131235368Sgnn  */
132235368Sgnn profile:::tick-1sec
133235368Sgnn /secs == 0/
134235368Sgnn {
135235368Sgnn	/* calculate hit percent */
136235368Sgnn	this->divide = misses + hits == 0 ? 1 : misses + hits;
137235368Sgnn	ratio = hits * 100 / this->divide;
138235368Sgnn
139235368Sgnn	/* print output */
140235368Sgnn	printf("%10d %8d %8d\n",ratio,hits,misses);
141235368Sgnn
142235368Sgnn	/* clear counters */
143235368Sgnn	hits = 0;
144235368Sgnn	misses = 0;
145235368Sgnn
146235368Sgnn        /* process counts */
147235368Sgnn        secs = INTERVAL;
148235368Sgnn        counts--;
149235368Sgnn        lines++;
150235368Sgnn
151235368Sgnn }
152235368Sgnn
153235368Sgnn /*
154235368Sgnn  * End
155235368Sgnn  */
156235368Sgnn profile:::tick-1sec
157235368Sgnn /counts == 0/
158235368Sgnn {
159235368Sgnn        exit(0);
160235368Sgnn }
161235368Sgnn'
162235368Sgnn
163