xref: /titanic_51/usr/src/contrib/ast/src/lib/libcmd/vmstate.c (revision b4dd7d09880f14016feece03929a224eca1cf39a)
1*b4dd7d09SAndy Fiddaman /***********************************************************************
2*b4dd7d09SAndy Fiddaman *                                                                      *
3*b4dd7d09SAndy Fiddaman *               This software is part of the ast package               *
4*b4dd7d09SAndy Fiddaman *          Copyright (c) 1992-2012 AT&T Intellectual Property          *
5*b4dd7d09SAndy Fiddaman *                      and is licensed under the                       *
6*b4dd7d09SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b4dd7d09SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b4dd7d09SAndy Fiddaman *                                                                      *
9*b4dd7d09SAndy Fiddaman *                A copy of the License is available at                 *
10*b4dd7d09SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b4dd7d09SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b4dd7d09SAndy Fiddaman *                                                                      *
13*b4dd7d09SAndy Fiddaman *              Information and Software Systems Research               *
14*b4dd7d09SAndy Fiddaman *                            AT&T Research                             *
15*b4dd7d09SAndy Fiddaman *                           Florham Park NJ                            *
16*b4dd7d09SAndy Fiddaman *                                                                      *
17*b4dd7d09SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b4dd7d09SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b4dd7d09SAndy Fiddaman *                                                                      *
20*b4dd7d09SAndy Fiddaman ***********************************************************************/
21*b4dd7d09SAndy Fiddaman #pragma prototyped
22*b4dd7d09SAndy Fiddaman 
23*b4dd7d09SAndy Fiddaman #define FORMAT		"region=%(region)p method=%(method)s flags=%(flags)s size=%(size)d segments=%(segments)d busy=(%(busy_size)d,%(busy_blocks)d,%(busy_max)d) free=(%(free_size)d,%(free_blocks)d,%(free_max)d)"
24*b4dd7d09SAndy Fiddaman 
25*b4dd7d09SAndy Fiddaman static const char usage[] =
26*b4dd7d09SAndy Fiddaman "[-?\n@(#)$Id: vmstate (AT&T Research) 2010-04-08 $\n]"
27*b4dd7d09SAndy Fiddaman USAGE_LICENSE
28*b4dd7d09SAndy Fiddaman "[+NAME?vmstate - list the calling process vmalloc region state]"
29*b4dd7d09SAndy Fiddaman "[+DESCRIPTION?When invoked as a shell builtin, \bvmstate\b lists the "
30*b4dd7d09SAndy Fiddaman     "calling process \bvmalloc\b(3) state for all regions.]"
31*b4dd7d09SAndy Fiddaman "[f:format?List the ids specified by \aformat\a. \aformat\a follows "
32*b4dd7d09SAndy Fiddaman     "\bprintf\b(3) conventions, except that \bsfio\b(3) inline ids are used "
33*b4dd7d09SAndy Fiddaman     "instead of arguments: "
34*b4dd7d09SAndy Fiddaman     "%[-+]][\awidth\a[.\aprecis\a[.\abase\a]]]]]](\aid\a)\achar\a. The "
35*b4dd7d09SAndy Fiddaman     "supported \aid\as are:]:[format:=" FORMAT "]"
36*b4dd7d09SAndy Fiddaman     "{"
37*b4dd7d09SAndy Fiddaman 	"[+method?The vmalloc method name.]"
38*b4dd7d09SAndy Fiddaman 	"[+flags?The vmalloc method flags.]"
39*b4dd7d09SAndy Fiddaman         "[+size?The total region size.]"
40*b4dd7d09SAndy Fiddaman         "[+segments?The number of segments in the region.]"
41*b4dd7d09SAndy Fiddaman         "[+busy_size?The total busy block size.]"
42*b4dd7d09SAndy Fiddaman         "[+busy_blocks?The number of busy blocks.]"
43*b4dd7d09SAndy Fiddaman         "[+busy_max?The maximum busy block size.]"
44*b4dd7d09SAndy Fiddaman         "[+free_size?The total free block size.]"
45*b4dd7d09SAndy Fiddaman         "[+free_blocks?The number of free blocks.]"
46*b4dd7d09SAndy Fiddaman         "[+free_max?The maximum free block size.]"
47*b4dd7d09SAndy Fiddaman     "}"
48*b4dd7d09SAndy Fiddaman "[+SEE ALSO?\bvmalloc\b(3)]"
49*b4dd7d09SAndy Fiddaman ;
50*b4dd7d09SAndy Fiddaman 
51*b4dd7d09SAndy Fiddaman #include <cmd.h>
52*b4dd7d09SAndy Fiddaman #include <vmalloc.h>
53*b4dd7d09SAndy Fiddaman #include <sfdisc.h>
54*b4dd7d09SAndy Fiddaman 
55*b4dd7d09SAndy Fiddaman typedef struct State_s
56*b4dd7d09SAndy Fiddaman {
57*b4dd7d09SAndy Fiddaman 	char*		format;
58*b4dd7d09SAndy Fiddaman 	Vmalloc_t*	vm;
59*b4dd7d09SAndy Fiddaman 	Vmstat_t	vs;
60*b4dd7d09SAndy Fiddaman 	unsigned int	regions;
61*b4dd7d09SAndy Fiddaman 	Vmalloc_t*	region[256];
62*b4dd7d09SAndy Fiddaman } State_t;
63*b4dd7d09SAndy Fiddaman 
64*b4dd7d09SAndy Fiddaman /*
65*b4dd7d09SAndy Fiddaman  * sfkeyprintf() lookup
66*b4dd7d09SAndy Fiddaman  * handle==0 for heading
67*b4dd7d09SAndy Fiddaman  */
68*b4dd7d09SAndy Fiddaman 
69*b4dd7d09SAndy Fiddaman static int
70*b4dd7d09SAndy Fiddaman key(void* handle, Sffmt_t* fp, const char* arg, char** ps, Sflong_t* pn)
71*b4dd7d09SAndy Fiddaman {
72*b4dd7d09SAndy Fiddaman 	register State_t*	state = (State_t*)handle;
73*b4dd7d09SAndy Fiddaman 	register char*		s;
74*b4dd7d09SAndy Fiddaman 
75*b4dd7d09SAndy Fiddaman 	if (!(s = fp->t_str) || streq(s, "size"))
76*b4dd7d09SAndy Fiddaman 		*pn = state->vs.extent;
77*b4dd7d09SAndy Fiddaman 	else if (streq(s, "region"))
78*b4dd7d09SAndy Fiddaman 		*pn = integralof(state->vm);
79*b4dd7d09SAndy Fiddaman 	else if (streq(s, "segments"))
80*b4dd7d09SAndy Fiddaman 		*pn = state->vs.n_seg;
81*b4dd7d09SAndy Fiddaman 	else if (streq(s, "busy_size"))
82*b4dd7d09SAndy Fiddaman 		*pn = state->vs.s_busy;
83*b4dd7d09SAndy Fiddaman 	else if (streq(s, "busy_blocks"))
84*b4dd7d09SAndy Fiddaman 		*pn = state->vs.n_busy;
85*b4dd7d09SAndy Fiddaman 	else if (streq(s, "busy_max"))
86*b4dd7d09SAndy Fiddaman 		*pn = state->vs.m_busy;
87*b4dd7d09SAndy Fiddaman 	else if (streq(s, "flags"))
88*b4dd7d09SAndy Fiddaman 	{
89*b4dd7d09SAndy Fiddaman 		*ps = s = fmtbuf(32);
90*b4dd7d09SAndy Fiddaman #ifdef VM_TRUST
91*b4dd7d09SAndy Fiddaman 		if (state->vs.mode & VM_TRUST)
92*b4dd7d09SAndy Fiddaman 			s = strcopy(s, "TRUST|");
93*b4dd7d09SAndy Fiddaman #endif
94*b4dd7d09SAndy Fiddaman 		if (state->vs.mode & VM_TRACE)
95*b4dd7d09SAndy Fiddaman 			s = strcopy(s, "TRACE|");
96*b4dd7d09SAndy Fiddaman 		if (state->vs.mode & VM_DBCHECK)
97*b4dd7d09SAndy Fiddaman 			s = strcopy(s, "DBCHECK|");
98*b4dd7d09SAndy Fiddaman 		if (state->vs.mode & VM_DBABORT)
99*b4dd7d09SAndy Fiddaman 			s = strcopy(s, "DBABORT|");
100*b4dd7d09SAndy Fiddaman 		if (s > *ps)
101*b4dd7d09SAndy Fiddaman 			*(s - 1) = 0;
102*b4dd7d09SAndy Fiddaman 		else
103*b4dd7d09SAndy Fiddaman 			strcpy(s, "0");
104*b4dd7d09SAndy Fiddaman 	}
105*b4dd7d09SAndy Fiddaman 	else if (streq(s, "free_size"))
106*b4dd7d09SAndy Fiddaman 		*pn = state->vs.s_free;
107*b4dd7d09SAndy Fiddaman 	else if (streq(s, "free_blocks"))
108*b4dd7d09SAndy Fiddaman 		*pn = state->vs.n_free;
109*b4dd7d09SAndy Fiddaman 	else if (streq(s, "free_max"))
110*b4dd7d09SAndy Fiddaman 		*pn = state->vs.m_free;
111*b4dd7d09SAndy Fiddaman 	else if (streq(s, "format"))
112*b4dd7d09SAndy Fiddaman 		*ps = (char*)state->format;
113*b4dd7d09SAndy Fiddaman 	else if (streq(s, "method"))
114*b4dd7d09SAndy Fiddaman 	{
115*b4dd7d09SAndy Fiddaman 		if (state->vs.mode & VM_MTBEST)
116*b4dd7d09SAndy Fiddaman 			*ps = "best";
117*b4dd7d09SAndy Fiddaman 		else if (state->vs.mode & VM_MTPOOL)
118*b4dd7d09SAndy Fiddaman 			*ps = "pool";
119*b4dd7d09SAndy Fiddaman 		else if (state->vs.mode & VM_MTLAST)
120*b4dd7d09SAndy Fiddaman 			*ps = "last";
121*b4dd7d09SAndy Fiddaman 		else if (state->vs.mode & VM_MTDEBUG)
122*b4dd7d09SAndy Fiddaman 			*ps = "debug";
123*b4dd7d09SAndy Fiddaman 		else if (state->vs.mode & VM_MTPROFILE)
124*b4dd7d09SAndy Fiddaman 			*ps = "profile";
125*b4dd7d09SAndy Fiddaman 		else
126*b4dd7d09SAndy Fiddaman 			*ps = "UNKNOWN";
127*b4dd7d09SAndy Fiddaman 	}
128*b4dd7d09SAndy Fiddaman 	else
129*b4dd7d09SAndy Fiddaman 	{
130*b4dd7d09SAndy Fiddaman 		error(2, "%s: unknown format identifier", s);
131*b4dd7d09SAndy Fiddaman 		return 0;
132*b4dd7d09SAndy Fiddaman 	}
133*b4dd7d09SAndy Fiddaman 	return 1;
134*b4dd7d09SAndy Fiddaman }
135*b4dd7d09SAndy Fiddaman 
136*b4dd7d09SAndy Fiddaman static int
137*b4dd7d09SAndy Fiddaman visit(Vmalloc_t* vm, void* addr, size_t size, Vmdisc_t* disc, void* handle)
138*b4dd7d09SAndy Fiddaman {
139*b4dd7d09SAndy Fiddaman 	State_t*	state = (State_t*)handle;
140*b4dd7d09SAndy Fiddaman 
141*b4dd7d09SAndy Fiddaman 	if (vm != state->vm)
142*b4dd7d09SAndy Fiddaman 	{
143*b4dd7d09SAndy Fiddaman 		state->vm = vm;
144*b4dd7d09SAndy Fiddaman 		if (state->regions < elementsof(state->region))
145*b4dd7d09SAndy Fiddaman 			state->region[state->regions++] = vm;
146*b4dd7d09SAndy Fiddaman 	}
147*b4dd7d09SAndy Fiddaman 	return 0;
148*b4dd7d09SAndy Fiddaman }
149*b4dd7d09SAndy Fiddaman 
150*b4dd7d09SAndy Fiddaman int
151*b4dd7d09SAndy Fiddaman b_vmstate(int argc, char** argv, Shbltin_t* context)
152*b4dd7d09SAndy Fiddaman {
153*b4dd7d09SAndy Fiddaman 	register int	i;
154*b4dd7d09SAndy Fiddaman 	State_t		state;
155*b4dd7d09SAndy Fiddaman 
156*b4dd7d09SAndy Fiddaman 	memset(&state, 0, sizeof(state));
157*b4dd7d09SAndy Fiddaman 	cmdinit(argc, argv, context, ERROR_CATALOG, 0);
158*b4dd7d09SAndy Fiddaman 	for (;;)
159*b4dd7d09SAndy Fiddaman 	{
160*b4dd7d09SAndy Fiddaman 		switch (optget(argv, usage))
161*b4dd7d09SAndy Fiddaman 		{
162*b4dd7d09SAndy Fiddaman 		case 'f':
163*b4dd7d09SAndy Fiddaman 			state.format = opt_info.arg;
164*b4dd7d09SAndy Fiddaman 			continue;
165*b4dd7d09SAndy Fiddaman 		case '?':
166*b4dd7d09SAndy Fiddaman 			error(ERROR_USAGE|4, "%s", opt_info.arg);
167*b4dd7d09SAndy Fiddaman 			break;
168*b4dd7d09SAndy Fiddaman 		case ':':
169*b4dd7d09SAndy Fiddaman 			error(2, "%s", opt_info.arg);
170*b4dd7d09SAndy Fiddaman 			break;
171*b4dd7d09SAndy Fiddaman 		}
172*b4dd7d09SAndy Fiddaman 		break;
173*b4dd7d09SAndy Fiddaman 	}
174*b4dd7d09SAndy Fiddaman 	argv += opt_info.index;
175*b4dd7d09SAndy Fiddaman 	if (error_info.errors || *argv)
176*b4dd7d09SAndy Fiddaman 		error(ERROR_USAGE|4, "%s", optusage(NiL));
177*b4dd7d09SAndy Fiddaman 	if (!state.format)
178*b4dd7d09SAndy Fiddaman 		state.format = FORMAT;
179*b4dd7d09SAndy Fiddaman 
180*b4dd7d09SAndy Fiddaman 	/*
181*b4dd7d09SAndy Fiddaman 	 * the walk must do no allocations because it locks the regions
182*b4dd7d09SAndy Fiddaman 	 */
183*b4dd7d09SAndy Fiddaman 
184*b4dd7d09SAndy Fiddaman 	vmwalk(NiL, visit, &state);
185*b4dd7d09SAndy Fiddaman 
186*b4dd7d09SAndy Fiddaman 	/*
187*b4dd7d09SAndy Fiddaman 	 * now we can compute and list the state of each region
188*b4dd7d09SAndy Fiddaman 	 */
189*b4dd7d09SAndy Fiddaman 
190*b4dd7d09SAndy Fiddaman 	for (i = 0; i < state.regions; i++)
191*b4dd7d09SAndy Fiddaman 	{
192*b4dd7d09SAndy Fiddaman 		state.vm = state.region[i];
193*b4dd7d09SAndy Fiddaman 		vmstat(state.vm, &state.vs);
194*b4dd7d09SAndy Fiddaman 		sfkeyprintf(sfstdout, &state, state.format, key, NiL);
195*b4dd7d09SAndy Fiddaman 		sfprintf(sfstdout, "\n");
196*b4dd7d09SAndy Fiddaman 	}
197*b4dd7d09SAndy Fiddaman 	return 0;
198*b4dd7d09SAndy Fiddaman }
199