vmstat.c revision 123409
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1980, 1986, 1991, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 3487690Smarkm#include <sys/cdefs.h> 3587690Smarkm 3687690Smarkm__FBSDID("$FreeBSD: head/usr.bin/vmstat/vmstat.c 123409 2003-12-10 22:11:51Z des $"); 3787690Smarkm 381590Srgrimes#ifndef lint 3928693Scharnierstatic const char copyright[] = 401590Srgrimes"@(#) Copyright (c) 1980, 1986, 1991, 1993\n\ 411590Srgrimes The Regents of the University of California. All rights reserved.\n"; 4287690Smarkm#endif 431590Srgrimes 441590Srgrimes#ifndef lint 4587690Smarkmstatic const char sccsid[] = "@(#)vmstat.c 8.1 (Berkeley) 6/6/93"; 4628693Scharnier#endif 471590Srgrimes 481590Srgrimes#include <sys/param.h> 491590Srgrimes#include <sys/time.h> 501590Srgrimes#include <sys/proc.h> 5112811Sbde#include <sys/uio.h> 521590Srgrimes#include <sys/namei.h> 531590Srgrimes#include <sys/malloc.h> 541590Srgrimes#include <sys/signal.h> 551590Srgrimes#include <sys/fcntl.h> 561590Srgrimes#include <sys/ioctl.h> 57111008Sphk#include <sys/resource.h> 581590Srgrimes#include <sys/sysctl.h> 5912804Speter#include <sys/vmmeter.h> 6012811Sbde 6112811Sbde#include <vm/vm_param.h> 6212811Sbde 6328693Scharnier#include <ctype.h> 6487690Smarkm#include <devstat.h> 6528693Scharnier#include <err.h> 6628693Scharnier#include <errno.h> 6728693Scharnier#include <kvm.h> 6828693Scharnier#include <limits.h> 691590Srgrimes#include <nlist.h> 7028693Scharnier#include <paths.h> 711590Srgrimes#include <stdio.h> 721590Srgrimes#include <stdlib.h> 731590Srgrimes#include <string.h> 7430180Sdima#include <sysexits.h> 7528693Scharnier#include <time.h> 7628693Scharnier#include <unistd.h> 771590Srgrimes 7887690Smarkmstatic char da[] = "da"; 7987690Smarkm 8087690Smarkmstatic struct nlist namelist[] = { 811590Srgrimes#define X_CPTIME 0 821590Srgrimes { "_cp_time" }, 8339230Sgibbs#define X_SUM 1 841590Srgrimes { "_cnt" }, 8539230Sgibbs#define X_BOOTTIME 2 861590Srgrimes { "_boottime" }, 8739230Sgibbs#define X_HZ 3 881590Srgrimes { "_hz" }, 8939230Sgibbs#define X_STATHZ 4 901590Srgrimes { "_stathz" }, 9139230Sgibbs#define X_NCHSTATS 5 921590Srgrimes { "_nchstats" }, 9339230Sgibbs#define X_INTRNAMES 6 941590Srgrimes { "_intrnames" }, 9539230Sgibbs#define X_EINTRNAMES 7 961590Srgrimes { "_eintrnames" }, 9739230Sgibbs#define X_INTRCNT 8 981590Srgrimes { "_intrcnt" }, 9939230Sgibbs#define X_EINTRCNT 9 1001590Srgrimes { "_eintrcnt" }, 10130180Sdima#ifdef notyet 10294729Sjeff#define X_DEFICIT 10 1031590Srgrimes { "_deficit" }, 104113460Stjr#define X_REC 11 1051590Srgrimes { "_rectime" }, 106113460Stjr#define X_PGIN 12 1071590Srgrimes { "_pgintime" }, 108113460Stjr#define X_XSTATS 13 1091590Srgrimes { "_xstats" }, 110113460Stjr#define X_END 14 11192653Sjeff#else 11294729Sjeff#define X_END 10 1131590Srgrimes#endif 1141590Srgrimes { "" }, 1151590Srgrimes}; 1161590Srgrimes 117123250Sdesstatic struct statinfo cur, last; 118123250Sdesstatic int num_devices, maxshowdevs; 119123250Sdesstatic long generation; 120123250Sdesstatic struct device_selection *dev_select; 121123250Sdesstatic int num_selected; 122123250Sdesstatic struct devstat_match *matches; 123123250Sdesstatic int num_matches = 0; 124123250Sdesstatic int num_devices_specified, num_selections; 125123250Sdesstatic long select_generation; 126123250Sdesstatic char **specified_devices; 127123250Sdesstatic devstat_select_mode select_mode; 1281590Srgrimes 129123250Sdesstatic struct vmmeter sum, osum; 1301590Srgrimes 131123250Sdesstatic int winlines = 20; 132123250Sdesstatic int aflag; 133123250Sdesstatic int nflag; 1341590Srgrimes 135123250Sdesstatic kvm_t *kd; 1361590Srgrimes 1371590Srgrimes#define FORKSTAT 0x01 1381590Srgrimes#define INTRSTAT 0x02 1391590Srgrimes#define MEMSTAT 0x04 1401590Srgrimes#define SUMSTAT 0x08 1411590Srgrimes#define TIMESTAT 0x10 1421590Srgrimes#define VMSTAT 0x20 14343962Sdillon#define ZMEMSTAT 0x40 1441590Srgrimes 14592922Simpstatic void cpustats(void); 14692922Simpstatic void devstats(void); 147122300Sjmgstatic void doforkst(void); 14892922Simpstatic void domem(void); 14992922Simpstatic void dointr(void); 15092922Simpstatic void dosum(void); 151123401Sdwmalonestatic void dosysctl(const char *); 152123407Sdesstatic void dovmstat(unsigned int, int); 15392922Simpstatic void dozmem(void); 15492922Simpstatic void kread(int, void *, size_t); 15592922Simpstatic void needhdr(int); 15692922Simpstatic void printhdr(void); 15792922Simpstatic void usage(void); 1581590Srgrimes 15992922Simpstatic long pct(long, long); 16092922Simpstatic long getuptime(void); 16187690Smarkm 162123250Sdesstatic char **getdrivedata(char **); 16387690Smarkm 16428693Scharnierint 165123250Sdesmain(int argc, char *argv[]) 1661590Srgrimes{ 16787690Smarkm int c, todo; 168123407Sdes unsigned int interval; 1691590Srgrimes int reps; 1701590Srgrimes char *memf, *nlistf; 17178474Sschweikh char errbuf[_POSIX2_LINE_MAX]; 1721590Srgrimes 1731590Srgrimes memf = nlistf = NULL; 1741590Srgrimes interval = reps = todo = 0; 17543822Sken maxshowdevs = 2; 176123250Sdes while ((c = getopt(argc, argv, "ac:fiM:mN:n:p:stw:z")) != -1) { 1771590Srgrimes switch (c) { 178123250Sdes case 'a': 179123250Sdes aflag++; 180123250Sdes break; 1811590Srgrimes case 'c': 1821590Srgrimes reps = atoi(optarg); 1831590Srgrimes break; 1841590Srgrimes case 'f': 185113460Stjr todo |= FORKSTAT; 1861590Srgrimes break; 1871590Srgrimes case 'i': 1881590Srgrimes todo |= INTRSTAT; 1891590Srgrimes break; 1901590Srgrimes case 'M': 1911590Srgrimes memf = optarg; 1921590Srgrimes break; 1931590Srgrimes case 'm': 1941590Srgrimes todo |= MEMSTAT; 1951590Srgrimes break; 1961590Srgrimes case 'N': 1971590Srgrimes nlistf = optarg; 1981590Srgrimes break; 19939230Sgibbs case 'n': 20039372Sdillon nflag = 1; 20139230Sgibbs maxshowdevs = atoi(optarg); 20239230Sgibbs if (maxshowdevs < 0) 20339230Sgibbs errx(1, "number of devices %d is < 0", 20439230Sgibbs maxshowdevs); 20539230Sgibbs break; 20639230Sgibbs case 'p': 207112284Sphk if (devstat_buildmatch(optarg, &matches, &num_matches) != 0) 20839230Sgibbs errx(1, "%s", devstat_errbuf); 20939230Sgibbs break; 2101590Srgrimes case 's': 2111590Srgrimes todo |= SUMSTAT; 2121590Srgrimes break; 2131590Srgrimes case 't': 21430180Sdima#ifdef notyet 2151590Srgrimes todo |= TIMESTAT; 21630180Sdima#else 21730180Sdima errx(EX_USAGE, "sorry, -t is not (re)implemented yet"); 21830180Sdima#endif 2191590Srgrimes break; 2201590Srgrimes case 'w': 2211590Srgrimes interval = atoi(optarg); 2221590Srgrimes break; 22344067Sbde case 'z': 22444067Sbde todo |= ZMEMSTAT; 22544067Sbde break; 2261590Srgrimes case '?': 2271590Srgrimes default: 2281590Srgrimes usage(); 2291590Srgrimes } 2301590Srgrimes } 2311590Srgrimes argc -= optind; 2321590Srgrimes argv += optind; 2331590Srgrimes 2341590Srgrimes if (todo == 0) 2351590Srgrimes todo = VMSTAT; 2361590Srgrimes 237123250Sdes if (memf != NULL) { 238123250Sdes kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); 239123250Sdes if (kd == NULL) 240123250Sdes errx(1, "kvm_openfiles: %s", errbuf); 241123250Sdes } 2421590Srgrimes 243123250Sdes if (kd != NULL && (c = kvm_nlist(kd, namelist)) != 0) { 2441590Srgrimes if (c > 0) { 24528693Scharnier warnx("undefined symbols:"); 2461590Srgrimes for (c = 0; 247123250Sdes c < (int)(sizeof(namelist)/sizeof(namelist[0])); 248123250Sdes c++) 2491590Srgrimes if (namelist[c].n_type == 0) 25081537Sken (void)fprintf(stderr, " %s", 2511590Srgrimes namelist[c].n_name); 2521590Srgrimes (void)fputc('\n', stderr); 2531590Srgrimes } else 25428693Scharnier warnx("kvm_nlist: %s", kvm_geterr(kd)); 2551590Srgrimes exit(1); 2561590Srgrimes } 2571590Srgrimes 2581590Srgrimes if (todo & VMSTAT) { 2591590Srgrimes struct winsize winsize; 2601590Srgrimes 26143819Sken /* 26243819Sken * Make sure that the userland devstat version matches the 26343819Sken * kernel devstat version. If not, exit and print a 26443819Sken * message informing the user of his mistake. 26543819Sken */ 266112284Sphk if (devstat_checkversion(NULL) < 0) 26743819Sken errx(1, "%s", devstat_errbuf); 26843819Sken 26943819Sken 2701590Srgrimes argv = getdrivedata(argv); 2711590Srgrimes winsize.ws_row = 0; 2721590Srgrimes (void) ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&winsize); 2731590Srgrimes if (winsize.ws_row > 0) 2741590Srgrimes winlines = winsize.ws_row; 2751590Srgrimes 2761590Srgrimes } 2771590Srgrimes 2781590Srgrimes#define BACKWARD_COMPATIBILITY 2791590Srgrimes#ifdef BACKWARD_COMPATIBILITY 2801590Srgrimes if (*argv) { 2811590Srgrimes interval = atoi(*argv); 2821590Srgrimes if (*++argv) 2831590Srgrimes reps = atoi(*argv); 2841590Srgrimes } 2851590Srgrimes#endif 2861590Srgrimes 2871590Srgrimes if (interval) { 2881590Srgrimes if (!reps) 2891590Srgrimes reps = -1; 2901590Srgrimes } else if (reps) 2911590Srgrimes interval = 1; 2921590Srgrimes 2931590Srgrimes if (todo & FORKSTAT) 2941590Srgrimes doforkst(); 2951590Srgrimes if (todo & MEMSTAT) 2961590Srgrimes domem(); 29743962Sdillon if (todo & ZMEMSTAT) 29843962Sdillon dozmem(); 2991590Srgrimes if (todo & SUMSTAT) 3001590Srgrimes dosum(); 30130180Sdima#ifdef notyet 3021590Srgrimes if (todo & TIMESTAT) 3031590Srgrimes dotimes(); 3041590Srgrimes#endif 3051590Srgrimes if (todo & INTRSTAT) 3061590Srgrimes dointr(); 3071590Srgrimes if (todo & VMSTAT) 3081590Srgrimes dovmstat(interval, reps); 3091590Srgrimes exit(0); 3101590Srgrimes} 3111590Srgrimes 312123250Sdesstatic int 313123250Sdesmysysctl(const char *name, void *oldp, size_t *oldlenp, 314123250Sdes void *newp, size_t newlen) 3151590Srgrimes{ 316123250Sdes int error; 317123250Sdes 318123250Sdes error = sysctlbyname(name, oldp, oldlenp, newp, newlen); 319123250Sdes if (error != 0 && errno != ENOMEM) 320123250Sdes err(1, "sysctl(%s)", name); 321123250Sdes return (error); 322123250Sdes} 323123250Sdes 324123250Sdesstatic char ** 325123250Sdesgetdrivedata(char **argv) 326123250Sdes{ 327112284Sphk if ((num_devices = devstat_getnumdevs(NULL)) < 0) 32839230Sgibbs errx(1, "%s", devstat_errbuf); 3291590Srgrimes 33039230Sgibbs cur.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); 33139230Sgibbs last.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); 33239230Sgibbs bzero(cur.dinfo, sizeof(struct devinfo)); 33339230Sgibbs bzero(last.dinfo, sizeof(struct devinfo)); 33439230Sgibbs 335112284Sphk if (devstat_getdevs(NULL, &cur) == -1) 33639230Sgibbs errx(1, "%s", devstat_errbuf); 33739230Sgibbs 33839230Sgibbs num_devices = cur.dinfo->numdevs; 33939230Sgibbs generation = cur.dinfo->generation; 34039230Sgibbs 34139230Sgibbs specified_devices = (char **)malloc(sizeof(char *)); 34239230Sgibbs for (num_devices_specified = 0; *argv; ++argv) { 3431590Srgrimes if (isdigit(**argv)) 3441590Srgrimes break; 34539230Sgibbs num_devices_specified++; 34639230Sgibbs specified_devices = (char **)realloc(specified_devices, 34739230Sgibbs sizeof(char *) * 34839230Sgibbs num_devices_specified); 34939230Sgibbs specified_devices[num_devices_specified - 1] = *argv; 3501590Srgrimes } 35139230Sgibbs dev_select = NULL; 35239230Sgibbs 35339372Sdillon if (nflag == 0 && maxshowdevs < num_devices_specified) 35439372Sdillon maxshowdevs = num_devices_specified; 35539372Sdillon 35639230Sgibbs /* 35739230Sgibbs * People are generally only interested in disk statistics when 35839230Sgibbs * they're running vmstat. So, that's what we're going to give 35939230Sgibbs * them if they don't specify anything by default. We'll also give 36039230Sgibbs * them any other random devices in the system so that we get to 36139230Sgibbs * maxshowdevs devices, if that many devices exist. If the user 36239230Sgibbs * specifies devices on the command line, either through a pattern 36339230Sgibbs * match or by naming them explicitly, we will give the user only 36439230Sgibbs * those devices. 36539230Sgibbs */ 36639230Sgibbs if ((num_devices_specified == 0) && (num_matches == 0)) { 367112284Sphk if (devstat_buildmatch(da, &matches, &num_matches) != 0) 36839230Sgibbs errx(1, "%s", devstat_errbuf); 36939230Sgibbs 37039230Sgibbs select_mode = DS_SELECT_ADD; 37139230Sgibbs } else 37239230Sgibbs select_mode = DS_SELECT_ONLY; 37339230Sgibbs 37439230Sgibbs /* 37539230Sgibbs * At this point, selectdevs will almost surely indicate that the 37639230Sgibbs * device list has changed, so we don't look for return values of 0 37739230Sgibbs * or 1. If we get back -1, though, there is an error. 37839230Sgibbs */ 379112284Sphk if (devstat_selectdevs(&dev_select, &num_selected, &num_selections, 38039230Sgibbs &select_generation, generation, cur.dinfo->devices, 38139230Sgibbs num_devices, matches, num_matches, specified_devices, 38239230Sgibbs num_devices_specified, select_mode, 38339230Sgibbs maxshowdevs, 0) == -1) 38439230Sgibbs errx(1, "%s", devstat_errbuf); 38539230Sgibbs 3861590Srgrimes return(argv); 3871590Srgrimes} 3881590Srgrimes 389123250Sdesstatic long 390123250Sdesgetuptime(void) 3911590Srgrimes{ 392101590Stmm static struct timeval boottime; 393101590Stmm static time_t now; 3941590Srgrimes time_t uptime; 3951590Srgrimes 396123250Sdes if (boottime.tv_sec == 0) { 397123250Sdes if (kd != NULL) { 398123250Sdes kread(X_BOOTTIME, &boottime, sizeof(boottime)); 399123250Sdes } else { 400123250Sdes size_t size; 401123250Sdes 402123250Sdes size = sizeof(boottime); 403123250Sdes mysysctl("kern.boottime", &boottime, &size, NULL, 0); 404123250Sdes if (size != sizeof(boottime)) 405123250Sdes errx(1, "kern.boottime size mismatch"); 406123250Sdes } 407123250Sdes } 4081590Srgrimes (void)time(&now); 409101590Stmm uptime = now - boottime.tv_sec; 41028693Scharnier if (uptime <= 0 || uptime > 60*60*24*365*10) 41128693Scharnier errx(1, "time makes no sense; namelist must be wrong"); 4121590Srgrimes return(uptime); 4131590Srgrimes} 4141590Srgrimes 415123250Sdesstatic void 416123250Sdesfill_vmmeter(struct vmmeter *vmmp) 417123250Sdes{ 418123250Sdes if (kd != NULL) { 419123250Sdes kread(X_SUM, vmmp, sizeof(*vmmp)); 420123250Sdes } else { 421123250Sdes size_t size = sizeof(unsigned int); 422123250Sdes#define GET_VM_STATS(cat, name) \ 423123250Sdes mysysctl("vm.stats." #cat "." #name, &vmmp->name, &size, NULL, 0) 424123250Sdes /* sys */ 425123250Sdes GET_VM_STATS(sys, v_swtch); 426123250Sdes GET_VM_STATS(sys, v_trap); 427123250Sdes GET_VM_STATS(sys, v_syscall); 428123250Sdes GET_VM_STATS(sys, v_intr); 429123250Sdes GET_VM_STATS(sys, v_soft); 4301590Srgrimes 431123250Sdes /* vm */ 432123250Sdes GET_VM_STATS(vm, v_vm_faults); 433123250Sdes GET_VM_STATS(vm, v_cow_faults); 434123250Sdes GET_VM_STATS(vm, v_cow_optim); 435123250Sdes GET_VM_STATS(vm, v_zfod); 436123250Sdes GET_VM_STATS(vm, v_ozfod); 437123250Sdes GET_VM_STATS(vm, v_swapin); 438123250Sdes GET_VM_STATS(vm, v_swapout); 439123250Sdes GET_VM_STATS(vm, v_swappgsin); 440123250Sdes GET_VM_STATS(vm, v_swappgsout); 441123250Sdes GET_VM_STATS(vm, v_vnodein); 442123250Sdes GET_VM_STATS(vm, v_vnodeout); 443123250Sdes GET_VM_STATS(vm, v_vnodepgsin); 444123250Sdes GET_VM_STATS(vm, v_vnodepgsout); 445123250Sdes GET_VM_STATS(vm, v_intrans); 446123250Sdes GET_VM_STATS(vm, v_reactivated); 447123250Sdes GET_VM_STATS(vm, v_pdwakeups); 448123250Sdes GET_VM_STATS(vm, v_pdpages); 449123250Sdes GET_VM_STATS(vm, v_dfree); 450123250Sdes GET_VM_STATS(vm, v_pfree); 451123250Sdes GET_VM_STATS(vm, v_tfree); 452123250Sdes GET_VM_STATS(vm, v_page_size); 453123250Sdes GET_VM_STATS(vm, v_page_count); 454123250Sdes GET_VM_STATS(vm, v_free_reserved); 455123250Sdes GET_VM_STATS(vm, v_free_target); 456123250Sdes GET_VM_STATS(vm, v_free_min); 457123250Sdes GET_VM_STATS(vm, v_free_count); 458123250Sdes GET_VM_STATS(vm, v_wire_count); 459123250Sdes GET_VM_STATS(vm, v_active_count); 460123250Sdes GET_VM_STATS(vm, v_inactive_target); 461123250Sdes GET_VM_STATS(vm, v_inactive_count); 462123250Sdes GET_VM_STATS(vm, v_cache_count); 463123250Sdes GET_VM_STATS(vm, v_cache_min); 464123250Sdes GET_VM_STATS(vm, v_cache_max); 465123250Sdes GET_VM_STATS(vm, v_pageout_free_min); 466123250Sdes GET_VM_STATS(vm, v_interrupt_free_min); 467123250Sdes /*GET_VM_STATS(vm, v_free_severe);*/ 468123250Sdes GET_VM_STATS(vm, v_forks); 469123250Sdes GET_VM_STATS(vm, v_vforks); 470123250Sdes GET_VM_STATS(vm, v_rforks); 471123250Sdes GET_VM_STATS(vm, v_kthreads); 472123250Sdes GET_VM_STATS(vm, v_forkpages); 473123250Sdes GET_VM_STATS(vm, v_vforkpages); 474123250Sdes GET_VM_STATS(vm, v_rforkpages); 475123250Sdes GET_VM_STATS(vm, v_kthreadpages); 476123250Sdes#undef GET_VM_STATS 477123250Sdes } 478123250Sdes} 479123250Sdes 480123250Sdesstatic void 481123250Sdesfill_vmtotal(struct vmtotal *vmtp) 4821590Srgrimes{ 483123250Sdes if (kd != NULL) { 484123250Sdes /* XXX fill vmtp */ 485123250Sdes errx(1, "not implemented"); 486123250Sdes } else { 487123250Sdes size_t size = sizeof(*vmtp); 488123250Sdes mysysctl("vm.vmtotal", vmtp, &size, NULL, 0); 489123250Sdes if (size != sizeof(*vmtp)) 490123250Sdes errx(1, "vm.total size mismatch"); 491123250Sdes } 492123250Sdes} 493123250Sdes 494123250Sdesstatic int hz, hdrcnt; 495123250Sdes 496123250Sdesstatic void 497123407Sdesdovmstat(unsigned int interval, int reps) 498123250Sdes{ 4991590Srgrimes struct vmtotal total; 5001590Srgrimes time_t uptime, halfuptime; 50139230Sgibbs struct devinfo *tmp_dinfo; 50280551Stmm size_t size; 5031590Srgrimes 5041590Srgrimes uptime = getuptime(); 5051590Srgrimes halfuptime = uptime / 2; 5061590Srgrimes (void)signal(SIGCONT, needhdr); 5071590Srgrimes 508123250Sdes if (kd != NULL) { 509123250Sdes if (namelist[X_STATHZ].n_type != 0 && 510123250Sdes namelist[X_STATHZ].n_value != 0) 511123250Sdes kread(X_STATHZ, &hz, sizeof(hz)); 512123250Sdes if (!hz) 513123250Sdes kread(X_HZ, &hz, sizeof(hz)); 514123250Sdes } else { 515123250Sdes struct clockinfo clockrate; 5161590Srgrimes 517123250Sdes size = sizeof(clockrate); 518123250Sdes mysysctl("kern.clockrate", &clockrate, &size, NULL, 0); 519123250Sdes if (size != sizeof(clockrate)) 520123250Sdes errx(1, "clockrate size mismatch"); 521123250Sdes hz = clockrate.hz; 522123250Sdes } 523123250Sdes 5241590Srgrimes for (hdrcnt = 1;;) { 5251590Srgrimes if (!--hdrcnt) 5261590Srgrimes printhdr(); 527123250Sdes if (kd != NULL) { 528123250Sdes kread(X_CPTIME, cur.cp_time, sizeof(cur.cp_time)); 529123250Sdes } else { 530123250Sdes size = sizeof(cur.cp_time); 531123250Sdes mysysctl("kern.cp_time", &cur.cp_time, &size, NULL, 0); 532123250Sdes if (size != sizeof(cur.cp_time)) 533123250Sdes errx(1, "cp_time size mismatch"); 534123250Sdes } 53539230Sgibbs 53639230Sgibbs tmp_dinfo = last.dinfo; 53739230Sgibbs last.dinfo = cur.dinfo; 53839230Sgibbs cur.dinfo = tmp_dinfo; 539112288Sphk last.snap_time = cur.snap_time; 54039230Sgibbs 54139230Sgibbs /* 54239230Sgibbs * Here what we want to do is refresh our device stats. 54339230Sgibbs * getdevs() returns 1 when the device list has changed. 54439230Sgibbs * If the device list has changed, we want to go through 54539230Sgibbs * the selection process again, in case a device that we 54639230Sgibbs * were previously displaying has gone away. 54739230Sgibbs */ 548112284Sphk switch (devstat_getdevs(NULL, &cur)) { 54939230Sgibbs case -1: 55039230Sgibbs errx(1, "%s", devstat_errbuf); 55139230Sgibbs break; 55239230Sgibbs case 1: { 55339230Sgibbs int retval; 55439230Sgibbs 55539230Sgibbs num_devices = cur.dinfo->numdevs; 55639230Sgibbs generation = cur.dinfo->generation; 55739230Sgibbs 558112284Sphk retval = devstat_selectdevs(&dev_select, &num_selected, 55939230Sgibbs &num_selections, &select_generation, 56039230Sgibbs generation, cur.dinfo->devices, 56139230Sgibbs num_devices, matches, num_matches, 56239230Sgibbs specified_devices, 56339230Sgibbs num_devices_specified, select_mode, 56439230Sgibbs maxshowdevs, 0); 56539230Sgibbs switch (retval) { 56639230Sgibbs case -1: 56739230Sgibbs errx(1, "%s", devstat_errbuf); 56839230Sgibbs break; 56939230Sgibbs case 1: 57039230Sgibbs printhdr(); 57139230Sgibbs break; 57239230Sgibbs default: 57339230Sgibbs break; 57439230Sgibbs } 57539230Sgibbs } 57639230Sgibbs default: 57739230Sgibbs break; 57839230Sgibbs } 57939230Sgibbs 580123250Sdes fill_vmmeter(&sum); 581123250Sdes fill_vmtotal(&total); 58278672Sschweikh (void)printf("%2d %1d %1d", 5831590Srgrimes total.t_rq - 1, total.t_dw + total.t_pw, total.t_sw); 58472887Salfred#define vmstat_pgtok(a) ((a) * sum.v_page_size >> 10) 5851590Srgrimes#define rate(x) (((x) + halfuptime) / uptime) /* round */ 58681537Sken (void)printf(" %7ld %6ld ", (long)vmstat_pgtok(total.t_avm), 58781537Sken (long)vmstat_pgtok(total.t_free)); 58837453Sbde (void)printf("%4lu ", 589123407Sdes (unsigned long)rate(sum.v_vm_faults - osum.v_vm_faults)); 5901590Srgrimes (void)printf("%3lu ", 591123407Sdes (unsigned long)rate(sum.v_reactivated - osum.v_reactivated)); 59237453Sbde (void)printf("%3lu ", 593123407Sdes (unsigned long)rate(sum.v_swapin + sum.v_vnodein - 5943659Sdg (osum.v_swapin + osum.v_vnodein))); 59537453Sbde (void)printf("%3lu ", 596123407Sdes (unsigned long)rate(sum.v_swapout + sum.v_vnodeout - 5973693Sdg (osum.v_swapout + osum.v_vnodeout))); 59837453Sbde (void)printf("%3lu ", 599123407Sdes (unsigned long)rate(sum.v_tfree - osum.v_tfree)); 60037453Sbde (void)printf("%3lu ", 601123407Sdes (unsigned long)rate(sum.v_pdpages - osum.v_pdpages)); 60239230Sgibbs devstats(); 6031590Srgrimes (void)printf("%4lu %4lu %3lu ", 604123407Sdes (unsigned long)rate(sum.v_intr - osum.v_intr), 605123407Sdes (unsigned long)rate(sum.v_syscall - osum.v_syscall), 606123407Sdes (unsigned long)rate(sum.v_swtch - osum.v_swtch)); 6071590Srgrimes cpustats(); 6081590Srgrimes (void)printf("\n"); 6091590Srgrimes (void)fflush(stdout); 6101590Srgrimes if (reps >= 0 && --reps <= 0) 6111590Srgrimes break; 6121590Srgrimes osum = sum; 6131590Srgrimes uptime = interval; 6141590Srgrimes /* 6151590Srgrimes * We round upward to avoid losing low-frequency events 6161590Srgrimes * (i.e., >= 1 per interval but < 1 per second). 6171590Srgrimes */ 6183659Sdg if (interval != 1) 6193659Sdg halfuptime = (uptime + 1) / 2; 6203659Sdg else 6213659Sdg halfuptime = 0; 6221590Srgrimes (void)sleep(interval); 6231590Srgrimes } 6241590Srgrimes} 6251590Srgrimes 626123250Sdesstatic void 627123250Sdesprinthdr(void) 6281590Srgrimes{ 62943822Sken int i, num_shown; 6301590Srgrimes 63143822Sken num_shown = (num_selected < maxshowdevs) ? num_selected : maxshowdevs; 63278672Sschweikh (void)printf(" procs memory page%*s", 19, ""); 63343822Sken if (num_shown > 1) 63443822Sken (void)printf(" disks %*s", num_shown * 4 - 7, ""); 63543822Sken else if (num_shown == 1) 63643822Sken (void)printf("disk"); 63743822Sken (void)printf(" faults cpu\n"); 63878672Sschweikh (void)printf(" r b w avm fre flt re pi po fr sr "); 63939230Sgibbs for (i = 0; i < num_devices; i++) 64039230Sgibbs if ((dev_select[i].selected) 64139230Sgibbs && (dev_select[i].selected <= maxshowdevs)) 64239230Sgibbs (void)printf("%c%c%d ", dev_select[i].device_name[0], 64339230Sgibbs dev_select[i].device_name[1], 64439230Sgibbs dev_select[i].unit_number); 6451590Srgrimes (void)printf(" in sy cs us sy id\n"); 6461590Srgrimes hdrcnt = winlines - 2; 6471590Srgrimes} 6481590Srgrimes 6491590Srgrimes/* 6501590Srgrimes * Force a header to be prepended to the next output. 6511590Srgrimes */ 652123250Sdesstatic void 653123250Sdesneedhdr(int dummy __unused) 6541590Srgrimes{ 6551590Srgrimes 6561590Srgrimes hdrcnt = 1; 6571590Srgrimes} 6581590Srgrimes 65930180Sdima#ifdef notyet 660123250Sdesstatic void 661123250Sdesdotimes(void) 6621590Srgrimes{ 663123407Sdes unsigned int pgintime, rectime; 6641590Srgrimes 6651590Srgrimes kread(X_REC, &rectime, sizeof(rectime)); 6661590Srgrimes kread(X_PGIN, &pgintime, sizeof(pgintime)); 6671590Srgrimes kread(X_SUM, &sum, sizeof(sum)); 6681590Srgrimes (void)printf("%u reclaims, %u total time (usec)\n", 6691590Srgrimes sum.v_pgrec, rectime); 6701590Srgrimes (void)printf("average: %u usec / reclaim\n", rectime / sum.v_pgrec); 6711590Srgrimes (void)printf("\n"); 6721590Srgrimes (void)printf("%u page ins, %u total time (msec)\n", 6731590Srgrimes sum.v_pgin, pgintime / 10); 6741590Srgrimes (void)printf("average: %8.1f msec / page in\n", 6751590Srgrimes pgintime / (sum.v_pgin * 10.0)); 6761590Srgrimes} 6771590Srgrimes#endif 6781590Srgrimes 679123250Sdesstatic long 680123250Sdespct(long top, long bot) 6811590Srgrimes{ 6821590Srgrimes long ans; 6831590Srgrimes 6841590Srgrimes if (bot == 0) 6851590Srgrimes return(0); 6861590Srgrimes ans = (quad_t)top * 100 / bot; 6871590Srgrimes return (ans); 6881590Srgrimes} 6891590Srgrimes 6901590Srgrimes#define PCT(top, bot) pct((long)(top), (long)(bot)) 6911590Srgrimes 692123250Sdesstatic void 693123250Sdesdosum(void) 6941590Srgrimes{ 69587690Smarkm struct nchstats lnchstats; 6961590Srgrimes long nchtotal; 6971590Srgrimes 698123250Sdes fill_vmmeter(&sum); 6991590Srgrimes (void)printf("%9u cpu context switches\n", sum.v_swtch); 7001590Srgrimes (void)printf("%9u device interrupts\n", sum.v_intr); 7011590Srgrimes (void)printf("%9u software interrupts\n", sum.v_soft); 7021590Srgrimes (void)printf("%9u traps\n", sum.v_trap); 7031590Srgrimes (void)printf("%9u system calls\n", sum.v_syscall); 70471429Sume (void)printf("%9u kernel threads created\n", sum.v_kthreads); 70571429Sume (void)printf("%9u fork() calls\n", sum.v_forks); 70671429Sume (void)printf("%9u vfork() calls\n", sum.v_vforks); 70771429Sume (void)printf("%9u rfork() calls\n", sum.v_rforks); 7083659Sdg (void)printf("%9u swap pager pageins\n", sum.v_swapin); 7093693Sdg (void)printf("%9u swap pager pages paged in\n", sum.v_swappgsin); 7103659Sdg (void)printf("%9u swap pager pageouts\n", sum.v_swapout); 7113659Sdg (void)printf("%9u swap pager pages paged out\n", sum.v_swappgsout); 7123659Sdg (void)printf("%9u vnode pager pageins\n", sum.v_vnodein); 7133693Sdg (void)printf("%9u vnode pager pages paged in\n", sum.v_vnodepgsin); 7143659Sdg (void)printf("%9u vnode pager pageouts\n", sum.v_vnodeout); 7153659Sdg (void)printf("%9u vnode pager pages paged out\n", sum.v_vnodepgsout); 7163693Sdg (void)printf("%9u page daemon wakeups\n", sum.v_pdwakeups); 7173693Sdg (void)printf("%9u pages examined by the page daemon\n", sum.v_pdpages); 7181590Srgrimes (void)printf("%9u pages reactivated\n", sum.v_reactivated); 7197351Sdg (void)printf("%9u copy-on-write faults\n", sum.v_cow_faults); 72034214Sdyson (void)printf("%9u copy-on-write optimized faults\n", sum.v_cow_optim); 7217351Sdg (void)printf("%9u zero fill pages zeroed\n", sum.v_zfod); 72234214Sdyson (void)printf("%9u zero fill pages prezeroed\n", sum.v_ozfod); 7231590Srgrimes (void)printf("%9u intransit blocking page faults\n", sum.v_intrans); 7241590Srgrimes (void)printf("%9u total VM faults taken\n", sum.v_vm_faults); 72571429Sume (void)printf("%9u pages affected by kernel thread creation\n", sum.v_kthreadpages); 72671429Sume (void)printf("%9u pages affected by fork()\n", sum.v_forkpages); 72771429Sume (void)printf("%9u pages affected by vfork()\n", sum.v_vforkpages); 72871429Sume (void)printf("%9u pages affected by rfork()\n", sum.v_rforkpages); 7293693Sdg (void)printf("%9u pages freed\n", sum.v_tfree); 7301590Srgrimes (void)printf("%9u pages freed by daemon\n", sum.v_dfree); 7311590Srgrimes (void)printf("%9u pages freed by exiting processes\n", sum.v_pfree); 7321590Srgrimes (void)printf("%9u pages active\n", sum.v_active_count); 7331590Srgrimes (void)printf("%9u pages inactive\n", sum.v_inactive_count); 7345463Sdg (void)printf("%9u pages in VM cache\n", sum.v_cache_count); 7353693Sdg (void)printf("%9u pages wired down\n", sum.v_wire_count); 7363693Sdg (void)printf("%9u pages free\n", sum.v_free_count); 7371590Srgrimes (void)printf("%9u bytes per page\n", sum.v_page_size); 738123250Sdes if (kd != NULL) { 739123250Sdes kread(X_NCHSTATS, &lnchstats, sizeof(lnchstats)); 740123250Sdes } else { 741123250Sdes size_t size = sizeof(lnchstats); 742123250Sdes mysysctl("vfs.cache.nchstats", &lnchstats, &size, NULL, 0); 743123250Sdes if (size != sizeof(lnchstats)) 744123250Sdes errx(1, "vfs.cache.nchstats size mismatch"); 745123250Sdes } 74687690Smarkm nchtotal = lnchstats.ncs_goodhits + lnchstats.ncs_neghits + 74787690Smarkm lnchstats.ncs_badhits + lnchstats.ncs_falsehits + 74887690Smarkm lnchstats.ncs_miss + lnchstats.ncs_long; 7491590Srgrimes (void)printf("%9ld total name lookups\n", nchtotal); 7501590Srgrimes (void)printf( 75128693Scharnier "%9s cache hits (%ld%% pos + %ld%% neg) system %ld%% per-directory\n", 75287690Smarkm "", PCT(lnchstats.ncs_goodhits, nchtotal), 75387690Smarkm PCT(lnchstats.ncs_neghits, nchtotal), 75487690Smarkm PCT(lnchstats.ncs_pass2, nchtotal)); 75528693Scharnier (void)printf("%9s deletions %ld%%, falsehits %ld%%, toolong %ld%%\n", "", 75687690Smarkm PCT(lnchstats.ncs_badhits, nchtotal), 75787690Smarkm PCT(lnchstats.ncs_falsehits, nchtotal), 75887690Smarkm PCT(lnchstats.ncs_long, nchtotal)); 7591590Srgrimes} 7601590Srgrimes 761123250Sdesstatic void 762123250Sdesdoforkst(void) 7631590Srgrimes{ 764123250Sdes fill_vmmeter(&sum); 7651590Srgrimes (void)printf("%d forks, %d pages, average %.2f\n", 766113460Stjr sum.v_forks, sum.v_forkpages, 767113460Stjr sum.v_forks == 0 ? 0.0 : 768113460Stjr (double)sum.v_forkpages / sum.v_forks); 7691590Srgrimes (void)printf("%d vforks, %d pages, average %.2f\n", 770113460Stjr sum.v_vforks, sum.v_vforkpages, 771113460Stjr sum.v_vforks == 0 ? 0.0 : 772113460Stjr (double)sum.v_vforkpages / sum.v_vforks); 773113460Stjr (void)printf("%d rforks, %d pages, average %.2f\n", 774113460Stjr sum.v_rforks, sum.v_rforkpages, 775113460Stjr sum.v_rforks == 0 ? 0.0 : 776113460Stjr (double)sum.v_rforkpages / sum.v_rforks); 7771590Srgrimes} 7781590Srgrimes 77939230Sgibbsstatic void 780123250Sdesdevstats(void) 7811590Srgrimes{ 78287690Smarkm int dn, state; 78339230Sgibbs long double transfers_per_second; 78439230Sgibbs long double busy_seconds; 7851590Srgrimes long tmp; 786123250Sdes 7871590Srgrimes for (state = 0; state < CPUSTATES; ++state) { 78839230Sgibbs tmp = cur.cp_time[state]; 78939230Sgibbs cur.cp_time[state] -= last.cp_time[state]; 79039230Sgibbs last.cp_time[state] = tmp; 7911590Srgrimes } 79239230Sgibbs 793112288Sphk busy_seconds = cur.snap_time - last.snap_time; 79439230Sgibbs 79539230Sgibbs for (dn = 0; dn < num_devices; dn++) { 79639230Sgibbs int di; 79739230Sgibbs 79839230Sgibbs if ((dev_select[dn].selected == 0) 79939230Sgibbs || (dev_select[dn].selected > maxshowdevs)) 8001590Srgrimes continue; 80139230Sgibbs 80239230Sgibbs di = dev_select[dn].position; 80339230Sgibbs 80481537Sken if (devstat_compute_statistics(&cur.dinfo->devices[di], 80581537Sken &last.dinfo->devices[di], busy_seconds, 80681537Sken DSM_TRANSFERS_PER_SECOND, &transfers_per_second, 80781537Sken DSM_NONE) != 0) 80839230Sgibbs errx(1, "%s", devstat_errbuf); 80939230Sgibbs 81081537Sken (void)printf("%3.0Lf ", transfers_per_second); 8111590Srgrimes } 8121590Srgrimes} 8131590Srgrimes 814123250Sdesstatic void 815123250Sdescpustats(void) 8161590Srgrimes{ 81787690Smarkm int state; 81887690Smarkm double lpct, total; 8191590Srgrimes 8201590Srgrimes total = 0; 8211590Srgrimes for (state = 0; state < CPUSTATES; ++state) 82239230Sgibbs total += cur.cp_time[state]; 8231590Srgrimes if (total) 82487690Smarkm lpct = 100.0 / total; 8251590Srgrimes else 82687690Smarkm lpct = 0.0; 82739230Sgibbs (void)printf("%2.0f ", (cur.cp_time[CP_USER] + 82887690Smarkm cur.cp_time[CP_NICE]) * lpct); 82939230Sgibbs (void)printf("%2.0f ", (cur.cp_time[CP_SYS] + 83087690Smarkm cur.cp_time[CP_INTR]) * lpct); 83187690Smarkm (void)printf("%2.0f", cur.cp_time[CP_IDLE] * lpct); 8321590Srgrimes} 8331590Srgrimes 834123250Sdesstatic void 835123250Sdesdointr(void) 8361590Srgrimes{ 837123407Sdes unsigned long *intrcnt, uptime; 838123409Sdes uint64_t inttotal; 839123409Sdes size_t clen, inamlen, intrcntlen, istrnamlen; 840123409Sdes unsigned int i, nintr; 841121626Sjmg char *intrname, *tintrname; 8421590Srgrimes 8431590Srgrimes uptime = getuptime(); 844123250Sdes if (kd != NULL) { 845123409Sdes intrcntlen = namelist[X_EINTRCNT].n_value - 846123250Sdes namelist[X_INTRCNT].n_value; 847123250Sdes inamlen = namelist[X_EINTRNAMES].n_value - 848123250Sdes namelist[X_INTRNAMES].n_value; 849123409Sdes if ((intrcnt = malloc(intrcntlen)) == NULL || 850123290Smarcel (intrname = malloc(inamlen)) == NULL) 851123250Sdes err(1, "malloc()"); 852123409Sdes kread(X_INTRCNT, intrcnt, intrcntlen); 853123290Smarcel kread(X_INTRNAMES, intrname, inamlen); 854123250Sdes } else { 855123409Sdes mysysctl("hw.intrcnt", NULL, &intrcntlen, NULL, 0); 856123409Sdes fprintf(stderr, "intrcntlen = %lu\n", (unsigned long)intrcntlen); 857123409Sdes if ((intrcnt = malloc(intrcntlen)) == NULL) 858123409Sdes err(1, "calloc()"); 859123409Sdes mysysctl("hw.intrcnt", intrcnt, &intrcntlen, NULL, 0); 860123250Sdes for (intrname = NULL, inamlen = 1024; ; inamlen *= 2) { 861123250Sdes if ((intrname = reallocf(intrname, inamlen)) == NULL) 862123250Sdes err(1, "reallocf()"); 863123250Sdes if (mysysctl("hw.intrnames", 864123250Sdes intrname, &inamlen, NULL, 0) == 0) 865123250Sdes break; 866123250Sdes } 867123250Sdes } 868123409Sdes nintr = intrcntlen / sizeof(unsigned long); 869121626Sjmg tintrname = intrname; 870122365Sjmg istrnamlen = strlen("interrupt"); 871121626Sjmg for (i = 0; i < nintr; i++) { 872121626Sjmg clen = strlen(tintrname); 873121626Sjmg if (clen > istrnamlen) 874121626Sjmg istrnamlen = clen; 875121626Sjmg tintrname += clen + 1; 876121626Sjmg } 877121626Sjmg (void)printf("%-*s %20s %10s\n", istrnamlen, "interrupt", "total", 878121626Sjmg "rate"); 8791590Srgrimes inttotal = 0; 880123290Smarcel for (i = 0; i < nintr; i++) { 881123250Sdes const char *p; 882123409Sdes if (intrname[0] != '\0' && (*intrcnt != 0 || aflag)) 883121626Sjmg (void)printf("%-*s %20lu %10lu\n", istrnamlen, intrname, 8841590Srgrimes *intrcnt, *intrcnt / uptime); 8851590Srgrimes intrname += strlen(intrname) + 1; 8861590Srgrimes inttotal += *intrcnt++; 8871590Srgrimes } 888123290Smarcel (void)printf("%-*s %20llu %10llu\n", istrnamlen, "Total", 889123290Smarcel (long long)inttotal, (long long)(inttotal / uptime)); 8901590Srgrimes} 8911590Srgrimes 892123250Sdesstatic void 89394729Sjeffdomem(void) 89494729Sjeff{ 895123250Sdes if (kd != NULL) 896123250Sdes errx(1, "not implemented"); 89794729Sjeff dosysctl("kern.malloc"); 89894729Sjeff} 89946852Simp 900123250Sdesstatic void 90194729Sjeffdozmem(void) 9021590Srgrimes{ 903123250Sdes if (kd != NULL) 904123250Sdes errx(1, "not implemented"); 90594729Sjeff dosysctl("vm.zone"); 9061590Srgrimes} 9071590Srgrimes 908123250Sdesstatic void 909123401Sdwmalonedosysctl(const char *name) 91043962Sdillon{ 91171404Sdes char *buf; 91271404Sdes size_t bufsize; 91343962Sdillon 914123250Sdes for (buf = NULL, bufsize = 1024; ; bufsize *= 2) { 91571404Sdes if ((buf = realloc(buf, bufsize)) == NULL) 91671404Sdes err(1, "realloc()"); 917123250Sdes if (mysysctl(name, buf, &bufsize, 0, NULL) == 0) 91843962Sdillon break; 91971404Sdes bufsize *= 2; 92043962Sdillon } 92171404Sdes buf[bufsize] = '\0'; /* play it safe */ 92271404Sdes (void)printf("%s\n\n", buf); 92371404Sdes free(buf); 92443962Sdillon} 92543962Sdillon 9261590Srgrimes/* 9271590Srgrimes * kread reads something from the kernel, given its nlist index. 9281590Srgrimes */ 929123250Sdesstatic void 930123250Sdeskread(int nlx, void *addr, size_t size) 9311590Srgrimes{ 9321590Srgrimes char *sym; 9331590Srgrimes 93440690Sjdp if (namelist[nlx].n_type == 0 || namelist[nlx].n_value == 0) { 9351590Srgrimes sym = namelist[nlx].n_name; 9361590Srgrimes if (*sym == '_') 9371590Srgrimes ++sym; 93828693Scharnier errx(1, "symbol %s not defined", sym); 9391590Srgrimes } 940122300Sjmg if ((size_t)kvm_read(kd, namelist[nlx].n_value, addr, size) != size) { 9411590Srgrimes sym = namelist[nlx].n_name; 9421590Srgrimes if (*sym == '_') 9431590Srgrimes ++sym; 94428693Scharnier errx(1, "%s: %s", sym, kvm_geterr(kd)); 9451590Srgrimes } 9461590Srgrimes} 9471590Srgrimes 948123250Sdesstatic void 949123250Sdesusage(void) 9501590Srgrimes{ 95172887Salfred (void)fprintf(stderr, "%s%s", 952123250Sdes "usage: vmstat [-aimsz] [-c count] [-M core] [-N system] [-w wait]\n", 95372887Salfred " [-n devs] [disks]\n"); 9541590Srgrimes exit(1); 9551590Srgrimes} 956