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