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