1#!/usr/sbin/dtrace -s
2/*
3 * vmstat-p.d - vmstat -p demo in DTrace.
4 *              Written using DTrace (Solaris 10 3/05).
5 *
6 * This has been written to demonstrate fetching similar data as vmstat
7 * from DTrace. This program is intended as a starting point for other
8 * DTrace scripts, by beginning with familiar statistics.
9 *
10 * $Id: vmstat-p.d 3 2007-08-01 10:50:08Z brendan $
11 *
12 * USAGE:	vmstat-p.d
13 *
14 * FIELDS:
15 *		swap	virtual memory free	Kbytes
16 *		free	free RAM		Kbytes
17 *		re	page reclaims		Kbytes
18 *		mf	minor faults		Kbytes
19 *		sr	scan rate		pages
20 *		epi	executable page ins	Kbytes
21 *		epo	executable page outs	Kbytes
22 *		epf	executable frees	Kbytes
23 *		api	anonymous page ins	Kbytes
24 *		apo	anonymous page outs	Kbytes
25 *		apf	anonymous frees		Kbytes
26 *		fpi	filesystem page ins	Kbytes
27 *		fpo	filesystem page outs	Kbytes
28 *		fpf	filesystem frees	Kbytes
29 *
30 * NOTES:
31 *	Most of the statistics are in units of kilobytes, unlike the
32 *	original vmstat command which sometimes uses page counts.
33 *	As this program does not use Kstat, there is no summary since
34 *	boot line. Free RAM is both free free + cache free.
35 *
36 * SEE ALSO:	vmstat(1M)
37 *
38 * COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
39 *
40 * CDDL HEADER START
41 *
42 *  The contents of this file are subject to the terms of the
43 *  Common Development and Distribution License, Version 1.0 only
44 *  (the "License").  You may not use this file except in compliance
45 *  with the License.
46 *
47 *  You can obtain a copy of the license at Docs/cddl1.txt
48 *  or http://www.opensolaris.org/os/licensing.
49 *  See the License for the specific language governing permissions
50 *  and limitations under the License.
51 *
52 * CDDL HEADER END
53 *
54 * 11-Jun-2005  Brendan Gregg   Created this.
55 * 08-Jan-2006	   "      "	Last update.
56 */
57
58#pragma D option quiet
59
60inline int SCREEN = 21;
61
62/*
63 * Initialise variables
64 */
65dtrace:::BEGIN
66{
67	pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
68	sy = 0; in = 0; cs = 0; maj = 0; cow = 0; pro = 0;
69	epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0;
70	fpi = 0; fpo = 0; fpf = 0;
71	lines = SCREEN + 1;
72}
73
74/*
75 * Print header
76 */
77dtrace:::BEGIN,
78tick-1sec
79/lines++ > SCREEN/
80{
81	printf("%14s %13s %16s %14s %13s\n",
82	    "memory", "page", "executable", "anonymous", "filesystem");
83	printf("%9s %7s %5s %4s %3s ",
84	    "swap", "free", "re", "mf", "sr");
85	printf("%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
86	    "epi", "epo", "epf", "api", "apo", "apf", "fpi", "fpo", "fpf");
87	lines = 0;
88}
89
90/*
91 * Probe events
92 */
93vminfo:::pgrec	   { re += arg0; }
94vminfo:::scan	   { sr += arg0; }
95vminfo:::as_fault  { mf += arg0; }
96vminfo:::execpgin  { epi += arg0; }
97vminfo:::execpgout { epo += arg0; }
98vminfo:::execfree  { epf += arg0; }
99vminfo:::anonpgin  { api += arg0; }
100vminfo:::anonpgout { apo += arg0; }
101vminfo:::anonfree  { apf += arg0; }
102vminfo:::fspgin    { fpi += arg0; }
103vminfo:::fspgout   { fpo += arg0; }
104vminfo:::fsfree    { fpf += arg0; }
105
106/*
107 * Print output line
108 */
109profile:::tick-1sec
110{
111	/* fetch free mem */
112	this->free = `freemem;
113
114	/*
115	 * fetch free swap
116	 *
117	 * free swap is described in /usr/include/vm/anon.h as,
118	 * MAX(ani_max - ani_resv, 0) + (availrmem - swapfs_minfree)
119	 */
120	this->ani_max = `k_anoninfo.ani_max;
121	this->ani_resv = `k_anoninfo.ani_phys_resv + `k_anoninfo.ani_mem_resv;
122	this->swap = (this->ani_max - this->ani_resv > 0 ?
123	    this->ani_max - this->ani_resv : 0) + `availrmem - `swapfs_minfree;
124
125	/* fetch w */
126	this->w = `nswapped;
127
128	/* convert to Kbytes */
129	epi *= `_pagesize / 1024;
130	epo *= `_pagesize / 1024;
131	epf *= `_pagesize / 1024;
132	api *= `_pagesize / 1024;
133	apo *= `_pagesize / 1024;
134	apf *= `_pagesize / 1024;
135	fpi *= `_pagesize / 1024;
136	fpo *= `_pagesize / 1024;
137	fpf *= `_pagesize / 1024;
138	re  *= `_pagesize / 1024;
139	sr  *= `_pagesize / 1024;
140	mf  *= `_pagesize / 1024;
141	this->swap *= `_pagesize / 1024;
142	this->free *= `_pagesize / 1024;
143
144	/* print line */
145	printf("%9d %7d %5d %4d %3d ",
146	    this->swap, this->free, re, mf, sr);
147	printf("%4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
148	    epi, epo, epf, api, apo, apf, fpi, fpo, fpf);
149
150	/* clear counters */
151	pi = 0; po = 0; re = 0; sr = 0; mf = 0; fr = 0;
152	sy = 0; in = 0; cs = 0; maj = 0; cow = 0; pro = 0;
153	epi = 0; epo = 0; epf = 0; api = 0; apo = 0; apf = 0;
154	fpi = 0; fpo = 0; fpf = 0;
155}
156