net-snmp sun mods install: make sure destdirs exist
[unleashed-userland.git] / components / sysutils / net-snmp / sun / agent / modules / healthMonitor / kr_vmstat.c
blobd7b856c3034d4ee467b2a671b2c7362b733430f1
1 /*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
4 * U.S. Government Rights - Commercial software. Government users are subject
5 * to the Sun Microsystems, Inc. standard license agreement and applicable
6 * provisions of the FAR and its supplements.
9 * This distribution may include materials developed by third parties. Sun,
10 * Sun Microsystems, the Sun logo and Solaris are trademarks or registered
11 * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <ctype.h>
21 #include <unistd.h>
22 #include <memory.h>
23 #include <string.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <signal.h>
27 #include <kstat.h>
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/sysinfo.h>
32 #include <sys/vfs.h>
33 #include <sys/dnlc.h>
34 #include <sys/vmmeter.h>
36 static kstat_ctl_t *kc; /* libkstat cookie */
37 static int ncpus;
38 static kstat_t **cpu_stat_list = NULL;
39 static kstat_t *sysinfo_ksp, *vminfo_ksp, *system_misc_ksp;
40 static kstat_named_t *deficit_knp, *lbolt_knp, *clk_intr_knp;
42 static void fail(int, char *, ...);
43 static void safe_zalloc(void **, int, int);
45 typedef struct {
46 cpu_sysinfo_t cpu_sysinfo;
47 cpu_vminfo_t cpu_vminfo;
48 sysinfo_t sysinfo;
49 vminfo_t vminfo;
50 long deficit;
51 } all_stat_t;
53 static all_stat_t s_new, s_old;
55 #define denom(x) ((x) ? (x) : 1)
56 #define DELTA(x) (s_new.x - s_old.x)
58 static int hz;
59 static int pagesize;
60 static int etime;
62 static void all_stat_init(void);
63 static int all_stat_load(void);
64 static void safe_kstat_read(kstat_ctl_t *, kstat_t *, void *);
65 static kstat_t *safe_kstat_lookup(kstat_ctl_t *, char *, int, char *);
66 static void *safe_kstat_data_lookup(kstat_t *, char *);
68 static int fr_time = 0;
69 /* Get CPU Process details from kstats-
70 * Number of processes in runqueue,
71 * waiting and swapqueue
73 int
74 krgetprocdetail(int *runque, int *waiting, int *swapque)
76 ulong_t updates;
78 if(!fr_time) {
79 /* Initialize a kstat control structure */
80 if ((kc = kstat_open()) == NULL)
81 fail(1, "kstat_open(): can't open /dev/kstat");
82 all_stat_init();
83 fr_time = 1;
86 /* update the kstat header chain or load all_stat structure */
87 while (kstat_chain_update(kc) || all_stat_load()) {
88 all_stat_init();
91 updates = denom(DELTA(sysinfo.updates));
93 #define ADJ(n) ((adj <= 0) ? n : (adj >= n) ? 1 : n - adj)
94 #define adjprintf(fmt, n, val) adj -= (n + 1) - printf(fmt, ADJ(n), val)
96 *runque = DELTA(sysinfo.runque) / updates;
97 *waiting = DELTA(sysinfo.waiting) / updates;
98 *swapque = DELTA(sysinfo.swpque) / updates;
101 * Close the kstat control structure and set it to null.
103 /* kstat_close(kc);
104 kc = (kstat_ctl_t *)NULL;*/
106 return(0);
110 /* Get RAm details from kstats */
111 int
112 krgetramdetail(int *handspread, int *scan)
114 int i;
115 int pages, handspreadpages;
117 pagesize = sysconf(_SC_PAGESIZE);
118 hz = sysconf(_SC_CLK_TCK);
120 /* default max handspread is 64MB worth of pages */
121 handspreadpages = (64 * 1048576)/sysconf(_SC_PAGESIZE);
122 pages = sysconf(_SC_PHYS_PAGES);
124 if(!fr_time) {
125 if ((kc = kstat_open()) == NULL) {
126 fail(1, "kstat_open(): can't open /dev/kstat");
129 /* Initialize the all_stat structure */
130 all_stat_init();
131 fr_time = 1;
134 if (handspreadpages > (pages/4)) {
135 handspreadpages = (int)(pages/4);
137 /* update the kstat header chain or load all_stat structure */
138 while (kstat_chain_update(kc) || all_stat_load())
139 /* (void) printf("<<State change>>\n"); */
140 all_stat_init();
143 etime = 0;
144 for (i = 0; i < CPU_STATES; i++)
145 etime += DELTA(cpu_sysinfo.cpu[i]);
147 etime = denom(((etime / ncpus) + (hz >> 1)) / hz);
149 *handspread = handspreadpages;
150 *scan = DELTA(cpu_vminfo.scan) / etime;
153 * Close the kstat control structure and set it to null.
155 /* kstat_close(kc);
156 kc = (kstat_ctl_t *)NULL;
158 return(0);
161 /* Get ncstat data */
162 int
163 krgetncstatdetail(unsigned long *hits, unsigned long *misses)
165 struct ncstats ncstats;
167 if(!fr_time) {
168 /* Initialize the all_stat structure */
169 if ((kc = kstat_open()) == NULL) {
170 fail(1, "kstat_open(): can't open /dev/kstat");
173 /* Initialize the all_stat structure */
174 all_stat_init();
175 fr_time =1 ;
178 if (all_stat_load() != 0)
179 fail(1, "all_stat_load() failed");
181 safe_kstat_read(kc, safe_kstat_lookup(kc, "unix", 0, "ncstats"), (void *) &ncstats);
183 *hits = (unsigned long)ncstats.hits;
184 *misses = (unsigned long)ncstats.misses;
187 * Close the kstat control structure and set it to null.
189 /* kstat_close(kc);
190 kc = (kstat_ctl_t *)NULL;
192 return(0);
195 /* Initialize the all_stat structure */
196 static void
197 all_stat_init(void)
199 kstat_t *ksp;
202 * Global statistics
205 sysinfo_ksp = safe_kstat_lookup(kc, "unix", 0, "sysinfo");
206 vminfo_ksp = safe_kstat_lookup(kc, "unix", 0, "vminfo");
207 system_misc_ksp = safe_kstat_lookup(kc, "unix", 0, "system_misc");
209 safe_kstat_read(kc, system_misc_ksp, NULL);
210 deficit_knp = safe_kstat_data_lookup(system_misc_ksp, "deficit");
211 lbolt_knp = safe_kstat_data_lookup(system_misc_ksp, "lbolt");
212 clk_intr_knp = safe_kstat_data_lookup(system_misc_ksp, "clk_intr");
215 * Per-CPU statistics
218 ncpus = 0;
219 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next)
220 if (strncmp(ksp->ks_name, "cpu_stat", 8) == 0)
221 ncpus++;
223 safe_zalloc((void **) &cpu_stat_list, ncpus * sizeof (kstat_t *), 1);
225 ncpus = 0;
226 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next)
227 if (strncmp(ksp->ks_name, "cpu_stat", 8) == 0 &&
228 kstat_read(kc, ksp, NULL) != -1)
229 cpu_stat_list[ncpus++] = ksp;
231 if (ncpus == 0)
232 fail(0, "can't find any cpu statistics");
234 (void) memset(&s_new, 0, sizeof (all_stat_t));
238 * load statistics, summing across CPUs where needed
241 static int
242 all_stat_load(void)
244 int i, j;
245 cpu_stat_t cs;
246 uint *np, *tp;
248 s_old = s_new;
249 (void) memset(&s_new, 0, sizeof (all_stat_t));
252 * Global statistics
255 safe_kstat_read(kc, sysinfo_ksp, (void *) &s_new.sysinfo);
256 safe_kstat_read(kc, vminfo_ksp, (void *) &s_new.vminfo);
257 safe_kstat_read(kc, system_misc_ksp, NULL);
258 s_new.deficit = deficit_knp->value.l;
261 * Per-CPU statistics.
262 * For now, we just sum across all CPUs. In the future,
263 * we should add options to vmstat for per-CPU data.
266 for (i = 0; i < ncpus; i++) {
267 if (kstat_read(kc, cpu_stat_list[i], (void *) &cs) == -1)
268 return (1);
269 np = (uint *) &s_new.cpu_sysinfo;
270 tp = (uint *) &cs.cpu_sysinfo;
271 for (j = 0; j < sizeof (cpu_sysinfo_t); j += sizeof (uint_t))
272 *np++ += *tp++;
273 np = (uint *) &s_new.cpu_vminfo;
274 tp = (uint *) &cs.cpu_vminfo;
275 for (j = 0; j < sizeof (cpu_vminfo_t); j += sizeof (uint_t))
276 *np++ += *tp++;
278 return (0);
281 static void
282 fail(int do_perror, char *message, ...)
284 va_list args;
285 int save_errno = errno;
287 va_start(args, message);
288 (void) vfprintf(stderr, message, args);
289 va_end(args);
290 if (do_perror)
291 (void) fprintf(stderr, ": %s", strerror(save_errno));
292 (void) fprintf(stderr, "\n");
293 exit(2);
296 static void
297 safe_zalloc(void **ptr, int size, int free_first)
299 if (free_first && *ptr != NULL)
300 free(*ptr);
301 if ((*ptr = (void *) malloc(size)) == NULL)
302 fail(1, "malloc failed");
303 (void) memset(*ptr, 0, size);
307 void
308 safe_kstat_read(kstat_ctl_t *kc, kstat_t *ksp, void *data)
310 kid_t kstat_chain_id = kstat_read(kc, ksp, data);
312 if (kstat_chain_id == -1)
313 fail(1, "kstat_read(%x, '%s') failed", kc, ksp->ks_name);
316 kstat_t *
317 safe_kstat_lookup(kstat_ctl_t *kc, char *ks_module, int ks_instance,
318 char *ks_name)
320 kstat_t *ksp = kstat_lookup(kc, ks_module, ks_instance, ks_name);
322 if (ksp == NULL)
323 fail(0, "kstat_lookup('%s', %d, '%s') failed",
324 ks_module == NULL ? "" : ks_module,
325 ks_instance,
326 ks_name == NULL ? "" : ks_name);
327 return (ksp);
330 void *
331 safe_kstat_data_lookup(kstat_t *ksp, char *name)
333 void *fp = kstat_data_lookup(ksp, name);
335 if (fp == NULL)
336 fail(0, "kstat_data_lookup('%s', '%s') failed",
337 ksp->ks_name, name);
338 return (fp);