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