Annotation of src/usr.bin/vmstat/vmstat.c, Revision 1.60
1.11 deraadt 1: /* $NetBSD: vmstat.c,v 1.29.4.1 1996/06/05 00:21:05 cgd Exp $ */
1.60 ! art 2: /* $OpenBSD: vmstat.c,v 1.59 2001/08/12 12:03:03 heko Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1980, 1986, 1991, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: static char copyright[] =
39: "@(#) Copyright (c) 1980, 1986, 1991, 1993\n\
40: The Regents of the University of California. All rights reserved.\n";
41: #endif /* not lint */
42:
43: #ifndef lint
44: #if 0
45: static char sccsid[] = "@(#)vmstat.c 8.1 (Berkeley) 6/6/93";
46: #else
1.11 deraadt 47: static char rcsid[] = "$NetBSD: vmstat.c,v 1.29.4.1 1996/06/05 00:21:05 cgd Exp $";
1.1 deraadt 48: #endif
49: #endif /* not lint */
50:
1.48 art 51: #define __POOL_EXPOSE
52:
1.1 deraadt 53: #include <sys/param.h>
54: #include <sys/time.h>
55: #include <sys/proc.h>
56: #include <sys/user.h>
57: #include <sys/dkstat.h>
58: #include <sys/buf.h>
59: #include <sys/namei.h>
60: #include <sys/malloc.h>
61: #include <sys/fcntl.h>
62: #include <sys/ioctl.h>
63: #include <sys/sysctl.h>
64: #include <sys/device.h>
1.48 art 65: #include <sys/pool.h>
1.1 deraadt 66: #include <vm/vm.h>
67: #include <time.h>
68: #include <nlist.h>
69: #include <kvm.h>
1.21 millert 70: #include <err.h>
1.1 deraadt 71: #include <errno.h>
72: #include <unistd.h>
73: #include <signal.h>
74: #include <stdio.h>
75: #include <ctype.h>
76: #include <stdlib.h>
77: #include <string.h>
78: #include <paths.h>
79: #include <limits.h>
1.6 tholo 80: #include "dkstats.h"
1.1 deraadt 81:
1.56 angelos 82: #include <uvm/uvm_object.h>
1.29 art 83: #include <uvm/uvm_extern.h>
84:
1.1 deraadt 85: struct nlist namelist[] = {
1.53 deraadt 86: #define X_UVMEXP 0
1.29 art 87: { "_uvmexp" },
1.53 deraadt 88: #define X_BOOTTIME 1
1.1 deraadt 89: { "_boottime" },
1.53 deraadt 90: #define X_NCHSTATS 2
1.1 deraadt 91: { "_nchstats" },
1.53 deraadt 92: #define X_INTRNAMES 3
1.1 deraadt 93: { "_intrnames" },
1.53 deraadt 94: #define X_EINTRNAMES 4
1.1 deraadt 95: { "_eintrnames" },
1.53 deraadt 96: #define X_INTRCNT 5
1.1 deraadt 97: { "_intrcnt" },
1.53 deraadt 98: #define X_EINTRCNT 6
1.1 deraadt 99: { "_eintrcnt" },
1.53 deraadt 100: #define X_KMEMSTAT 7
1.1 deraadt 101: { "_kmemstats" },
1.53 deraadt 102: #define X_KMEMBUCKETS 8
1.1 deraadt 103: { "_bucket" },
1.53 deraadt 104: #define X_ALLEVENTS 9
1.1 deraadt 105: { "_allevents" },
1.53 deraadt 106: #define X_FORKSTAT 10
1.12 tholo 107: { "_forkstat" },
1.53 deraadt 108: #define X_POOLHEAD 11
1.48 art 109: { "_pool_head" },
1.53 deraadt 110: #define X_NSELCOLL 12
1.50 art 111: { "_nselcoll" },
1.53 deraadt 112: #define X_END 13
1.28 espie 113: #if defined(__i386__)
1.12 tholo 114: #define X_INTRHAND (X_END)
115: { "_intrhand" },
116: #define X_INTRSTRAY (X_END+1)
117: { "_intrstray" },
118: #endif
1.1 deraadt 119: { "" },
120: };
121:
1.6 tholo 122: /* Objects defined in dkstats.c */
123: extern struct _disk cur;
1.10 deraadt 124: extern char **dr_name;
125: extern int *dk_select, dk_ndrive;
1.1 deraadt 126:
1.29 art 127: struct uvmexp uvmexp, ouvmexp;
1.6 tholo 128: int ndrives;
1.1 deraadt 129:
130: int winlines = 20;
131:
132: kvm_t *kd;
133:
134: #define FORKSTAT 0x01
135: #define INTRSTAT 0x02
136: #define MEMSTAT 0x04
137: #define SUMSTAT 0x08
138: #define TIMESTAT 0x10
139: #define VMSTAT 0x20
140:
1.10 deraadt 141: void cpustats __P((void));
142: void dkstats __P((void));
143: void dointr __P((void));
144: void domem __P((void));
1.48 art 145: void dopool __P((void));
1.10 deraadt 146: void dosum __P((void));
147: void dovmstat __P((u_int, int));
148: void kread __P((int, void *, size_t));
149: void usage __P((void));
150: void dotimes __P((void));
151: void doforkst __P((void));
1.21 millert 152: void printhdr __P((void));
1.1 deraadt 153:
1.10 deraadt 154: char **choosedrives __P((char **));
155:
156: /* Namelist and memory file names. */
157: char *nlistf, *memf;
1.6 tholo 158:
1.50 art 159: extern char *__progname;
160:
1.21 millert 161: int
1.1 deraadt 162: main(argc, argv)
163: register int argc;
164: register char **argv;
165: {
166: extern int optind;
167: extern char *optarg;
168: register int c, todo;
169: u_int interval;
170: int reps;
1.25 deraadt 171: char errbuf[_POSIX2_LINE_MAX];
1.1 deraadt 172:
173: interval = reps = todo = 0;
1.16 millert 174: while ((c = getopt(argc, argv, "c:fiM:mN:stw:")) != -1) {
1.1 deraadt 175: switch (c) {
176: case 'c':
177: reps = atoi(optarg);
178: break;
179: case 'f':
180: todo |= FORKSTAT;
181: break;
182: case 'i':
183: todo |= INTRSTAT;
184: break;
185: case 'M':
186: memf = optarg;
187: break;
188: case 'm':
189: todo |= MEMSTAT;
190: break;
191: case 'N':
192: nlistf = optarg;
193: break;
194: case 's':
195: todo |= SUMSTAT;
196: break;
197: case 't':
198: todo |= TIMESTAT;
199: break;
200: case 'w':
201: interval = atoi(optarg);
202: break;
203: case '?':
204: default:
205: usage();
206: }
207: }
208: argc -= optind;
209: argv += optind;
210:
211: if (todo == 0)
212: todo = VMSTAT;
213:
1.56 angelos 214: if (nlistf != NULL || memf != NULL) {
215: setegid(getgid());
216: setgid(getgid());
217: }
218:
1.1 deraadt 219: /*
220: * Discard setgid privileges if not the running kernel so that bad
221: * guys can't print interesting stuff from kernel memory.
222: */
1.56 angelos 223: #if notyet
1.15 tholo 224: if (nlistf != NULL || memf != NULL) {
1.56 angelos 225: #endif
226: kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
227: if (kd == 0)
228: errx(1, "kvm_openfiles: %s", errbuf);
229:
230: if ((c = kvm_nlist(kd, namelist)) != 0) {
231: setgid(getgid());
232: setegid(getegid());
233:
234: if (c > 0) {
235: (void)fprintf(stderr,
236: "%s: undefined symbols:", __progname);
237: for (c = 0;
238: c < sizeof(namelist)/sizeof(namelist[0]);
239: c++)
240: if (namelist[c].n_type == 0)
241: fprintf(stderr, " %s",
242: namelist[c].n_name);
243: (void)fputc('\n', stderr);
244: exit(1);
245: } else
246: errx(1, "kvm_nlist: %s", kvm_geterr(kd));
247: }
248: #ifdef notyet
1.15 tholo 249: }
1.59 heko 250: #endif /* notyet */
1.1 deraadt 251:
1.56 angelos 252: setegid(getegid());
253: setgid(getgid());
1.1 deraadt 254:
255: if (todo & VMSTAT) {
256: struct winsize winsize;
257:
1.6 tholo 258: dkinit(0); /* Initialize disk stats, no disks selected. */
259: argv = choosedrives(argv); /* Select disks. */
1.1 deraadt 260: winsize.ws_row = 0;
261: (void) ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&winsize);
262: if (winsize.ws_row > 0)
263: winlines = winsize.ws_row;
264:
265: }
1.25 deraadt 266:
1.1 deraadt 267: #define BACKWARD_COMPATIBILITY
268: #ifdef BACKWARD_COMPATIBILITY
269: if (*argv) {
270: interval = atoi(*argv);
271: if (*++argv)
272: reps = atoi(*argv);
273: }
274: #endif
275:
276: if (interval) {
277: if (!reps)
278: reps = -1;
279: } else if (reps)
280: interval = 1;
281:
282: if (todo & FORKSTAT)
283: doforkst();
1.48 art 284: if (todo & MEMSTAT) {
1.1 deraadt 285: domem();
1.48 art 286: dopool();
287: }
1.1 deraadt 288: if (todo & SUMSTAT)
289: dosum();
290: if (todo & TIMESTAT)
291: dotimes();
292: if (todo & INTRSTAT)
293: dointr();
294: if (todo & VMSTAT)
295: dovmstat(interval, reps);
296: exit(0);
297: }
298:
299: char **
1.6 tholo 300: choosedrives(argv)
1.1 deraadt 301: char **argv;
302: {
303: register int i;
304:
305: /*
306: * Choose drives to be displayed. Priority goes to (in order) drives
307: * supplied as arguments, default drives. If everything isn't filled
308: * in and there are drives not taken care of, display the first few
309: * that fit.
310: */
311: #define BACKWARD_COMPATIBILITY
312: for (ndrives = 0; *argv; ++argv) {
313: #ifdef BACKWARD_COMPATIBILITY
314: if (isdigit(**argv))
315: break;
316: #endif
317: for (i = 0; i < dk_ndrive; i++) {
318: if (strcmp(dr_name[i], *argv))
319: continue;
1.6 tholo 320: dk_select[i] = 1;
1.1 deraadt 321: ++ndrives;
322: break;
323: }
324: }
325: for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
1.6 tholo 326: if (dk_select[i])
1.1 deraadt 327: continue;
1.6 tholo 328: dk_select[i] = 1;
1.1 deraadt 329: ++ndrives;
330: }
331: return(argv);
332: }
333:
1.19 deraadt 334: time_t
1.1 deraadt 335: getuptime()
336: {
1.11 deraadt 337: static time_t now;
338: static struct timeval boottime;
1.1 deraadt 339: time_t uptime;
1.50 art 340: int mib[2];
341: size_t size;
1.1 deraadt 342:
1.50 art 343: if (boottime.tv_sec == 0) {
1.56 angelos 344: if (nlistf == NULL && memf == NULL) {
1.50 art 345: size = sizeof(boottime);
346: mib[0] = CTL_KERN;
347: mib[1] = KERN_BOOTTIME;
348: if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) {
1.56 angelos 349: warn("could not get kern.boottime");
1.50 art 350: bzero(&boottime, sizeof(boottime));
351: }
1.56 angelos 352: } else {
353: kread(X_BOOTTIME, &boottime, sizeof(boottime));
1.50 art 354: }
355: }
1.1 deraadt 356: (void)time(&now);
1.11 deraadt 357: uptime = now - boottime.tv_sec;
1.50 art 358: if (uptime <= 0 || uptime > 60*60*24*365*10)
359: errx(1, "time makes no sense; namelist must be wrong");
360:
1.1 deraadt 361: return(uptime);
362: }
363:
364: int hz, hdrcnt;
365:
366: void
367: dovmstat(interval, reps)
368: u_int interval;
369: int reps;
370: {
371: struct vmtotal total;
372: time_t uptime, halfuptime;
373: void needhdr();
374: int mib[2];
1.50 art 375: struct clockinfo clkinfo;
1.1 deraadt 376: size_t size;
377:
378: uptime = getuptime();
379: halfuptime = uptime / 2;
380: (void)signal(SIGCONT, needhdr);
381:
1.50 art 382: mib[0] = CTL_KERN;
383: mib[1] = KERN_CLOCKRATE;
384: size = sizeof(clkinfo);
385: if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0) {
1.56 angelos 386: warn("could not read kern.clockrate");
1.50 art 387: return;
388: }
389: hz = clkinfo.stathz;
1.1 deraadt 390:
391: for (hdrcnt = 1;;) {
392: if (!--hdrcnt)
393: printhdr();
1.6 tholo 394: /* Read new disk statistics */
395: dkreadstats();
1.56 angelos 396: if (nlistf == NULL && memf == NULL) {
397: size = sizeof(struct uvmexp);
1.52 angelos 398: mib[0] = CTL_VM;
399: mib[1] = VM_UVMEXP;
400: if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
1.56 angelos 401: warn("could not get vm.uvmexp");
402: bzero(&uvmexp, sizeof(struct uvmexp));
1.52 angelos 403: }
1.56 angelos 404: } else {
405: kread(X_UVMEXP, &uvmexp, sizeof(struct uvmexp));
1.52 angelos 406: }
1.1 deraadt 407: size = sizeof(total);
408: mib[0] = CTL_VM;
409: mib[1] = VM_METER;
410: if (sysctl(mib, 2, &total, &size, NULL, 0) < 0) {
1.56 angelos 411: warn("could not read vm.vmmeter");
1.1 deraadt 412: bzero(&total, sizeof(total));
413: }
1.22 millert 414: (void)printf("%2u%2u%2u",
1.1 deraadt 415: total.t_rq - 1, total.t_dw + total.t_pw, total.t_sw);
1.29 art 416: #define rate(x) (((x) + halfuptime) / uptime) /* round */
417: #define pgtok(a) ((a) * ((int)uvmexp.pagesize >> 10))
1.35 hugh 418: (void)printf("%7u%7u ",
1.1 deraadt 419: pgtok(total.t_avm), pgtok(total.t_free));
1.29 art 420: (void)printf("%4u ", rate(uvmexp.faults - ouvmexp.faults));
421: (void)printf("%3u ", rate(uvmexp.pdreact - ouvmexp.pdreact));
422: (void)printf("%3u ", rate(uvmexp.pageins - ouvmexp.pageins));
423: (void)printf("%3u %3u ",
424: rate(uvmexp.pdpageouts - ouvmexp.pdpageouts), 0);
425: (void)printf("%3u ", rate(uvmexp.pdscans - ouvmexp.pdscans));
426: dkstats();
427: (void)printf("%4u %4u %3u ",
428: rate(uvmexp.intrs - ouvmexp.intrs),
429: rate(uvmexp.syscalls - ouvmexp.syscalls),
430: rate(uvmexp.swtch - ouvmexp.swtch));
1.1 deraadt 431: cpustats();
432: (void)printf("\n");
433: (void)fflush(stdout);
434: if (reps >= 0 && --reps <= 0)
435: break;
1.29 art 436: ouvmexp = uvmexp;
1.1 deraadt 437: uptime = interval;
438: /*
439: * We round upward to avoid losing low-frequency events
440: * (i.e., >= 1 per interval but < 1 per second).
441: */
1.14 deraadt 442: halfuptime = uptime == 1 ? 0 : (uptime + 1) / 2;
1.1 deraadt 443: (void)sleep(interval);
444: }
445: }
446:
1.21 millert 447: void
1.1 deraadt 448: printhdr()
449: {
450: register int i;
451:
1.35 hugh 452: (void)printf(" procs memory page%*s", 20, "");
1.6 tholo 453: if (ndrives > 0)
454: (void)printf("%s %*sfaults cpu\n",
455: ((ndrives > 1) ? "disks" : "disk"),
456: ((ndrives > 1) ? ndrives * 3 - 4 : 0), "");
1.1 deraadt 457: else
1.6 tholo 458: (void)printf("%*s faults cpu\n",
459: ndrives * 3, "");
460:
1.35 hugh 461: (void)printf(" r b w avm fre flt re pi po fr sr ");
1.1 deraadt 462: for (i = 0; i < dk_ndrive; i++)
1.6 tholo 463: if (dk_select[i])
1.1 deraadt 464: (void)printf("%c%c ", dr_name[i][0],
465: dr_name[i][strlen(dr_name[i]) - 1]);
466: (void)printf(" in sy cs us sy id\n");
467: hdrcnt = winlines - 2;
468: }
469:
470: /*
471: * Force a header to be prepended to the next output.
472: */
473: void
474: needhdr()
475: {
476:
477: hdrcnt = 1;
478: }
479:
480: void
481: dotimes()
482: {
483: u_int pgintime, rectime;
1.52 angelos 484: int mib[2];
485: size_t size;
1.1 deraadt 486:
1.56 angelos 487: /* XXX Why are these set to 0 ? This doesn't look right. */
1.12 tholo 488: pgintime = 0;
489: rectime = 0;
1.56 angelos 490:
491: if (nlistf == NULL && memf == NULL) {
492: size = sizeof(struct uvmexp);
1.52 angelos 493: mib[0] = CTL_VM;
494: mib[1] = VM_UVMEXP;
495: if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
1.56 angelos 496: warn("could not read vm.uvmexp");
497: bzero(&uvmexp, sizeof(struct uvmexp));
1.52 angelos 498: }
1.56 angelos 499: } else {
500: kread(X_UVMEXP, &uvmexp, sizeof(struct uvmexp));
1.52 angelos 501: }
502:
1.29 art 503: (void)printf("%u reactivates, %u total time (usec)\n",
504: uvmexp.pdreact, rectime);
505: (void)printf("average: %u usec / reclaim\n", rectime / uvmexp.pdreact);
506: (void)printf("\n");
507: (void)printf("%u page ins, %u total time (msec)\n",
508: uvmexp.pageins, pgintime / 10);
509: (void)printf("average: %8.1f msec / page in\n",
510: pgintime / (uvmexp.pageins * 10.0));
1.1 deraadt 511: }
512:
1.21 millert 513: int
1.1 deraadt 514: pct(top, bot)
515: long top, bot;
516: {
517: long ans;
518:
519: if (bot == 0)
520: return(0);
521: ans = (quad_t)top * 100 / bot;
522: return (ans);
523: }
524:
525: #define PCT(top, bot) pct((long)(top), (long)(bot))
526:
527: void
528: dosum()
529: {
530: struct nchstats nchstats;
531: long nchtotal;
1.52 angelos 532: size_t size;
533: int mib[2], nselcoll;
1.1 deraadt 534:
1.56 angelos 535: if (nlistf == NULL && memf == NULL) {
536: size = sizeof(struct uvmexp);
1.52 angelos 537: mib[0] = CTL_VM;
538: mib[1] = VM_UVMEXP;
539: if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
1.56 angelos 540: warn("could not read vm.uvmexp");
541: bzero(&uvmexp, sizeof(struct uvmexp));
1.52 angelos 542: }
1.56 angelos 543: } else {
544: kread(X_UVMEXP, &uvmexp, sizeof(struct uvmexp));
1.52 angelos 545: }
546:
1.32 art 547: /* vm_page constants */
1.35 hugh 548: (void)printf("%11u bytes per page\n", uvmexp.pagesize);
1.32 art 549:
550: /* vm_page counters */
1.35 hugh 551: (void)printf("%11u pages managed\n", uvmexp.npages);
552: (void)printf("%11u pages free\n", uvmexp.free);
553: (void)printf("%11u pages active\n", uvmexp.active);
554: (void)printf("%11u pages inactive\n", uvmexp.inactive);
555: (void)printf("%11u pages being paged out\n", uvmexp.paging);
556: (void)printf("%11u pages wired\n", uvmexp.wired);
557: (void)printf("%11u pages reserved for pagedaemon\n",
1.48 art 558: uvmexp.reserve_pagedaemon);
1.35 hugh 559: (void)printf("%11u pages reserved for kernel\n",
1.48 art 560: uvmexp.reserve_kernel);
1.32 art 561:
562: /* swap */
1.35 hugh 563: (void)printf("%11u swap pages\n", uvmexp.swpages);
564: (void)printf("%11u swap pages in use\n", uvmexp.swpginuse);
565: (void)printf("%11u total anon's in system\n", uvmexp.nanon);
566: (void)printf("%11u free anon's\n", uvmexp.nfreeanon);
1.32 art 567:
568: /* stat counters */
1.35 hugh 569: (void)printf("%11u page faults\n", uvmexp.faults);
570: (void)printf("%11u traps\n", uvmexp.traps);
571: (void)printf("%11u interrupts\n", uvmexp.intrs);
572: (void)printf("%11u cpu context switches\n", uvmexp.swtch);
573: (void)printf("%11u software interrupts\n", uvmexp.softs);
574: (void)printf("%11u syscalls\n", uvmexp.syscalls);
575: (void)printf("%11u pagein operations\n", uvmexp.pageins);
576: (void)printf("%11u swap ins\n", uvmexp.swapins);
577: (void)printf("%11u swap outs\n", uvmexp.swapouts);
578: (void)printf("%11u forks\n", uvmexp.forks);
579: (void)printf("%11u forks where vmspace is shared\n",
1.48 art 580: uvmexp.forks_sharevm);
1.32 art 581:
582: /* daemon counters */
1.37 art 583: (void)printf("%11u number of times the pagedeamon woke up\n",
1.48 art 584: uvmexp.pdwoke);
1.35 hugh 585: (void)printf("%11u revolutions of the clock hand\n", uvmexp.pdrevs);
586: (void)printf("%11u pages freed by pagedaemon\n", uvmexp.pdfreed);
587: (void)printf("%11u pages scanned by pagedaemon\n", uvmexp.pdscans);
588: (void)printf("%11u pages reactivated by pagedaemon\n", uvmexp.pdreact);
589: (void)printf("%11u busy pages found by pagedaemon\n", uvmexp.pdbusy);
1.29 art 590:
1.56 angelos 591: if (nlistf == NULL && memf == NULL) {
1.52 angelos 592: size = sizeof(nchstats);
593: mib[0] = CTL_KERN;
594: mib[1] = KERN_NCHSTATS;
595: if (sysctl(mib, 2, &nchstats, &size, NULL, 0) < 0) {
1.56 angelos 596: warn("could not read kern.nchstats");
1.52 angelos 597: bzero(&nchstats, sizeof(nchstats));
598: }
1.56 angelos 599: } else {
600: kread(X_NCHSTATS, &nchstats, sizeof(nchstats));
1.52 angelos 601: }
602:
1.1 deraadt 603: nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits +
604: nchstats.ncs_badhits + nchstats.ncs_falsehits +
605: nchstats.ncs_miss + nchstats.ncs_long;
1.35 hugh 606: (void)printf("%11ld total name lookups\n", nchtotal);
1.52 angelos 607: (void)printf("%11s cache hits (%d%% pos + %d%% neg) system %d%% "
608: "per-directory\n",
1.1 deraadt 609: "", PCT(nchstats.ncs_goodhits, nchtotal),
610: PCT(nchstats.ncs_neghits, nchtotal),
611: PCT(nchstats.ncs_pass2, nchtotal));
1.35 hugh 612: (void)printf("%11s deletions %d%%, falsehits %d%%, toolong %d%%\n", "",
1.1 deraadt 613: PCT(nchstats.ncs_badhits, nchtotal),
614: PCT(nchstats.ncs_falsehits, nchtotal),
615: PCT(nchstats.ncs_long, nchtotal));
1.52 angelos 616:
1.56 angelos 617: if (nlistf == NULL && memf == NULL) {
1.52 angelos 618: size = sizeof(nselcoll);
619: mib[0] = CTL_KERN;
620: mib[1] = KERN_NSELCOLL;
621: if (sysctl(mib, 2, &nselcoll, &size, NULL, 0) < 0) {
1.56 angelos 622: warn("could not read kern.nselcoll");
1.52 angelos 623: nselcoll = 0;
624: }
1.56 angelos 625: } else {
626: kread(X_NSELCOLL, &nselcoll, sizeof(nselcoll));
1.52 angelos 627: }
1.50 art 628: (void)printf("%11d select collisions\n", nselcoll);
1.1 deraadt 629: }
630:
631: void
632: doforkst()
633: {
634: struct forkstat fks;
1.52 angelos 635: size_t size;
636: int mib[2];
637:
1.56 angelos 638: if (nlistf == NULL && memf == NULL) {
1.52 angelos 639: size = sizeof(struct forkstat);
640: mib[0] = CTL_KERN;
641: mib[1] = KERN_FORKSTAT;
642: if (sysctl(mib, 2, &fks, &size, NULL, 0) < 0) {
1.56 angelos 643: warn("could not read kern.forkstat");
1.52 angelos 644: bzero(&fks, sizeof(struct forkstat));
645: }
1.56 angelos 646: } else {
647: kread(X_FORKSTAT, &fks, sizeof(struct forkstat));
1.52 angelos 648: }
1.1 deraadt 649:
650: (void)printf("%d forks, %d pages, average %.2f\n",
651: fks.cntfork, fks.sizfork, (double)fks.sizfork / fks.cntfork);
652: (void)printf("%d vforks, %d pages, average %.2f\n",
1.12 tholo 653: fks.cntvfork, fks.sizvfork, (double)fks.sizvfork / (fks.cntvfork ? fks.cntvfork : 1));
654: (void)printf("%d rforks, %d pages, average %.2f\n",
655: fks.cntrfork, fks.sizrfork, (double)fks.sizrfork / (fks.cntrfork ? fks.cntrfork : 1));
1.36 niklas 656: (void)printf("%d kthread creations, %d pages, average %.2f\n",
657: fks.cntkthread, fks.sizkthread, (double)fks.sizkthread / (fks.cntkthread ? fks.cntkthread : 1));
1.1 deraadt 658: }
659:
660: void
661: dkstats()
662: {
663: register int dn, state;
664: double etime;
665:
1.6 tholo 666: /* Calculate disk stat deltas. */
667: dkswap();
1.1 deraadt 668: etime = 0;
669: for (state = 0; state < CPUSTATES; ++state) {
1.6 tholo 670: etime += cur.cp_time[state];
1.1 deraadt 671: }
672: if (etime == 0)
673: etime = 1;
674: etime /= hz;
675: for (dn = 0; dn < dk_ndrive; ++dn) {
1.6 tholo 676: if (!dk_select[dn])
1.1 deraadt 677: continue;
1.6 tholo 678: (void)printf("%2.0f ", cur.dk_xfer[dn] / etime);
1.1 deraadt 679: }
680: }
681:
682: void
683: cpustats()
684: {
685: register int state;
686: double pct, total;
687:
688: total = 0;
689: for (state = 0; state < CPUSTATES; ++state)
1.6 tholo 690: total += cur.cp_time[state];
1.1 deraadt 691: if (total)
692: pct = 100 / total;
693: else
694: pct = 0;
1.6 tholo 695: (void)printf("%2.0f ", (cur.cp_time[CP_USER] + cur.cp_time[CP_NICE]) * pct);
696: (void)printf("%2.0f ", (cur.cp_time[CP_SYS] + cur.cp_time[CP_INTR]) * pct);
697: (void)printf("%2.0f", cur.cp_time[CP_IDLE] * pct);
1.1 deraadt 698: }
699:
1.53 deraadt 700: #if defined(__i386__)
1.12 tholo 701: /* To get struct intrhand */
1.13 tholo 702: #define _KERNEL
1.12 tholo 703: #include <machine/psl.h>
1.56 angelos 704: #include <machine/cpu.h>
1.13 tholo 705: #undef _KERNEL
1.12 tholo 706: void
707: dointr()
708: {
709: struct intrhand *intrhand[16], *ihp, ih;
1.56 angelos 710: u_long inttotal = 0;
1.19 deraadt 711: time_t uptime;
1.50 art 712: u_long intrstray[16];
1.34 deraadt 713: char iname[17], fname[31];
1.58 pvalchev 714: int i;
715: #if 0
716: int mib[2], l, incflag;
1.56 angelos 717: size_t size;
718: char *intrnames, *intrcount, *intrn, *intrc, *buf1, *buf2;
1.58 pvalchev 719: #endif
1.12 tholo 720:
721: iname[16] = '\0';
722: uptime = getuptime();
723:
1.27 alex 724: (void)printf("interrupt total rate\n");
1.56 angelos 725:
726: #if 0 /* XXX Something else is needed here....get on with it Theo! */
727: if (nlistf == NULL && memf == NULL) {
728: mib[0] = CTL_MACHDEP;
729: mib[1] = CPU_INTRNAMES;
730: size = 0;
731: if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0)
732: err(1, "could not get machdep.intrnames");
733: intrnames = calloc(size, sizeof(char));
734: if (intrnames == NULL)
735: err(1,
736: "could not allocate memory for interrupt names");
737: if (sysctl(mib, 2, intrnames, &size, NULL, 0) < 0)
738: err(1, "could not get machdep.intrnames");
739:
740: mib[1] = CPU_INTRCOUNT;
741: size = 0;
742: if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0)
743: err(1, "could not get machdep.intrcount");
744: intrcount = calloc(size, sizeof(char));
745: if (intrcount == NULL)
746: err(1,
747: "could not allocate memory for interrupt count");
748: if (sysctl(mib, 2, intrcount, &size, NULL, 0) < 0)
749: err(1, "could not get machdep.intrcount");
750:
751: mib[1] = CPU_INTRSTRAY;
752: size = sizeof(intrstray);
753: if (sysctl(mib, 2, intrstray, &size, NULL, 0) < 0) {
754: warn("could not get machdep.intrstray");
755: bzero(intrstray, sizeof(intrstray));
756: }
757:
758: buf1 = intrnames;
759: buf2 = intrcount;
760: i = 0;
761: while ((intrn = strsep(&buf1, ",/")) != NULL) {
762: /* Find what the next delimiter is */
763: for (l = 0; buf2[l] != '\0'; l++) {
764: if (buf2[l] == '/') {
765: /* Don't increase the irq count */
766: incflag = 0;
767: break;
768: } else if (buf2[l] == ',') {
769: incflag = 1;
770: break;
771: }
772: }
773:
774: if ((intrc = strsep(&buf2, ",/")) == NULL)
775: errx(1, "unexpected failure matching interrupts with usage counters");
776:
777: /* Unused interrupt ? If so, skip this entry */
778: if (intrn[0] == '\0') {
779: if (incflag)
780: i++;
781: continue;
782: }
783:
784: snprintf(fname, sizeof fname, "irq%d/%s", i, intrn);
785: printf("%-16.16s %10lu %8lu\n", fname,
786: strtoul(intrc, NULL, 10),
787: strtoul(intrc, NULL, 10) / uptime);
788: inttotal += strtoul(intrc, NULL, 10);
789:
790: if (incflag)
791: i++;
792: }
793:
794: free(intrnames);
795: free(intrcount);
796: } else
797: #endif /* 0 */
798: {
799: kread(X_INTRHAND, intrhand, sizeof(intrhand));
800: kread(X_INTRSTRAY, intrstray, sizeof(intrstray));
801:
802: for (i = 0; i < 16; i++) {
803: ihp = intrhand[i];
804: while (ihp) {
805: if (kvm_read(kd, (u_long)ihp, &ih,
806: sizeof(ih)) != sizeof(ih))
807: errx(1, "vmstat: ih: %s",
808: kvm_geterr(kd));
809: if (kvm_read(kd, (u_long)ih.ih_what, iname,
810: 16) != 16)
811: errx(1, "vmstat: ih_what: %s",
812: kvm_geterr(kd));
813: snprintf(fname, sizeof fname, "irq%d/%s", i,
814: iname);
815: printf("%-16.16s %10lu %8lu\n", fname,
816: ih.ih_count, ih.ih_count / uptime);
817: inttotal += ih.ih_count;
818: ihp = ih.ih_next;
819: }
1.12 tholo 820: }
821: }
1.56 angelos 822:
1.12 tholo 823: for (i = 0; i < 16; i++)
824: if (intrstray[i]) {
1.50 art 825: printf("Stray irq %-2d %10lu %8lu\n",
1.53 deraadt 826: i, intrstray[i], intrstray[i] / uptime);
1.12 tholo 827: inttotal += intrstray[i];
828: }
1.50 art 829: printf("Total %10lu %8lu\n", inttotal, inttotal / uptime);
1.1 deraadt 830: }
831: #else
832: void
833: dointr()
834: {
1.19 deraadt 835: register long *intrcnt, inttotal;
836: time_t uptime;
1.1 deraadt 837: register int nintr, inamlen;
838: register char *intrname;
1.9 deraadt 839: struct evcntlist allevents;
840: struct evcnt evcnt, *evptr;
1.1 deraadt 841: struct device dev;
842:
843: uptime = getuptime();
844: nintr = namelist[X_EINTRCNT].n_value - namelist[X_INTRCNT].n_value;
845: inamlen =
846: namelist[X_EINTRNAMES].n_value - namelist[X_INTRNAMES].n_value;
847: intrcnt = malloc((size_t)nintr);
848: intrname = malloc((size_t)inamlen);
1.50 art 849: if (intrcnt == NULL || intrname == NULL)
850: err(1, "malloc");
1.1 deraadt 851: kread(X_INTRCNT, intrcnt, (size_t)nintr);
852: kread(X_INTRNAMES, intrname, (size_t)inamlen);
1.27 alex 853: (void)printf("interrupt total rate\n");
1.1 deraadt 854: inttotal = 0;
855: nintr /= sizeof(long);
856: while (--nintr >= 0) {
857: if (*intrcnt)
1.27 alex 858: (void)printf("%-14s %12ld %8ld\n", intrname,
1.1 deraadt 859: *intrcnt, *intrcnt / uptime);
860: intrname += strlen(intrname) + 1;
861: inttotal += *intrcnt++;
862: }
863: kread(X_ALLEVENTS, &allevents, sizeof allevents);
1.9 deraadt 864: evptr = allevents.tqh_first;
865: while (evptr) {
866: if (kvm_read(kd, (long)evptr, (void *)&evcnt,
1.50 art 867: sizeof evcnt) != sizeof evcnt)
868: errx(1, "event chain trashed: %s", kvm_geterr(kd));
1.1 deraadt 869: if (strcmp(evcnt.ev_name, "intr") == 0) {
870: if (kvm_read(kd, (long)evcnt.ev_dev, (void *)&dev,
1.50 art 871: sizeof dev) != sizeof dev)
872: errx(1, "event chain trashed: %s", kvm_geterr(kd));
1.1 deraadt 873: if (evcnt.ev_count)
1.33 art 874: (void)printf("%-14s %12d %8ld\n", dev.dv_xname,
875: evcnt.ev_count, (long)(evcnt.ev_count / uptime));
1.1 deraadt 876: inttotal += evcnt.ev_count++;
877: }
1.9 deraadt 878: evptr = evcnt.ev_list.tqe_next;
1.1 deraadt 879: }
1.27 alex 880: (void)printf("Total %12ld %8ld\n", inttotal, inttotal / uptime);
1.1 deraadt 881: }
882: #endif
883:
884: /*
885: * These names are defined in <sys/malloc.h>.
886: */
887: char *kmemnames[] = INITKMEMNAMES;
888:
889: void
890: domem()
891: {
892: register struct kmembuckets *kp;
893: register struct kmemstats *ks;
894: register int i, j;
895: int len, size, first;
1.50 art 896: u_long totuse = 0, totfree = 0;
897: quad_t totreq = 0;
1.1 deraadt 898: char *name;
899: struct kmemstats kmemstats[M_LAST];
900: struct kmembuckets buckets[MINBUCKET + 16];
1.50 art 901: int mib[4];
902: size_t siz;
903: char buf[BUFSIZ], *bufp, *ap;
904:
905: if (memf == NULL && nlistf == NULL) {
1.53 deraadt 906: mib[0] = CTL_KERN;
1.50 art 907: mib[1] = KERN_MALLOCSTATS;
908: mib[2] = KERN_MALLOC_BUCKETS;
909: siz = sizeof(buf);
910: if (sysctl(mib, 3, buf, &siz, NULL, 0) < 0) {
1.56 angelos 911: warnx("could not read kern.malloc.buckets");
1.50 art 912: return;
913: }
914:
915: bufp = buf;
916: mib[2] = KERN_MALLOC_BUCKET;
917: siz = sizeof(struct kmembuckets);
918: i = 0;
919: while ((ap = strsep(&bufp, ",")) != NULL) {
1.53 deraadt 920: mib[3] = atoi(ap);
1.50 art 921:
922: if (sysctl(mib, 4, &buckets[MINBUCKET + i], &siz,
1.53 deraadt 923: NULL, 0) < 0) {
1.56 angelos 924: warn("could not read kern.malloc.bucket.%d", mib[3]);
1.50 art 925: return;
926: }
927: i++;
928: }
929: } else {
1.53 deraadt 930: kread(X_KMEMBUCKETS, buckets, sizeof(buckets));
1.50 art 931: }
1.1 deraadt 932:
1.18 kstailey 933: for (first = 1, i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16;
934: i++, kp++) {
1.1 deraadt 935: if (kp->kb_calls == 0)
936: continue;
1.18 kstailey 937: if (first) {
938: (void)printf("Memory statistics by bucket size\n");
939: (void)printf(
1.50 art 940: " Size In Use Free Requests HighWater Couldfree\n");
1.18 kstailey 941: first = 0;
942: }
1.1 deraadt 943: size = 1 << i;
1.60 ! art 944: (void)printf("%8d %8llu %6llu %18llu %7llu %10llu\n", size,
! 945: (unsigned long long)(kp->kb_total - kp->kb_totalfree),
! 946: (unsigned long long)kp->kb_totalfree,
! 947: (unsigned long long)kp->kb_calls,
! 948: (unsigned long long)kp->kb_highwat,
! 949: (unsigned long long)kp->kb_couldfree);
1.1 deraadt 950: totfree += size * kp->kb_totalfree;
1.18 kstailey 951: }
952:
953: /*
954: * If kmem statistics are not being gathered by the kernel,
955: * first will still be 1.
956: */
957: if (first) {
958: printf(
959: "Kmem statistics are not being gathered by the kernel.\n");
960: return;
1.1 deraadt 961: }
962:
1.52 angelos 963: if (memf == NULL && nlistf == NULL) {
964: bzero(kmemstats, sizeof(kmemstats));
965: for (i = 0; i < M_LAST; i++) {
1.53 deraadt 966: mib[0] = CTL_KERN;
1.52 angelos 967: mib[1] = KERN_MALLOCSTATS;
968: mib[2] = KERN_MALLOC_KMEMSTATS;
969: mib[3] = i;
970: siz = sizeof(struct kmemstats);
971:
972: /*
973: * Skip errors -- these are presumed to be unallocated
974: * entries.
975: */
976: if (sysctl(mib, 4, &kmemstats[i], &siz, NULL, 0) < 0)
977: continue;
978: }
979: } else {
980: kread(X_KMEMSTAT, kmemstats, sizeof(kmemstats));
981: }
982:
1.1 deraadt 983: (void)printf("\nMemory usage type by bucket size\n");
984: (void)printf(" Size Type(s)\n");
985: kp = &buckets[MINBUCKET];
986: for (j = 1 << MINBUCKET; j < 1 << (MINBUCKET + 16); j <<= 1, kp++) {
987: if (kp->kb_calls == 0)
988: continue;
989: first = 1;
990: len = 8;
991: for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
992: if (ks->ks_calls == 0)
993: continue;
994: if ((ks->ks_size & j) == 0)
995: continue;
996: name = kmemnames[i] ? kmemnames[i] : "undefined";
997: len += 2 + strlen(name);
998: if (first)
999: printf("%8d %s", j, name);
1000: else
1001: printf(",");
1002: if (len >= 80) {
1003: printf("\n\t ");
1004: len = 10 + strlen(name);
1005: }
1006: if (!first)
1007: printf(" %s", name);
1008: first = 0;
1009: }
1010: printf("\n");
1011: }
1012:
1013: (void)printf(
1.26 deraadt 1014: "\nMemory statistics by type Type Kern\n");
1.1 deraadt 1015: (void)printf(
1.26 deraadt 1016: " Type InUse MemUse HighUse Limit Requests Limit Limit Size(s)\n");
1.1 deraadt 1017: for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
1018: if (ks->ks_calls == 0)
1019: continue;
1.24 mickey 1020: (void)printf("%14s%6ld%6ldK%7ldK%6ldK%9ld%5u%6u",
1.1 deraadt 1021: kmemnames[i] ? kmemnames[i] : "undefined",
1022: ks->ks_inuse, (ks->ks_memuse + 1023) / 1024,
1023: (ks->ks_maxused + 1023) / 1024,
1024: (ks->ks_limit + 1023) / 1024, ks->ks_calls,
1025: ks->ks_limblocks, ks->ks_mapblocks);
1026: first = 1;
1027: for (j = 1 << MINBUCKET; j < 1 << (MINBUCKET + 16); j <<= 1) {
1028: if ((ks->ks_size & j) == 0)
1029: continue;
1030: if (first)
1031: printf(" %d", j);
1032: else
1033: printf(",%d", j);
1034: first = 0;
1035: }
1036: printf("\n");
1037: totuse += ks->ks_memuse;
1038: totreq += ks->ks_calls;
1039: }
1040: (void)printf("\nMemory Totals: In Use Free Requests\n");
1.50 art 1041: (void)printf(" %7luK %6luK %8qu\n",
1.1 deraadt 1042: (totuse + 1023) / 1024, (totfree + 1023) / 1024, totreq);
1043: }
1044:
1.54 art 1045: static void
1046: print_pool(struct pool *pp, char *name)
1047: {
1048: static int first = 1;
1049: int ovflw;
1050: char maxp[32];
1051:
1052: if (first) {
1053: (void)printf("Memory resource pool statistics\n");
1054: (void)printf(
1055: "%-11s%5s%9s%5s%9s%6s%6s%6s%6s%6s%6s%5s\n",
1056: "Name",
1057: "Size",
1058: "Requests",
1059: "Fail",
1060: "Releases",
1061: "Pgreq",
1062: "Pgrel",
1063: "Npage",
1064: "Hiwat",
1065: "Minpg",
1066: "Maxpg",
1067: "Idle");
1068: first = 0;
1069: }
1070: if (pp->pr_maxpages == UINT_MAX)
1071: sprintf(maxp, "inf");
1072: else
1073: sprintf(maxp, "%u", pp->pr_maxpages);
1074: /*
1075: * Print single word. `ovflow' is number of characters didn't fit
1076: * on the last word. `fmt' is a format string to print this word.
1077: * It must contain asterisk for field width. `width' is a width
1078: * occupied by this word. `fixed' is a number of constant chars in
1079: * `fmt'. `val' is a value to be printed using format string `fmt'.
1080: */
1081: #define PRWORD(ovflw, fmt, width, fixed, val) do { \
1082: (ovflw) += printf((fmt), \
1083: (width) - (fixed) - (ovflw) > 0 ? \
1084: (width) - (fixed) - (ovflw) : 0, \
1085: (val)) - (width); \
1086: if ((ovflw) < 0) \
1087: (ovflw) = 0; \
1088: } while (/* CONSTCOND */0)
1089:
1090: ovflw = 0;
1091: PRWORD(ovflw, "%-*s", 11, 0, name);
1092: PRWORD(ovflw, " %*u", 5, 1, pp->pr_size);
1093: PRWORD(ovflw, " %*lu", 9, 1, pp->pr_nget);
1094: PRWORD(ovflw, " %*lu", 5, 1, pp->pr_nfail);
1095: PRWORD(ovflw, " %*lu", 9, 1, pp->pr_nput);
1096: PRWORD(ovflw, " %*lu", 6, 1, pp->pr_npagealloc);
1097: PRWORD(ovflw, " %*lu", 6, 1, pp->pr_npagefree);
1098: PRWORD(ovflw, " %*d", 6, 1, pp->pr_npages);
1099: PRWORD(ovflw, " %*d", 6, 1, pp->pr_hiwat);
1100: PRWORD(ovflw, " %*d", 6, 1, pp->pr_minpages);
1101: PRWORD(ovflw, " %*s", 6, 1, maxp);
1102: PRWORD(ovflw, " %*lu\n", 5, 1, pp->pr_nidle);
1103: }
1104:
1.55 art 1105: static void dopool_kvm(void);
1106: static void dopool_sysctl(void);
1107:
1.48 art 1108: void
1109: dopool(void)
1110: {
1.55 art 1111: if (nlistf == NULL && memf == NULL)
1112: dopool_sysctl();
1113: else
1114: dopool_kvm();
1115: }
1116:
1117: void
1118: dopool_sysctl(void)
1119: {
1120: struct pool pool;
1121: size_t size;
1122: int mib[4];
1123: int npools, i;
1124:
1125: mib[0] = CTL_KERN;
1126: mib[1] = KERN_POOL;
1127: mib[2] = KERN_POOL_NPOOLS;
1128: size = sizeof(npools);
1129: if (sysctl(mib, 3, &npools, &size, NULL, 0) < 0) {
1130: printf("Can't figure out number of pools in kernel: %s\n",
1131: strerror(errno));
1132: return;
1133: }
1134:
1135: for (i = 1; npools; i++) {
1136: char name[32];
1137:
1138: mib[0] = CTL_KERN;
1139: mib[1] = KERN_POOL;
1140: mib[2] = KERN_POOL_POOL;
1141: mib[3] = i;
1142: size = sizeof(struct pool);
1143: if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
1144: if (errno == ENOENT)
1145: continue;
1146: printf("error getting pool: %s\n", strerror(errno));
1147: return;
1148: }
1149: npools--;
1150: mib[2] = KERN_POOL_NAME;
1151: size = sizeof(name);
1152: if (sysctl(mib, 4, &name, &size, NULL, 0) < 0) {
1153: printf("error getting pool name: %s\n",
1154: strerror(errno));
1155: return;
1156: }
1157: print_pool(&pool, name);
1158: }
1159: }
1160:
1161: void
1162: dopool_kvm(void)
1163: {
1.48 art 1164: long addr;
1165: long total = 0, inuse = 0;
1166: TAILQ_HEAD(,pool) pool_head;
1167: struct pool pool, *pp = &pool;
1168:
1169: kread(X_POOLHEAD, &pool_head, sizeof(pool_head));
1170: addr = (long)TAILQ_FIRST(&pool_head);
1171:
1.55 art 1172: while (addr != 0) {
1.54 art 1173: char name[32];
1.56 angelos 1174:
1.48 art 1175: if (kvm_read(kd, addr, (void *)pp, sizeof *pp) != sizeof *pp) {
1176: (void)fprintf(stderr,
1177: "vmstat: pool chain trashed: %s\n",
1178: kvm_geterr(kd));
1179: exit(1);
1180: }
1181: if (kvm_read(kd, (long)pp->pr_wchan, name, sizeof name) < 0) {
1182: (void)fprintf(stderr,
1183: "vmstat: pool name trashed: %s\n",
1184: kvm_geterr(kd));
1185: exit(1);
1186: }
1.56 angelos 1187:
1.48 art 1188: name[31] = '\0';
1189:
1.54 art 1190: print_pool(pp, name);
1.48 art 1191:
1192: inuse += (pp->pr_nget - pp->pr_nput) * pp->pr_size;
1193: total += pp->pr_npages * pp->pr_pagesz;
1.56 angelos 1194:
1.48 art 1195: addr = (long)TAILQ_NEXT(pp, pr_poollist);
1196: }
1197:
1198: inuse /= 1024;
1199: total /= 1024;
1200: printf("\nIn use %ldK, total allocated %ldK; utilization %.1f%%\n",
1201: inuse, total, (double)(100 * inuse) / total);
1202: }
1203:
1.1 deraadt 1204: /*
1205: * kread reads something from the kernel, given its nlist index.
1206: */
1207: void
1208: kread(nlx, addr, size)
1209: int nlx;
1210: void *addr;
1211: size_t size;
1212: {
1213: char *sym;
1214:
1215: if (namelist[nlx].n_type == 0 || namelist[nlx].n_value == 0) {
1216: sym = namelist[nlx].n_name;
1217: if (*sym == '_')
1218: ++sym;
1.50 art 1219: errx(1, "symbol %s not defined", sym);
1.1 deraadt 1220: }
1221: if (kvm_read(kd, namelist[nlx].n_value, addr, size) != size) {
1222: sym = namelist[nlx].n_name;
1223: if (*sym == '_')
1224: ++sym;
1.50 art 1225: errx(1, "%s: %s", sym, kvm_geterr(kd));
1.1 deraadt 1226: }
1227: }
1228:
1229: void
1230: usage()
1231: {
1.50 art 1232: (void)fprintf(stderr, "usage: %s [-fimst] [-c count] [-M core] "
1233: "[-N system] [-w wait] [disks]\n", __progname);
1.1 deraadt 1234: exit(1);
1235: }