xref: /titanic_50/usr/src/cmd/avs/sdbc/sdbc_dynmem.c (revision 0a0e9771ca0211c15f3ac4466b661c145feeb9e4)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * This program is strictly for demonstration purposes and not for
28  * production use. It demonstrates how to access the dynamic memory
29  * caching statistics and turning variables via the kstat library.
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #include <stropts.h>
36 #include <ctype.h>
37 #include <unistd.h>
38 #include <memory.h>
39 #include <string.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <signal.h>
43 #include <locale.h>
44 #include <kstat.h>
45 
46 #include <sys/types.h>
47 #include <sys/time.h>
48 #include <sys/sysinfo.h>
49 #include <sys/buf.h>
50 #include <sys/vfs.h>
51 #include <sys/dnlc.h>
52 #include <sys/vmmeter.h>
53 
54 #define	TRUE 1
55 #define	FALSE 0
56 #define	SDBC_KSTAT_MODULE	"sdbc"
57 #define	SDBC_KSTAT_DYNMEM	"dynmem"
58 
59 typedef struct {
60 	int instance;
61 	kstat_t *ksp;
62 	} KSTAT_INFO_DEF;
63 
64 typedef struct {
65 	kstat_named_t	*knp;
66 	char		*named;
67 	int		newval;
68 	} DYNMEM_KNP_DEFN;
69 
70 typedef enum {
71 MONITOR = 0,
72 MAXLIST,
73 AGECT1,
74 AGECT2,
75 AGECT3,
76 SEC1,
77 SEC2,
78 SEC3,
79 PCNT1,
80 PCNT2,
81 HDPCNT,
82 ALLOC,
83 DEALLOC,
84 HISTORY,
85 NODATA,
86 CAND,
87 DEALLOCS,
88 HOSTS,
89 PESTS,
90 METAS,
91 HOLDS,
92 OTHERS,
93 NOTAVAIL,
94 DIRECTIVE,
95 SIMPLECT
96 } arglist_id;
97 
98 #define	NO_VALUE -1
99 
100 DYNMEM_KNP_DEFN dynmem_knp[] = {
101 	NULL,	"sdbc_monitor_dynmem",		NO_VALUE,
102 	NULL,	"sdbc_max_dyn_list",		NO_VALUE,
103 	NULL,	"sdbc_cache_aging_ct1",		NO_VALUE,
104 	NULL,	"sdbc_cache_aging_ct2",		NO_VALUE,
105 	NULL,	"sdbc_cache_aging_ct3",		NO_VALUE,
106 	NULL,	"sdbc_cache_aging_sec1",	NO_VALUE,
107 	NULL,	"sdbc_cache_aging_sec2",	NO_VALUE,
108 	NULL,	"sdbc_cache_aging_sec3",	NO_VALUE,
109 	NULL,	"sdbc_cache_aging_pcnt1",	NO_VALUE,
110 	NULL,	"sdbc_cache_aging_pcnt2",	NO_VALUE,
111 	NULL,	"sdbc_max_holds_pcnt",		NO_VALUE,
112 	NULL,	"sdbc_alloc_cnt",		NO_VALUE,
113 	NULL,	"sdbc_dealloc_cnt",		NO_VALUE,
114 	NULL,	"sdbc_history",			NO_VALUE,
115 	NULL,	"sdbc_nodatas",			NO_VALUE,
116 	NULL,	"sdbc_candidates",		NO_VALUE,
117 	NULL,	"sdbc_deallocs",		NO_VALUE,
118 	NULL,	"sdbc_hosts",			NO_VALUE,
119 	NULL,	"sdbc_pests",			NO_VALUE,
120 	NULL,	"sdbc_metas",			NO_VALUE,
121 	NULL,	"sdbc_holds",			NO_VALUE,
122 	NULL,	"sdbc_others",			NO_VALUE,
123 	NULL,	"sdbc_notavail",		NO_VALUE,
124 	NULL,	"sdbc_process_directive",	NO_VALUE,
125 	NULL,	"sdbc_simplect",		NO_VALUE,
126 	NULL,	NULL,				NO_VALUE
127 	};
128 
129 /*
130  * Print Usage
131  */
132 static void
133 print_usage()
134 {
135 	(void) printf("USAGE: wake - wakeup thread, hys - max hysteresis\n");
136 	(void) printf("       mon 1 - monitor shutdown\n");
137 	(void) printf("           2 - monitor thread stats1\n");
138 	(void) printf("           4 - monitor thread stats2\n");
139 	(void) printf("       age1 n - num cyc to full host aging and "
140 	    "dealloc\n");
141 	(void) printf("       age2 n - num cyc to full meta aging and "
142 	    "dealloc\n");
143 	(void) printf("       age3 n - num cyc to full one pg aging and "
144 	    "dealloc\n");
145 	(void) printf("       sec1 n  - sec1 aging time\n");
146 	(void) printf("       sec2 n  - sec2 aging time\n");
147 	(void) printf("       sec3 n  - sec3 aging time\n");
148 	(void) printf("       pcnt1 n  - percent to sec1/sec2 trans\n");
149 	(void) printf("       pcnt2 n  - percent to sec2/sec3 trans\n");
150 	(void) printf("       hdpcnt n  - max percent of cents for holds\n");
151 	(void) printf("       list n  - host+pest max len\n");
152 	(void) printf("No Args - print current settings only\n");
153 }
154 
155 /*
156  * Main
157  */
158 /* ARGSUSED */
159 #ifdef lint
160 int
161 sd_dynmem_lintmain(int argc, char *argv[])
162 #else
163 int
164 main(int argc, char *argv[])
165 #endif
166 {
167 	DYNMEM_KNP_DEFN	*p_dynmem_knp;
168 	kstat_ctl_t	*kctl;
169 	KSTAT_INFO_DEF	info_ksp;
170 	int		val;
171 	char		**pargs, **cur_pargs;
172 
173 	/*
174 	 * grab and parse argument list
175 	 */
176 	p_dynmem_knp = dynmem_knp;
177 	pargs = argv;
178 	while (*pargs) {
179 		(void) printf("pargs=%x - %s\n", (uint_t)pargs, *pargs);
180 
181 		cur_pargs = pargs;
182 		pargs++;
183 
184 		if (strcmp(*cur_pargs, "h") == 0) {
185 			print_usage();
186 			return (0);
187 		}
188 
189 		if (strcmp(*cur_pargs, "wake") == 0) {
190 			if ((p_dynmem_knp+DIRECTIVE)->newval == NO_VALUE)
191 				(p_dynmem_knp+DIRECTIVE)->newval = 0;
192 			(p_dynmem_knp+DIRECTIVE)->newval |= 0x01;
193 			continue;
194 		}
195 
196 		if (strcmp(*cur_pargs, "hys") == 0) {
197 			if ((p_dynmem_knp+DIRECTIVE)->newval == NO_VALUE)
198 				(p_dynmem_knp+DIRECTIVE)->newval = 0;
199 			(p_dynmem_knp+DIRECTIVE)->newval |= 0x02;
200 			continue;
201 		}
202 
203 		if (strcmp (*cur_pargs, "mon") == 0) {
204 			val = atoi(*pargs);
205 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
206 			    val);
207 			pargs++;
208 			(p_dynmem_knp+MONITOR)->newval = val;
209 		}
210 
211 		if (strcmp (*cur_pargs, "age1") == 0) {
212 			val = atoi(*pargs);
213 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
214 			    val);
215 			pargs++;
216 			(p_dynmem_knp+AGECT1)->newval = val;
217 		}
218 
219 		if (strcmp(*cur_pargs, "age2") == 0) {
220 			val = atoi(*pargs);
221 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
222 			    val);
223 			pargs++;
224 			(p_dynmem_knp+AGECT2)->newval = val;
225 		}
226 
227 		if (strcmp(*cur_pargs, "age3") == 0) {
228 			val = atoi(*pargs);
229 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
230 			    val);
231 			pargs++;
232 			(p_dynmem_knp+AGECT3)->newval = val;
233 		}
234 
235 		if (strcmp (*cur_pargs, "sec1") == 0) {
236 			val = atoi(*pargs);
237 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
238 			    val);
239 			pargs++;
240 			if (val == 0)
241 				break;
242 			else {
243 				(p_dynmem_knp+SEC1)->newval = val;
244 				continue;
245 			}
246 		}
247 
248 		if (strcmp(*cur_pargs, "sec2") == 0) {
249 			val = atoi(*pargs);
250 			pargs++;
251 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
252 			    val);
253 			if (val == 0)
254 				break;
255 			else {
256 				(p_dynmem_knp+SEC2)->newval = val;
257 				continue;
258 			}
259 		}
260 
261 		if (strcmp(*cur_pargs, "sec3") == 0) {
262 			val = atoi(*pargs);
263 			pargs++;
264 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
265 			    val);
266 			if (val == 0)
267 				break;
268 			else {
269 				(p_dynmem_knp+SEC3)->newval = val;
270 				continue;
271 			}
272 		}
273 
274 		if (strcmp(*cur_pargs, "pcnt1") == 0) {
275 			val = atoi(*pargs);
276 			pargs++;
277 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
278 			    val);
279 			if (val == 0)
280 				break;
281 			else {
282 				(p_dynmem_knp+PCNT1)->newval = val;
283 				continue;
284 			}
285 		}
286 
287 		if (strcmp(*cur_pargs, "pcnt2") == 0) {
288 			val = atoi(*pargs);
289 			pargs++;
290 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
291 			    val);
292 			if (val == 0)
293 				break;
294 			else {
295 				(p_dynmem_knp+PCNT2)->newval = val;
296 				continue;
297 			}
298 		}
299 
300 		if (strcmp(*cur_pargs, "hdpcnt") == 0) {
301 			val = atoi(*pargs);
302 			pargs++;
303 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
304 			    val);
305 			if (val < 0)
306 				break;
307 			else {
308 				(p_dynmem_knp+HDPCNT)->newval = val;
309 				continue;
310 			}
311 		}
312 
313 		if (strcmp(*cur_pargs, "list") == 0) {
314 			val = atoi(*pargs);
315 			pargs++;
316 			(void) printf("errno=%x, %s=%x\n", errno, *cur_pargs,
317 			    val);
318 			if (val == 0)
319 				break;
320 			else {
321 				(p_dynmem_knp+MAXLIST)->newval = val;
322 				continue;
323 			}
324 		}
325 	}   /* while(*pargs && cl) */
326 
327 	/*
328 	 * open the kstat library
329 	 */
330 	kctl = kstat_open();
331 	if (kctl == NULL) {
332 		(void) printf("kstat_open() failed\n");
333 		return (1);
334 	}
335 
336 	/*
337 	 * is the name module about
338 	 */
339 	info_ksp.instance = 0;
340 	info_ksp.ksp = kstat_lookup(kctl, SDBC_KSTAT_MODULE, 0,
341 	    SDBC_KSTAT_DYNMEM);
342 	if (info_ksp.ksp == NULL) {
343 		(void) printf("No module to report\n");
344 		return (1);
345 	}
346 
347 	/*
348 	 * using the info get a copy of the data
349 	 */
350 	if (kstat_read(kctl, info_ksp.ksp, NULL) == -1) {
351 		(void) printf("Can't read kstat\n");
352 		return (1);
353 	}
354 
355 	/*
356 	 * print the current data
357 	 */
358 	p_dynmem_knp = dynmem_knp;
359 	while (p_dynmem_knp->named) {
360 		p_dynmem_knp->knp =
361 			kstat_data_lookup(info_ksp.ksp, p_dynmem_knp->named);
362 		if (p_dynmem_knp->knp == NULL) {
363 			(void) printf("kstat_data_lookup(%s) failed\n",
364 			    p_dynmem_knp->named);
365 			return (1);
366 		} else {
367 			(void) printf("%s: %x\n", p_dynmem_knp->named,
368 			    (uint_t)p_dynmem_knp->knp->value.ul);
369 			p_dynmem_knp++;
370 		}
371 	}
372 
373 	/*
374 	 * modify the data and write it back
375 	 */
376 	p_dynmem_knp = dynmem_knp;
377 	while (p_dynmem_knp->named) {
378 		if (p_dynmem_knp->newval != NO_VALUE)
379 			p_dynmem_knp->knp->value.ul = p_dynmem_knp->newval;
380 		p_dynmem_knp++;
381 	}
382 
383 	if (kstat_write(kctl, info_ksp.ksp, NULL) == -1) {
384 		(void) printf("kstat_write() failed\n");
385 		return (1);
386 	}
387 
388 	(void) printf("Finished (h for help)\n");
389 	return (0);
390 }
391