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