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