[BACK]Return to vmstat.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / vmstat

Annotation of src/usr.bin/vmstat/vmstat.c, Revision 1.216.6.2

1.216.6.2! snj         1: /* $NetBSD: vmstat.c,v 1.216.6.1 2017/07/25 01:43:37 snj Exp $ */
1.45      thorpej     2:
                      3: /*-
1.154     ad          4:  * Copyright (c) 1998, 2000, 2001, 2007 The NetBSD Foundation, Inc.
1.45      thorpej     5:  * All rights reserved.
                      6:  *
1.87      lukem       7:  * This code is derived from software contributed to The NetBSD Foundation by:
                      8:  *     - Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                      9:  *       NASA Ames Research Center.
                     10:  *     - Simon Burge and Luke Mewburn of Wasabi Systems, Inc.
1.45      thorpej    11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     22:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     23:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     24:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     25:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     26:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     27:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     28:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     29:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     30:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     31:  * POSSIBILITY OF SUCH DAMAGE.
                     32:  */
1.21      cgd        33:
1.1       cgd        34: /*
1.13      cgd        35:  * Copyright (c) 1980, 1986, 1991, 1993
                     36:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd        37:  *
                     38:  * Redistribution and use in source and binary forms, with or without
                     39:  * modification, are permitted provided that the following conditions
                     40:  * are met:
                     41:  * 1. Redistributions of source code must retain the above copyright
                     42:  *    notice, this list of conditions and the following disclaimer.
                     43:  * 2. Redistributions in binary form must reproduce the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer in the
                     45:  *    documentation and/or other materials provided with the distribution.
1.117     agc        46:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        47:  *    may be used to endorse or promote products derived from this software
                     48:  *    without specific prior written permission.
                     49:  *
                     50:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     51:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     52:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     53:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     54:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     55:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     56:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     57:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     58:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     59:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     60:  * SUCH DAMAGE.
                     61:  */
                     62:
1.38      mrg        63: #include <sys/cdefs.h>
1.1       cgd        64: #ifndef lint
1.161     lukem      65: __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\
                     66:  The Regents of the University of California.  All rights reserved.");
1.1       cgd        67: #endif /* not lint */
                     68:
                     69: #ifndef lint
1.21      cgd        70: #if 0
1.37      mrg        71: static char sccsid[] = "@(#)vmstat.c   8.2 (Berkeley) 3/1/95";
1.21      cgd        72: #else
1.216.6.2! snj        73: __RCSID("$NetBSD: vmstat.c,v 1.216.6.1 2017/07/25 01:43:37 snj Exp $");
1.21      cgd        74: #endif
1.1       cgd        75: #endif /* not lint */
1.57      thorpej    76:
                     77: #define        __POOL_EXPOSE
1.1       cgd        78:
                     79: #include <sys/param.h>
1.174     christos   80: #include <sys/types.h>
1.87      lukem      81: #include <sys/mount.h>
                     82: #include <sys/uio.h>
                     83:
                     84: #include <sys/buf.h>
1.146     yamt       85: #include <sys/evcnt.h>
1.87      lukem      86: #include <sys/ioctl.h>
                     87: #include <sys/malloc.h>
1.109     thorpej    88: #include <sys/mallocvar.h>
1.1       cgd        89: #include <sys/namei.h>
1.87      lukem      90: #include <sys/pool.h>
                     91: #include <sys/proc.h>
1.64      perry      92: #include <sys/sched.h>
1.87      lukem      93: #include <sys/socket.h>
1.13      cgd        94: #include <sys/sysctl.h>
1.87      lukem      95: #include <sys/time.h>
1.171     christos   96: #include <sys/queue.h>
1.181     mrg        97: #include <sys/kernhist.h>
1.67      mrg        98:
                     99: #include <uvm/uvm_extern.h>
                    100: #include <uvm/uvm_stat.h>
                    101:
1.87      lukem     102: #include <net/if.h>
                    103: #include <netinet/in.h>
                    104: #include <netinet/in_var.h>
                    105:
                    106: #include <ufs/ufs/inode.h>
                    107:
                    108: #include <nfs/rpcv2.h>
                    109: #include <nfs/nfsproto.h>
                    110: #include <nfs/nfsnode.h>
                    111:
                    112: #include <ctype.h>
1.45      thorpej   113: #include <err.h>
1.87      lukem     114: #include <errno.h>
1.55      kleink    115: #include <fcntl.h>
1.87      lukem     116: #include <kvm.h>
                    117: #include <limits.h>
1.1       cgd       118: #include <nlist.h>
1.87      lukem     119: #undef n_hash
                    120: #include <paths.h>
1.22      jtc       121: #include <signal.h>
1.1       cgd       122: #include <stdio.h>
1.87      lukem     123: #include <stddef.h>
1.1       cgd       124: #include <stdlib.h>
                    125: #include <string.h>
1.87      lukem     126: #include <time.h>
                    127: #include <unistd.h>
1.104     mrg       128: #include <util.h>
1.87      lukem     129:
1.140     blymn     130: #include "drvstats.h"
1.45      thorpej   131:
1.90      lukem     132: /*
1.174     christos  133:  * All this mess will go away once everything is converted.
                    134:  */
                    135: #ifdef __HAVE_CPU_DATA_FIRST
1.175     christos  136:
                    137: # include <sys/cpu_data.h>
                    138: struct cpu_info {
1.174     christos  139:        struct cpu_data ci_data;
                    140: };
                    141: #else
1.190     rmind     142: # include <sys/cpu.h>
                    143: #endif
1.175     christos  144:
1.174     christos  145: /*
1.90      lukem     146:  * General namelist
                    147:  */
1.87      lukem     148: struct nlist namelist[] =
                    149: {
1.65      itojun    150: #define        X_BOOTTIME      0
1.153     christos  151:        { .n_name = "_boottime" },
1.75      enami     152: #define        X_HZ            1
1.153     christos  153:        { .n_name = "_hz" },
1.75      enami     154: #define        X_STATHZ        2
1.153     christos  155:        { .n_name = "_stathz" },
1.75      enami     156: #define        X_NCHSTATS      3
1.153     christos  157:        { .n_name = "_nchstats" },
1.188     para      158: #define        X_ALLEVENTS     4
1.153     christos  159:        { .n_name = "_allevents" },
1.188     para      160: #define        X_POOLHEAD      5
1.153     christos  161:        { .n_name = "_pool_head" },
1.188     para      162: #define        X_UVMEXP        6
1.153     christos  163:        { .n_name = "_uvmexp" },
1.188     para      164: #define        X_TIME_SECOND   7
1.153     christos  165:        { .n_name = "_time_second" },
1.188     para      166: #define X_TIME         8
1.153     christos  167:        { .n_name = "_time" },
1.190     rmind     168: #define X_CPU_INFOS    9
                    169:        { .n_name = "_cpu_infos" },
1.188     para      170: #define        X_NL_SIZE       10
1.153     christos  171:        { .n_name = NULL },
1.90      lukem     172: };
                    173:
                    174: /*
1.133     chs       175:  * Namelist for pre-evcnt interrupt counters.
                    176:  */
                    177: struct nlist intrnl[] =
                    178: {
                    179: #define        X_INTRNAMES     0
1.153     christos  180:        { .n_name = "_intrnames" },
1.133     chs       181: #define        X_EINTRNAMES    1
1.153     christos  182:        { .n_name = "_eintrnames" },
1.133     chs       183: #define        X_INTRCNT       2
1.153     christos  184:        { .n_name = "_intrcnt" },
1.133     chs       185: #define        X_EINTRCNT      3
1.153     christos  186:        { .n_name = "_eintrcnt" },
1.133     chs       187: #define        X_INTRNL_SIZE   4
1.153     christos  188:        { .n_name = NULL },
1.133     chs       189: };
                    190:
                    191:
                    192: /*
1.90      lukem     193:  * Namelist for hash statistics
                    194:  */
                    195: struct nlist hashnl[] =
                    196: {
                    197: #define        X_NFSNODE       0
1.153     christos  198:        { .n_name = "_nfsnodehash" },
1.90      lukem     199: #define        X_NFSNODETBL    1
1.153     christos  200:        { .n_name = "_nfsnodehashtbl" },
1.90      lukem     201: #define        X_IHASH         2
1.153     christos  202:        { .n_name = "_ihash" },
1.90      lukem     203: #define        X_IHASHTBL      3
1.153     christos  204:        { .n_name = "_ihashtbl" },
1.90      lukem     205: #define        X_BUFHASH       4
1.153     christos  206:        { .n_name = "_bufhash" },
1.90      lukem     207: #define        X_BUFHASHTBL    5
1.153     christos  208:        { .n_name = "_bufhashtbl" },
1.122     junyoung  209: #define        X_UIHASH        6
1.153     christos  210:        { .n_name = "_uihash" },
1.122     junyoung  211: #define        X_UIHASHTBL     7
1.153     christos  212:        { .n_name = "_uihashtbl" },
1.122     junyoung  213: #define        X_IFADDRHASH    8
1.153     christos  214:        { .n_name = "_in_ifaddrhash" },
1.122     junyoung  215: #define        X_IFADDRHASHTBL 9
1.153     christos  216:        { .n_name = "_in_ifaddrhashtbl" },
1.122     junyoung  217: #define        X_NCHASH        10
1.153     christos  218:        { .n_name = "_nchash" },
1.122     junyoung  219: #define        X_NCHASHTBL     11
1.153     christos  220:        { .n_name = "_nchashtbl" },
1.122     junyoung  221: #define        X_NCVHASH       12
1.153     christos  222:        { .n_name = "_ncvhash" },
1.122     junyoung  223: #define        X_NCVHASHTBL    13
1.153     christos  224:        { .n_name = "_ncvhashtbl" },
1.122     junyoung  225: #define X_HASHNL_SIZE  14      /* must be last */
1.153     christos  226:        { .n_name = NULL },
1.90      lukem     227: };
1.87      lukem     228:
1.90      lukem     229: /*
1.181     mrg       230:  * Namelist for kernel histories
1.90      lukem     231:  */
                    232: struct nlist histnl[] =
                    233: {
1.181     mrg       234:        { .n_name = "_kern_histories" },
                    235: #define        X_KERN_HISTORIES                0
1.153     christos  236:        { .n_name = NULL },
1.1       cgd       237: };
                    238:
1.87      lukem     239:
1.205     skrll     240: #define KILO   1024
1.90      lukem     241:
1.171     christos  242: struct cpu_counter {
                    243:        uint64_t nintr;
                    244:        uint64_t nsyscall;
                    245:        uint64_t nswtch;
                    246:        uint64_t nfault;
                    247:        uint64_t ntrap;
                    248:        uint64_t nsoft;
                    249: } cpucounter, ocpucounter;
                    250:
1.196     joerg     251: struct uvmexp_sysctl uvmexp, ouvmexp;
1.73      simonb    252: int    ndrives;
1.1       cgd       253:
                    254: int    winlines = 20;
                    255:
1.13      cgd       256: kvm_t *kd;
                    257:
1.174     christos  258:
1.185     christos  259: #define        FORKSTAT        0x001
                    260: #define        INTRSTAT        0x002
                    261: #define        MEMSTAT         0x004
                    262: #define        SUMSTAT         0x008
                    263: #define        EVCNTSTAT       0x010
                    264: #define        VMSTAT          0x020
                    265: #define        HISTLIST        0x040
                    266: #define        HISTDUMP        0x080
                    267: #define        HASHSTAT        0x100
                    268: #define        HASHLIST        0x200
                    269: #define        VMTOTAL         0x400
                    270: #define        POOLCACHESTAT   0x800
1.1       cgd       271:
1.151     yamt      272: /*
                    273:  * Print single word.  `ovflow' is number of characters didn't fit
                    274:  * on the last word.  `fmt' is a format string to print this word.
                    275:  * It must contain asterisk for field width.  `width' is a width
                    276:  * occupied by this word.  `fixed' is a number of constant chars in
                    277:  * `fmt'.  `val' is a value to be printed using format string `fmt'.
                    278:  */
                    279: #define        PRWORD(ovflw, fmt, width, fixed, val) do {      \
                    280:        (ovflw) += printf((fmt),                        \
                    281:            (width) - (fixed) - (ovflw) > 0 ?           \
                    282:            (width) - (fixed) - (ovflw) : 0,            \
                    283:            (val)) - (width);                           \
                    284:        if ((ovflw) < 0)                                \
                    285:                (ovflw) = 0;                            \
                    286: } while (/* CONSTCOND */0)
                    287:
                    288: void   cpustats(int *);
1.171     christos  289: void   cpucounters(struct cpu_counter *);
1.87      lukem     290: void   deref_kptr(const void *, void *, size_t, const char *);
1.151     yamt      291: void   drvstats(int *);
1.176     matt      292: void   doevcnt(int verbose, int type);
1.88      lukem     293: void   dohashstat(int, int, const char *);
1.73      simonb    294: void   dointr(int verbose);
1.126     simonb    295: void   dopool(int, int);
1.182     yamt      296: void   dopoolcache(int);
1.73      simonb    297: void   dosum(void);
1.103     mycroft   298: void   dovmstat(struct timespec *, int);
1.130     he        299: void   print_total_hdr(void);
                    300: void   dovmtotal(struct timespec *, int);
1.133     chs       301: void   kread(struct nlist *, int, void *, size_t);
1.147     kardel    302: int    kreadc(struct nlist *, int, void *, size_t);
1.73      simonb    303: void   needhdr(int);
1.176     matt      304: void   getnlist(int);
1.73      simonb    305: long   getuptime(void);
                    306: void   printhdr(void);
1.203     nakayama  307: long   pct(u_long, u_long);
1.183     joerg     308: __dead static void     usage(void);
1.73      simonb    309: void   doforkst(void);
                    310:
                    311: void   hist_traverse(int, const char *);
1.210     pgoyette  312: void   hist_dodump(struct kern_history *);
                    313: void   hist_traverse_sysctl(int, const char *);
                    314: void   hist_dodump_sysctl(int[], unsigned int);
1.73      simonb    315:
                    316: char   **choosedrives(char **);
1.38      mrg       317:
1.29      thorpej   318: /* Namelist and memory file names. */
                    319: char   *nlistf, *memf;
                    320:
1.47      mrg       321: /* allow old usage [vmstat 1] */
                    322: #define        BACKWARD_COMPATIBILITY
                    323:
1.197     joerg     324: static const int clockrate_mib[] = { CTL_KERN, KERN_CLOCKRATE };
1.170     christos  325: static const int vmmeter_mib[] = { CTL_VM, VM_METER };
                    326: static const int uvmexp2_mib[] = { CTL_VM, VM_UVMEXP2 };
1.176     matt      327: static const int boottime_mib[] = { CTL_KERN, KERN_BOOTTIME };
                    328: static char kvm_errbuf[_POSIX2_LINE_MAX];
1.170     christos  329:
1.38      mrg       330: int
1.75      enami     331: main(int argc, char *argv[])
1.1       cgd       332: {
1.126     simonb    333:        int c, todo, verbose, wide;
1.103     mycroft   334:        struct timespec interval;
1.1       cgd       335:        int reps;
1.75      enami     336:        gid_t egid = getegid();
1.88      lukem     337:        const char *histname, *hashname;
1.1       cgd       338:
1.88      lukem     339:        histname = hashname = NULL;
1.48      mrg       340:        (void)setegid(getgid());
1.13      cgd       341:        memf = nlistf = NULL;
1.126     simonb    342:        reps = todo = verbose = wide = 0;
1.103     mycroft   343:        interval.tv_sec = 0;
                    344:        interval.tv_nsec = 0;
1.154     ad        345:        while ((c = getopt(argc, argv, "Cc:efh:HilLM:mN:stu:UvWw:")) != -1) {
1.1       cgd       346:                switch (c) {
                    347:                case 'c':
                    348:                        reps = atoi(optarg);
                    349:                        break;
1.154     ad        350:                case 'C':
                    351:                        todo |= POOLCACHESTAT;
                    352:                        break;
1.66      cgd       353:                case 'e':
                    354:                        todo |= EVCNTSTAT;
                    355:                        break;
1.1       cgd       356:                case 'f':
                    357:                        todo |= FORKSTAT;
                    358:                        break;
1.45      thorpej   359:                case 'h':
1.88      lukem     360:                        hashname = optarg;
                    361:                        /* FALLTHROUGH */
                    362:                case 'H':
1.87      lukem     363:                        todo |= HASHSTAT;
1.45      thorpej   364:                        break;
1.1       cgd       365:                case 'i':
                    366:                        todo |= INTRSTAT;
                    367:                        break;
1.45      thorpej   368:                case 'l':
                    369:                        todo |= HISTLIST;
                    370:                        break;
1.88      lukem     371:                case 'L':
                    372:                        todo |= HASHLIST;
                    373:                        break;
1.1       cgd       374:                case 'M':
1.13      cgd       375:                        memf = optarg;
1.1       cgd       376:                        break;
                    377:                case 'm':
                    378:                        todo |= MEMSTAT;
                    379:                        break;
                    380:                case 'N':
1.13      cgd       381:                        nlistf = optarg;
1.1       cgd       382:                        break;
                    383:                case 's':
                    384:                        todo |= SUMSTAT;
                    385:                        break;
1.130     he        386:                case 't':
                    387:                        todo |= VMTOTAL;
                    388:                        break;
1.87      lukem     389:                case 'u':
                    390:                        histname = optarg;
                    391:                        /* FALLTHROUGH */
                    392:                case 'U':
                    393:                        todo |= HISTDUMP;
                    394:                        break;
1.66      cgd       395:                case 'v':
1.87      lukem     396:                        verbose++;
1.66      cgd       397:                        break;
1.126     simonb    398:                case 'W':
                    399:                        wide++;
                    400:                        break;
1.1       cgd       401:                case 'w':
1.103     mycroft   402:                        interval.tv_sec = atol(optarg);
1.1       cgd       403:                        break;
                    404:                case '?':
                    405:                default:
                    406:                        usage();
                    407:                }
                    408:        }
                    409:        argc -= optind;
                    410:        argv += optind;
                    411:
                    412:        if (todo == 0)
                    413:                todo = VMSTAT;
                    414:
1.13      cgd       415:        /*
1.48      mrg       416:         * Discard setgid privileges.  If not the running kernel, we toss
                    417:         * them away totally so that bad guys can't print interesting stuff
                    418:         * from kernel memory, otherwise switch back to kmem for the
                    419:         * duration of the kvm_openfiles() call.
1.13      cgd       420:         */
                    421:        if (nlistf != NULL || memf != NULL)
1.48      mrg       422:                (void)setgid(getgid());
                    423:        else
                    424:                (void)setegid(egid);
1.13      cgd       425:
1.176     matt      426:        kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, kvm_errbuf);
                    427:        if (kd == NULL) {
                    428:                if (nlistf != NULL || memf != NULL) {
                    429:                        errx(1, "kvm_openfiles: %s", kvm_errbuf);
                    430:                }
                    431:        }
1.48      mrg       432:
1.95      simonb    433:        if (nlistf == NULL && memf == NULL)
                    434:                (void)setgid(getgid());
1.1       cgd       435:
                    436:
                    437:        if (todo & VMSTAT) {
                    438:                struct winsize winsize;
                    439:
1.153     christos  440:                (void)drvinit(0);/* Initialize disk stats, no disks selected. */
1.49      drochner  441:
                    442:                (void)setgid(getgid()); /* don't need privs anymore */
                    443:
1.29      thorpej   444:                argv = choosedrives(argv);      /* Select disks. */
1.1       cgd       445:                winsize.ws_row = 0;
1.115     simonb    446:                (void)ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize);
1.1       cgd       447:                if (winsize.ws_row > 0)
                    448:                        winlines = winsize.ws_row;
                    449:
                    450:        }
                    451:
                    452: #ifdef BACKWARD_COMPATIBILITY
                    453:        if (*argv) {
1.103     mycroft   454:                interval.tv_sec = atol(*argv);
1.1       cgd       455:                if (*++argv)
                    456:                        reps = atoi(*argv);
                    457:        }
                    458: #endif
                    459:
1.103     mycroft   460:        if (interval.tv_sec) {
1.1       cgd       461:                if (!reps)
                    462:                        reps = -1;
                    463:        } else if (reps)
1.103     mycroft   464:                interval.tv_sec = 1;
1.1       cgd       465:
1.78      jhawk     466:
1.185     christos  467:        getnlist(todo);
1.78      jhawk     468:        /*
                    469:         * Statistics dumping is incompatible with the default
                    470:         * VMSTAT/dovmstat() output. So perform the interval/reps handling
                    471:         * for it here.
                    472:         */
1.130     he        473:        if ((todo & (VMSTAT|VMTOTAL)) == 0) {
1.99      enami     474:                for (;;) {
                    475:                        if (todo & (HISTLIST|HISTDUMP)) {
                    476:                                if ((todo & (HISTLIST|HISTDUMP)) ==
                    477:                                    (HISTLIST|HISTDUMP))
                    478:                                        errx(1, "you may list or dump,"
                    479:                                            " but not both!");
1.210     pgoyette  480:                                if (memf != NULL)
                    481:                                        hist_traverse(todo, histname);
                    482:                                else
                    483:                                        hist_traverse_sysctl(todo, histname);
1.153     christos  484:                                (void)putchar('\n');
1.99      enami     485:                        }
                    486:                        if (todo & FORKSTAT) {
                    487:                                doforkst();
1.153     christos  488:                                (void)putchar('\n');
1.99      enami     489:                        }
                    490:                        if (todo & MEMSTAT) {
1.126     simonb    491:                                dopool(verbose, wide);
1.153     christos  492:                                (void)putchar('\n');
1.99      enami     493:                        }
1.154     ad        494:                        if (todo & POOLCACHESTAT) {
1.182     yamt      495:                                dopoolcache(verbose);
1.154     ad        496:                                (void)putchar('\n');
                    497:                        }
1.99      enami     498:                        if (todo & SUMSTAT) {
                    499:                                dosum();
1.153     christos  500:                                (void)putchar('\n');
1.99      enami     501:                        }
                    502:                        if (todo & INTRSTAT) {
                    503:                                dointr(verbose);
1.153     christos  504:                                (void)putchar('\n');
1.99      enami     505:                        }
                    506:                        if (todo & EVCNTSTAT) {
1.176     matt      507:                                doevcnt(verbose, EVCNT_TYPE_ANY);
1.153     christos  508:                                (void)putchar('\n');
1.99      enami     509:                        }
                    510:                        if (todo & (HASHLIST|HASHSTAT)) {
                    511:                                if ((todo & (HASHLIST|HASHSTAT)) ==
                    512:                                    (HASHLIST|HASHSTAT))
                    513:                                        errx(1, "you may list or display,"
                    514:                                            " but not both!");
                    515:                                dohashstat(verbose, todo, hashname);
1.153     christos  516:                                (void)putchar('\n');
1.99      enami     517:                        }
1.101     sommerfe  518:
1.164     dholland  519:                        fflush(stdout);
1.101     sommerfe  520:                        if (reps >= 0 && --reps <=0)
1.99      enami     521:                                break;
1.153     christos  522:                        (void)nanosleep(&interval, NULL);
1.87      lukem     523:                }
1.130     he        524:        } else {
                    525:                if ((todo & (VMSTAT|VMTOTAL)) == (VMSTAT|VMTOTAL)) {
                    526:                        errx(1, "you may not both do vmstat and vmtotal");
                    527:                }
                    528:                if (todo & VMSTAT)
                    529:                        dovmstat(&interval, reps);
                    530:                if (todo & VMTOTAL)
                    531:                        dovmtotal(&interval, reps);
                    532:        }
1.153     christos  533:        return 0;
1.1       cgd       534: }
                    535:
1.176     matt      536: void
                    537: getnlist(int todo)
                    538: {
                    539:        static int namelist_done = 0;
1.185     christos  540:        static int done = 0;
1.176     matt      541:        int c;
                    542:        size_t i;
                    543:
                    544:        if (kd == NULL)
                    545:                errx(1, "kvm_openfiles: %s", kvm_errbuf);
                    546:
                    547:        if (!namelist_done) {
                    548:                namelist_done = 1;
                    549:                if ((c = kvm_nlist(kd, namelist)) != 0) {
                    550:                        int doexit = 0;
                    551:                        if (c == -1)
                    552:                                errx(1, "kvm_nlist: %s %s",
                    553:                                    "namelist", kvm_geterr(kd));
                    554:                        for (i = 0; i < __arraycount(namelist)-1; i++)
                    555:                                if (namelist[i].n_type == 0 &&
                    556:                                    i != X_TIME_SECOND &&
                    557:                                    i != X_TIME) {
                    558:                                        if (doexit++ == 0)
                    559:                                                (void)fprintf(stderr,
                    560:                                                    "%s: undefined symbols:",
                    561:                                                    getprogname());
                    562:                                        (void)fprintf(stderr, " %s",
                    563:                                            namelist[i].n_name);
                    564:                                }
                    565:                        if (doexit) {
                    566:                                (void)fputc('\n', stderr);
                    567:                                exit(1);
                    568:                        }
                    569:                }
                    570:        }
1.185     christos  571:        if ((todo & (SUMSTAT|INTRSTAT)) && !(done & (SUMSTAT|INTRSTAT))) {
                    572:                done |= SUMSTAT|INTRSTAT;
1.176     matt      573:                (void) kvm_nlist(kd, intrnl);
                    574:        }
1.185     christos  575:        if ((todo & (HASHLIST|HASHSTAT)) && !(done & (HASHLIST|HASHSTAT))) {
                    576:                done |= HASHLIST|HASHSTAT;
1.176     matt      577:                if ((c = kvm_nlist(kd, hashnl)) == -1 || c == X_HASHNL_SIZE)
                    578:                        errx(1, "kvm_nlist: %s %s", "hashnl", kvm_geterr(kd));
                    579:        }
1.185     christos  580:        if ((todo & (HISTLIST|HISTDUMP)) && !(done & (HISTLIST|HISTDUMP))) {
                    581:                done |= HISTLIST|HISTDUMP;
1.176     matt      582:                if (kvm_nlist(kd, histnl) == -1)
                    583:                        errx(1, "kvm_nlist: %s %s", "histnl", kvm_geterr(kd));
                    584:        }
                    585: }
                    586:
1.1       cgd       587: char **
1.73      simonb    588: choosedrives(char **argv)
1.1       cgd       589: {
1.165     lukem     590:        size_t i;
1.1       cgd       591:
                    592:        /*
                    593:         * Choose drives to be displayed.  Priority goes to (in order) drives
                    594:         * supplied as arguments, default drives.  If everything isn't filled
                    595:         * in and there are drives not taken care of, display the first few
                    596:         * that fit.
                    597:         */
1.75      enami     598: #define        BACKWARD_COMPATIBILITY
1.1       cgd       599:        for (ndrives = 0; *argv; ++argv) {
                    600: #ifdef BACKWARD_COMPATIBILITY
1.124     dsl       601:                if (isdigit((unsigned char)**argv))
1.1       cgd       602:                        break;
                    603: #endif
1.140     blymn     604:                for (i = 0; i < ndrive; i++) {
1.1       cgd       605:                        if (strcmp(dr_name[i], *argv))
                    606:                                continue;
1.140     blymn     607:                        drv_select[i] = 1;
1.136     blymn     608:                        ++ndrives;
                    609:                        break;
                    610:                }
1.1       cgd       611:        }
1.151     yamt      612:        for (i = 0; i < ndrive && ndrives < 2; i++) {
1.140     blymn     613:                if (drv_select[i])
1.1       cgd       614:                        continue;
1.140     blymn     615:                drv_select[i] = 1;
1.1       cgd       616:                ++ndrives;
                    617:        }
1.140     blymn     618:
1.75      enami     619:        return (argv);
1.1       cgd       620: }
                    621:
                    622: long
1.73      simonb    623: getuptime(void)
1.1       cgd       624: {
1.176     matt      625:        static struct timespec boottime;
                    626:        struct timespec now;
1.149     kardel    627:        time_t uptime, nowsec;
1.1       cgd       628:
1.176     matt      629:        if (memf == NULL) {
                    630:                if (boottime.tv_sec == 0) {
                    631:                        size_t buflen = sizeof(boottime);
                    632:                        if (sysctl(boottime_mib, __arraycount(boottime_mib),
                    633:                            &boottime, &buflen, NULL, 0) == -1)
                    634:                                warn("Can't get boottime");
                    635:                }
                    636:                clock_gettime(CLOCK_REALTIME, &now);
1.147     kardel    637:        } else {
1.176     matt      638:                if (boottime.tv_sec == 0)
                    639:                        kread(namelist, X_BOOTTIME, &boottime,
                    640:                            sizeof(boottime));
                    641:                if (kreadc(namelist, X_TIME_SECOND, &nowsec, sizeof(nowsec))) {
                    642:                        /*
                    643:                         * XXX this assignment dance can be removed once
                    644:                         * timeval tv_sec is SUS mandated time_t
                    645:                         */
                    646:                        now.tv_sec = nowsec;
                    647:                        now.tv_nsec = 0;
                    648:                } else {
                    649:                        kread(namelist, X_TIME, &now, sizeof(now));
                    650:                }
1.147     kardel    651:        }
1.145     kardel    652:        uptime = now.tv_sec - boottime.tv_sec;
1.87      lukem     653:        if (uptime <= 0 || uptime > 60*60*24*365*10)
                    654:                errx(1, "time makes no sense; namelist must be wrong.");
1.75      enami     655:        return (uptime);
1.1       cgd       656: }
                    657:
                    658: int    hz, hdrcnt;
                    659:
                    660: void
1.187     matt      661: print_total_hdr(void)
1.130     he        662: {
                    663:
1.166     rmind     664:        (void)printf("procs         memory\n");
                    665:        (void)printf("ru dw pw sl");
1.130     he        666:        (void)printf("   total-v  active-v  active-r");
                    667:        (void)printf(" vm-sh avm-sh rm-sh arm-sh free\n");
                    668:        hdrcnt = winlines - 2;
                    669: }
                    670:
                    671: void
                    672: dovmtotal(struct timespec *interval, int reps)
                    673: {
                    674:        struct vmtotal total;
                    675:        size_t size;
                    676:
                    677:        (void)signal(SIGCONT, needhdr);
                    678:
                    679:        for (hdrcnt = 1;;) {
                    680:                if (!--hdrcnt)
                    681:                        print_total_hdr();
                    682:                if (memf != NULL) {
1.170     christos  683:                        warnx("Unable to get vmtotals from crash dump.");
1.153     christos  684:                        (void)memset(&total, 0, sizeof(total));
1.130     he        685:                } else {
                    686:                        size = sizeof(total);
1.170     christos  687:                        if (sysctl(vmmeter_mib, __arraycount(vmmeter_mib),
                    688:                            &total, &size, NULL, 0) == -1) {
                    689:                                warn("Can't get vmtotals");
1.153     christos  690:                                (void)memset(&total, 0, sizeof(total));
1.130     he        691:                        }
                    692:                }
1.153     christos  693:                (void)printf("%2d ", total.t_rq);
                    694:                (void)printf("%2d ", total.t_dw);
                    695:                (void)printf("%2d ", total.t_pw);
                    696:                (void)printf("%2d ", total.t_sl);
                    697:
                    698:                (void)printf("%9d ", total.t_vm);
                    699:                (void)printf("%9d ", total.t_avm);
                    700:                (void)printf("%9d ", total.t_arm);
                    701:                (void)printf("%5d ", total.t_vmshr);
                    702:                (void)printf("%6d ", total.t_avmshr);
                    703:                (void)printf("%5d ", total.t_rmshr);
                    704:                (void)printf("%6d ", total.t_armshr);
                    705:                (void)printf("%5d",  total.t_free);
1.130     he        706:
1.153     christos  707:                (void)putchar('\n');
1.130     he        708:
                    709:                (void)fflush(stdout);
                    710:                if (reps >= 0 && --reps <= 0)
                    711:                        break;
                    712:
1.153     christos  713:                (void)nanosleep(interval, NULL);
1.130     he        714:        }
                    715: }
                    716:
                    717: void
1.103     mycroft   718: dovmstat(struct timespec *interval, int reps)
1.1       cgd       719: {
                    720:        struct vmtotal total;
                    721:        time_t uptime, halfuptime;
1.17      cgd       722:        size_t size;
1.41      mrg       723:        int pagesize = getpagesize();
1.151     yamt      724:        int ovflw;
1.1       cgd       725:
                    726:        uptime = getuptime();
                    727:        halfuptime = uptime / 2;
                    728:        (void)signal(SIGCONT, needhdr);
                    729:
1.197     joerg     730:        if (memf != NULL) {
                    731:                if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0)
                    732:                        kread(namelist, X_STATHZ, &hz, sizeof(hz));
                    733:                if (!hz)
                    734:                        kread(namelist, X_HZ, &hz, sizeof(hz));
                    735:        } else {
                    736:                struct clockinfo clockinfo;
                    737:                size = sizeof(clockinfo);
                    738:                if (sysctl(clockrate_mib, 2, &clockinfo, &size, NULL, 0) == -1)
                    739:                        err(1, "sysctl kern.clockrate failed");
                    740:                hz = clockinfo.stathz;
                    741:                if (!hz)
                    742:                        hz = clockinfo.hz;
                    743:        }
1.1       cgd       744:
                    745:        for (hdrcnt = 1;;) {
                    746:                if (!--hdrcnt)
                    747:                        printhdr();
1.29      thorpej   748:                /* Read new disk statistics */
1.139     dsl       749:                cpureadstats();
1.140     blymn     750:                drvreadstats();
1.139     dsl       751:                tkreadstats();
1.58      thorpej   752:                if (memf != NULL) {
1.196     joerg     753:                        struct uvmexp uvmexp_kernel;
1.58      thorpej   754:                        /*
                    755:                         * XXX Can't do this if we're reading a crash
                    756:                         * XXX dump because they're lazily-calculated.
                    757:                         */
1.170     christos  758:                        warnx("Unable to get vmtotals from crash dump.");
1.153     christos  759:                        (void)memset(&total, 0, sizeof(total));
1.196     joerg     760:                        kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel));
                    761: #define COPY(field) uvmexp.field = uvmexp_kernel.field
                    762:                        COPY(pdreact);
                    763:                        COPY(pageins);
                    764:                        COPY(pgswapout);
                    765:                        COPY(pdfreed);
                    766:                        COPY(pdscans);
                    767: #undef COPY
1.58      thorpej   768:                } else {
                    769:                        size = sizeof(total);
1.170     christos  770:                        if (sysctl(vmmeter_mib, __arraycount(vmmeter_mib),
                    771:                            &total, &size, NULL, 0) == -1) {
                    772:                                warn("Can't get vmtotals");
1.153     christos  773:                                (void)memset(&total, 0, sizeof(total));
1.58      thorpej   774:                        }
1.196     joerg     775:                        size = sizeof(uvmexp);
                    776:                        if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp,
                    777:                            &size, NULL, 0) == -1)
                    778:                                warn("sysctl vm.uvmexp2 failed");
1.13      cgd       779:                }
1.171     christos  780:                cpucounters(&cpucounter);
1.151     yamt      781:                ovflw = 0;
                    782:                PRWORD(ovflw, " %*d", 2, 1, total.t_rq - 1);
                    783:                PRWORD(ovflw, " %*d", 2, 1, total.t_dw + total.t_pw);
1.153     christos  784: #define        pgtok(a) (long)((a) * ((uint32_t)pagesize >> 10))
1.38      mrg       785: #define        rate(x) (u_long)(((x) + halfuptime) / uptime)   /* round */
1.166     rmind     786:                PRWORD(ovflw, " %*ld", 9, 1, pgtok(total.t_avm));
1.151     yamt      787:                PRWORD(ovflw, " %*ld", 7, 1, pgtok(total.t_free));
                    788:                PRWORD(ovflw, " %*ld", 5, 1,
1.171     christos  789:                    rate(cpucounter.nfault - ocpucounter.nfault));
1.151     yamt      790:                PRWORD(ovflw, " %*ld", 4, 1,
                    791:                    rate(uvmexp.pdreact - ouvmexp.pdreact));
                    792:                PRWORD(ovflw, " %*ld", 4, 1,
                    793:                    rate(uvmexp.pageins - ouvmexp.pageins));
                    794:                PRWORD(ovflw, " %*ld", 5, 1,
1.44      mrg       795:                    rate(uvmexp.pgswapout - ouvmexp.pgswapout));
1.151     yamt      796:                PRWORD(ovflw, " %*ld", 5, 1,
                    797:                    rate(uvmexp.pdfreed - ouvmexp.pdfreed));
                    798:                PRWORD(ovflw, " %*ld", 6, 2,
                    799:                    rate(uvmexp.pdscans - ouvmexp.pdscans));
                    800:                drvstats(&ovflw);
                    801:                PRWORD(ovflw, " %*ld", 5, 1,
1.171     christos  802:                    rate(cpucounter.nintr - ocpucounter.nintr));
1.151     yamt      803:                PRWORD(ovflw, " %*ld", 5, 1,
1.171     christos  804:                    rate(cpucounter.nsyscall - ocpucounter.nsyscall));
1.151     yamt      805:                PRWORD(ovflw, " %*ld", 4, 1,
1.171     christos  806:                    rate(cpucounter.nswtch - ocpucounter.nswtch));
1.151     yamt      807:                cpustats(&ovflw);
1.153     christos  808:                (void)putchar('\n');
1.42      mrg       809:                (void)fflush(stdout);
                    810:                if (reps >= 0 && --reps <= 0)
                    811:                        break;
1.172     enami     812:                ouvmexp = uvmexp;
1.171     christos  813:                ocpucounter = cpucounter;
1.103     mycroft   814:                uptime = interval->tv_sec;
1.1       cgd       815:                /*
                    816:                 * We round upward to avoid losing low-frequency events
                    817:                 * (i.e., >= 1 per interval but < 1 per second).
                    818:                 */
1.33      thorpej   819:                halfuptime = uptime == 1 ? 0 : (uptime + 1) / 2;
1.153     christos  820:                (void)nanosleep(interval, NULL);
1.1       cgd       821:        }
                    822: }
                    823:
1.38      mrg       824: void
1.73      simonb    825: printhdr(void)
1.1       cgd       826: {
1.165     lukem     827:        size_t i;
1.1       cgd       828:
1.104     mrg       829:        (void)printf(" procs    memory      page%*s", 23, "");
1.29      thorpej   830:        if (ndrives > 0)
1.70      sommerfe  831:                (void)printf("%s %*sfaults      cpu\n",
1.75      enami     832:                    ((ndrives > 1) ? "disks" : "disk"),
                    833:                    ((ndrives > 1) ? ndrives * 3 - 4 : 0), "");
1.1       cgd       834:        else
1.29      thorpej   835:                (void)printf("%*s  faults   cpu\n",
1.75      enami     836:                    ndrives * 3, "");
1.29      thorpej   837:
1.166     rmind     838:        (void)printf(" r b      avm    fre  flt  re  pi   po   fr   sr ");
1.140     blymn     839:        for (i = 0; i < ndrive; i++)
                    840:                if (drv_select[i])
1.1       cgd       841:                        (void)printf("%c%c ", dr_name[i][0],
                    842:                            dr_name[i][strlen(dr_name[i]) - 1]);
                    843:        (void)printf("  in   sy  cs us sy id\n");
                    844:        hdrcnt = winlines - 2;
                    845: }
                    846:
                    847: /*
                    848:  * Force a header to be prepended to the next output.
                    849:  */
                    850: void
1.153     christos  851: /*ARGSUSED*/
1.73      simonb    852: needhdr(int dummy)
1.1       cgd       853: {
                    854:
                    855:        hdrcnt = 1;
                    856: }
                    857:
1.38      mrg       858: long
1.203     nakayama  859: pct(u_long top, u_long bot)
1.1       cgd       860: {
1.13      cgd       861:        long ans;
                    862:
1.1       cgd       863:        if (bot == 0)
1.75      enami     864:                return (0);
1.153     christos  865:        ans = (long)((quad_t)top * 100 / bot);
1.13      cgd       866:        return (ans);
1.1       cgd       867: }
                    868:
1.203     nakayama  869: #define        PCT(top, bot) (int)pct((u_long)(top), (u_long)(bot))
1.1       cgd       870:
                    871: void
1.73      simonb    872: dosum(void)
1.1       cgd       873: {
1.206     dennis    874:        struct nchstats nch_stats;
1.194     joerg     875:        uint64_t nchtotal;
1.162     he        876:        size_t ssize;
                    877:        int active_kernel;
1.171     christos  878:        struct cpu_counter cc;
1.162     he        879:
                    880:        /*
                    881:         * The "active" and "inactive" variables
                    882:         * are now estimated by the kernel and sadly
                    883:         * can not easily be dug out of a crash dump.
                    884:         */
1.195     joerg     885:        ssize = sizeof(uvmexp);
                    886:        memset(&uvmexp, 0, ssize);
1.162     he        887:        active_kernel = (memf == NULL);
                    888:        if (active_kernel) {
                    889:                /* only on active kernel */
1.195     joerg     890:                if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp,
1.170     christos  891:                    &ssize, NULL, 0) == -1)
                    892:                        warn("sysctl vm.uvmexp2 failed");
1.195     joerg     893:        } else {
                    894:                struct uvmexp uvmexp_kernel;
                    895:                kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel));
                    896: #define COPY(field) uvmexp.field = uvmexp_kernel.field
                    897:                COPY(pagesize);
                    898:                COPY(ncolors);
                    899:                COPY(npages);
                    900:                COPY(free);
                    901:                COPY(paging);
                    902:                COPY(wired);
                    903:                COPY(zeropages);
                    904:                COPY(reserve_pagedaemon);
                    905:                COPY(reserve_kernel);
                    906:                COPY(anonpages);
                    907:                COPY(filepages);
                    908:                COPY(execpages);
                    909:                COPY(freemin);
                    910:                COPY(freetarg);
                    911:                COPY(wiredmax);
                    912:                COPY(nswapdev);
                    913:                COPY(swpages);
                    914:                COPY(swpginuse);
                    915:                COPY(nswget);
                    916:                COPY(pageins);
                    917:                COPY(pdpageouts);
                    918:                COPY(pgswapin);
                    919:                COPY(pgswapout);
                    920:                COPY(forks);
                    921:                COPY(forks_ppwait);
                    922:                COPY(forks_sharevm);
                    923:                COPY(pga_zerohit);
                    924:                COPY(pga_zeromiss);
                    925:                COPY(zeroaborts);
                    926:                COPY(colorhit);
                    927:                COPY(colormiss);
                    928:                COPY(cpuhit);
                    929:                COPY(cpumiss);
                    930:                COPY(fltnoram);
                    931:                COPY(fltnoanon);
                    932:                COPY(fltpgwait);
                    933:                COPY(fltpgrele);
                    934:                COPY(fltrelck);
                    935:                COPY(fltrelckok);
                    936:                COPY(fltanget);
                    937:                COPY(fltanretry);
                    938:                COPY(fltamcopy);
                    939:                COPY(fltamcopy);
                    940:                COPY(fltnomap);
                    941:                COPY(fltlget);
                    942:                COPY(fltget);
                    943:                COPY(flt_anon);
                    944:                COPY(flt_acow);
                    945:                COPY(flt_obj);
                    946:                COPY(flt_prcopy);
                    947:                COPY(flt_przero);
                    948:                COPY(pdwoke);
                    949:                COPY(pdrevs);
                    950:                COPY(pdfreed);
                    951:                COPY(pdscans);
                    952:                COPY(pdanscan);
                    953:                COPY(pdobscan);
                    954:                COPY(pdreact);
                    955:                COPY(pdbusy);
                    956:                COPY(pdpending);
                    957:                COPY(pddeact);
                    958: #undef COPY
1.162     he        959:        }
1.1       cgd       960:
1.41      mrg       961:
1.195     joerg     962:        (void)printf("%9" PRIu64 " bytes per page\n", uvmexp.pagesize);
1.44      mrg       963:
1.195     joerg     964:        (void)printf("%9" PRIu64 " page color%s\n",
1.81      thorpej   965:            uvmexp.ncolors, uvmexp.ncolors == 1 ? "" : "s");
                    966:
1.195     joerg     967:        (void)printf("%9" PRIu64 " pages managed\n", uvmexp.npages);
                    968:        (void)printf("%9" PRIu64 " pages free\n", uvmexp.free);
1.162     he        969:        if (active_kernel) {
1.195     joerg     970:                (void)printf("%9" PRIu64 " pages active\n", uvmexp.active);
                    971:                (void)printf("%9" PRIu64 " pages inactive\n", uvmexp.inactive);
1.162     he        972:        }
1.195     joerg     973:        (void)printf("%9" PRIu64 " pages paging\n", uvmexp.paging);
                    974:        (void)printf("%9" PRIu64 " pages wired\n", uvmexp.wired);
                    975:        (void)printf("%9" PRIu64 " zero pages\n", uvmexp.zeropages);
                    976:        (void)printf("%9" PRIu64 " reserve pagedaemon pages\n",
1.44      mrg       977:            uvmexp.reserve_pagedaemon);
1.195     joerg     978:        (void)printf("%9" PRIu64 " reserve kernel pages\n", uvmexp.reserve_kernel);
                    979:        (void)printf("%9" PRIu64 " anonymous pages\n", uvmexp.anonpages);
                    980:        (void)printf("%9" PRIu64 " cached file pages\n", uvmexp.filepages);
                    981:        (void)printf("%9" PRIu64 " cached executable pages\n", uvmexp.execpages);
                    982:
                    983:        (void)printf("%9" PRIu64 " minimum free pages\n", uvmexp.freemin);
                    984:        (void)printf("%9" PRIu64 " target free pages\n", uvmexp.freetarg);
                    985:        (void)printf("%9" PRIu64 " maximum wired pages\n", uvmexp.wiredmax);
                    986:
                    987:        (void)printf("%9" PRIu64 " swap devices\n", uvmexp.nswapdev);
                    988:        (void)printf("%9" PRIu64 " swap pages\n", uvmexp.swpages);
                    989:        (void)printf("%9" PRIu64 " swap pages in use\n", uvmexp.swpginuse);
                    990:        (void)printf("%9" PRIu64 " swap allocations\n", uvmexp.nswget);
1.44      mrg       991:
1.171     christos  992:        cpucounters(&cc);
1.190     rmind     993:
1.171     christos  994:        (void)printf("%9" PRIu64 " total faults taken\n", cc.nfault);
                    995:        (void)printf("%9" PRIu64 " traps\n", cc.ntrap);
                    996:        (void)printf("%9" PRIu64 " device interrupts\n", cc.nintr);
                    997:        (void)printf("%9" PRIu64 " CPU context switches\n", cc.nswtch);
                    998:        (void)printf("%9" PRIu64 " software interrupts\n", cc.nsoft);
                    999:        (void)printf("%9" PRIu64 " system calls\n", cc.nsyscall);
1.195     joerg    1000:        (void)printf("%9" PRIu64 " pagein requests\n", uvmexp.pageins);
                   1001:        (void)printf("%9" PRIu64 " pageout requests\n", uvmexp.pdpageouts);
                   1002:        (void)printf("%9" PRIu64 " pages swapped in\n", uvmexp.pgswapin);
                   1003:        (void)printf("%9" PRIu64 " pages swapped out\n", uvmexp.pgswapout);
                   1004:        (void)printf("%9" PRIu64 " forks total\n", uvmexp.forks);
                   1005:        (void)printf("%9" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait);
                   1006:        (void)printf("%9" PRIu64 " forks shared address space with parent\n",
1.43      mrg      1007:            uvmexp.forks_sharevm);
1.195     joerg    1008:        (void)printf("%9" PRIu64 " pagealloc zero wanted and avail\n",
1.63      thorpej  1009:            uvmexp.pga_zerohit);
1.195     joerg    1010:        (void)printf("%9" PRIu64 " pagealloc zero wanted and not avail\n",
1.63      thorpej  1011:            uvmexp.pga_zeromiss);
1.195     joerg    1012:        (void)printf("%9" PRIu64 " aborts of idle page zeroing\n",
1.68      thorpej  1013:            uvmexp.zeroaborts);
1.195     joerg    1014:        (void)printf("%9" PRIu64 " pagealloc desired color avail\n",
1.79      thorpej  1015:            uvmexp.colorhit);
1.195     joerg    1016:        (void)printf("%9" PRIu64 " pagealloc desired color not avail\n",
1.79      thorpej  1017:            uvmexp.colormiss);
1.195     joerg    1018:        (void)printf("%9" PRIu64 " pagealloc local cpu avail\n",
1.159     ad       1019:            uvmexp.cpuhit);
1.195     joerg    1020:        (void)printf("%9" PRIu64 " pagealloc local cpu not avail\n",
1.159     ad       1021:            uvmexp.cpumiss);
1.44      mrg      1022:
1.195     joerg    1023:        (void)printf("%9" PRIu64 " faults with no memory\n", uvmexp.fltnoram);
                   1024:        (void)printf("%9" PRIu64 " faults with no anons\n", uvmexp.fltnoanon);
                   1025:        (void)printf("%9" PRIu64 " faults had to wait on pages\n", uvmexp.fltpgwait);
                   1026:        (void)printf("%9" PRIu64 " faults found released page\n", uvmexp.fltpgrele);
                   1027:        (void)printf("%9" PRIu64 " faults relock (%" PRIu64 " ok)\n", uvmexp.fltrelck,
1.43      mrg      1028:            uvmexp.fltrelckok);
1.195     joerg    1029:        (void)printf("%9" PRIu64 " anon page faults\n", uvmexp.fltanget);
                   1030:        (void)printf("%9" PRIu64 " anon retry faults\n", uvmexp.fltanretry);
                   1031:        (void)printf("%9" PRIu64 " amap copy faults\n", uvmexp.fltamcopy);
                   1032:        (void)printf("%9" PRIu64 " neighbour anon page faults\n", uvmexp.fltnamap);
                   1033:        (void)printf("%9" PRIu64 " neighbour object page faults\n", uvmexp.fltnomap);
                   1034:        (void)printf("%9" PRIu64 " locked pager get faults\n", uvmexp.fltlget);
                   1035:        (void)printf("%9" PRIu64 " unlocked pager get faults\n", uvmexp.fltget);
                   1036:        (void)printf("%9" PRIu64 " anon faults\n", uvmexp.flt_anon);
                   1037:        (void)printf("%9" PRIu64 " anon copy on write faults\n", uvmexp.flt_acow);
                   1038:        (void)printf("%9" PRIu64 " object faults\n", uvmexp.flt_obj);
                   1039:        (void)printf("%9" PRIu64 " promote copy faults\n", uvmexp.flt_prcopy);
                   1040:        (void)printf("%9" PRIu64 " promote zero fill faults\n", uvmexp.flt_przero);
                   1041:
                   1042:        (void)printf("%9" PRIu64 " times daemon wokeup\n",uvmexp.pdwoke);
                   1043:        (void)printf("%9" PRIu64 " revolutions of the clock hand\n", uvmexp.pdrevs);
                   1044:        (void)printf("%9" PRIu64 " pages freed by daemon\n", uvmexp.pdfreed);
                   1045:        (void)printf("%9" PRIu64 " pages scanned by daemon\n", uvmexp.pdscans);
                   1046:        (void)printf("%9" PRIu64 " anonymous pages scanned by daemon\n",
1.75      enami    1047:            uvmexp.pdanscan);
1.195     joerg    1048:        (void)printf("%9" PRIu64 " object pages scanned by daemon\n", uvmexp.pdobscan);
                   1049:        (void)printf("%9" PRIu64 " pages reactivated\n", uvmexp.pdreact);
                   1050:        (void)printf("%9" PRIu64 " pages found busy by daemon\n", uvmexp.pdbusy);
                   1051:        (void)printf("%9" PRIu64 " total pending pageouts\n", uvmexp.pdpending);
                   1052:        (void)printf("%9" PRIu64 " pages deactivated\n", uvmexp.pddeact);
1.123     enami    1053:
1.194     joerg    1054:        if (active_kernel) {
                   1055:                ssize = sizeof(nch_stats);
                   1056:                if (sysctlbyname("vfs.namecache_stats", &nch_stats, &ssize,
                   1057:                    NULL, 0)) {
                   1058:                        warn("vfs.namecache_stats failed");
                   1059:                        memset(&nch_stats, 0, sizeof(nch_stats));
                   1060:                }
                   1061:        } else {
1.206     dennis   1062:                kread(namelist, X_NCHSTATS, &nch_stats, sizeof(nch_stats));
1.194     joerg    1063:        }
                   1064:
                   1065:        nchtotal = nch_stats.ncs_goodhits + nch_stats.ncs_neghits +
                   1066:            nch_stats.ncs_badhits + nch_stats.ncs_falsehits +
                   1067:            nch_stats.ncs_miss + nch_stats.ncs_long;
                   1068:        (void)printf("%9" PRIu64 " total name lookups\n", nchtotal);
                   1069:        (void)printf("%9" PRIu64 " good hits\n", nch_stats.ncs_goodhits);
                   1070:        (void)printf("%9" PRIu64 " negative hits\n", nch_stats.ncs_neghits);
                   1071:        (void)printf("%9" PRIu64 " bad hits\n", nch_stats.ncs_badhits);
                   1072:        (void)printf("%9" PRIu64 " false hits\n", nch_stats.ncs_falsehits);
                   1073:        (void)printf("%9" PRIu64 " miss\n", nch_stats.ncs_miss);
                   1074:        (void)printf("%9" PRIu64 " too long\n", nch_stats.ncs_long);
                   1075:        (void)printf("%9" PRIu64 " pass2 hits\n", nch_stats.ncs_pass2);
                   1076:        (void)printf("%9" PRIu64 " 2passes\n", nch_stats.ncs_2passes);
1.1       cgd      1077:        (void)printf(
                   1078:            "%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n",
1.194     joerg    1079:            "", PCT(nch_stats.ncs_goodhits, nchtotal),
                   1080:            PCT(nch_stats.ncs_neghits, nchtotal),
                   1081:            PCT(nch_stats.ncs_pass2, nchtotal));
1.1       cgd      1082:        (void)printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "",
1.194     joerg    1083:            PCT(nch_stats.ncs_badhits, nchtotal),
                   1084:            PCT(nch_stats.ncs_falsehits, nchtotal),
                   1085:            PCT(nch_stats.ncs_long, nchtotal));
1.1       cgd      1086: }
                   1087:
                   1088: void
1.73      simonb   1089: doforkst(void)
1.1       cgd      1090: {
1.196     joerg    1091:        if (memf != NULL) {
                   1092:                struct uvmexp uvmexp_kernel;
                   1093:                kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel));
                   1094: #define COPY(field) uvmexp.field = uvmexp_kernel.field
                   1095:                COPY(forks);
                   1096:                COPY(forks_ppwait);
                   1097:                COPY(forks_sharevm);
                   1098: #undef COPY
                   1099:        } else {
                   1100:                size_t size = sizeof(uvmexp);
                   1101:                if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp,
                   1102:                    &size, NULL, 0) == -1)
                   1103:                        warn("sysctl vm.uvmexp2 failed");
                   1104:        }
1.58      thorpej  1105:
1.196     joerg    1106:        (void)printf("%" PRIu64 " forks total\n", uvmexp.forks);
                   1107:        (void)printf("%" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait);
                   1108:        (void)printf("%" PRIu64 " forks shared address space with parent\n",
1.41      mrg      1109:            uvmexp.forks_sharevm);
1.1       cgd      1110: }
                   1111:
                   1112: void
1.151     yamt     1113: drvstats(int *ovflwp)
1.1       cgd      1114: {
1.165     lukem    1115:        size_t dn;
1.216.6.1  snj      1116:        double dtime;
1.151     yamt     1117:        int ovflw = *ovflwp;
1.1       cgd      1118:
1.29      thorpej  1119:        /* Calculate disk stat deltas. */
1.139     dsl      1120:        cpuswap();
1.140     blymn    1121:        drvswap();
1.139     dsl      1122:        tkswap();
1.101     sommerfe 1123:
1.140     blymn    1124:        for (dn = 0; dn < ndrive; ++dn) {
1.216.6.1  snj      1125:                /* elapsed time for disk stats */
                   1126:                dtime = (double)cur.timestamp[dn].tv_sec +
                   1127:                        ((double)cur.timestamp[dn].tv_usec / (double)1000000);
                   1128:
1.140     blymn    1129:                if (!drv_select[dn])
1.151     yamt     1130:                        continue;
                   1131:                PRWORD(ovflw, " %*.0f", 3, 1,
1.216.6.1  snj      1132:                    (cur.rxfer[dn] + cur.wxfer[dn]) / dtime);
1.136     blymn    1133:        }
1.151     yamt     1134:        *ovflwp = ovflw;
1.136     blymn    1135: }
                   1136:
                   1137: void
1.171     christos 1138: cpucounters(struct cpu_counter *cc)
                   1139: {
1.198     joerg    1140:        static struct cpu_info **cpu_infos;
                   1141:        static int initialised;
                   1142:        struct cpu_info **slot;
                   1143:
                   1144:        if (memf == NULL) {
                   1145:                cc->nintr = uvmexp.intrs;
                   1146:                cc->nsyscall = uvmexp.syscalls;
                   1147:                cc->nswtch = uvmexp.swtch;
                   1148:                cc->nfault = uvmexp.faults;
                   1149:                cc->ntrap = uvmexp.traps;
                   1150:                cc->nsoft = uvmexp.softs;
                   1151:                return;
                   1152:        }
                   1153:
                   1154:        if (!initialised) {
                   1155:                kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos));
                   1156:                initialised = 1;
                   1157:        }
                   1158:
                   1159:        slot = cpu_infos;
1.190     rmind    1160:
                   1161:        memset(cc, 0, sizeof(*cc));
                   1162:
                   1163:        for (;;) {
                   1164:                struct cpu_info tci, *ci = NULL;
                   1165:
                   1166:                deref_kptr(slot++, &ci, sizeof(ci), "CPU array trashed");
                   1167:                if (!ci) {
                   1168:                        break;
                   1169:                }
                   1170:
1.171     christos 1171:                if ((size_t)kvm_read(kd, (u_long)ci, &tci, sizeof(tci))
                   1172:                    != sizeof(tci)) {
1.190     rmind    1173:                        warnx("Can't read cpu info from %p (%s)",
                   1174:                            ci, kvm_geterr(kd));
                   1175:                        memset(cc, 0, sizeof(*cc));
                   1176:                        return;
1.171     christos 1177:                }
                   1178:                cc->nintr += tci.ci_data.cpu_nintr;
                   1179:                cc->nsyscall += tci.ci_data.cpu_nsyscall;
                   1180:                cc->nswtch = tci.ci_data.cpu_nswtch;
                   1181:                cc->nfault = tci.ci_data.cpu_nfault;
                   1182:                cc->ntrap = tci.ci_data.cpu_ntrap;
                   1183:                cc->nsoft = tci.ci_data.cpu_nsoft;
                   1184:        }
                   1185: }
                   1186:
                   1187: void
1.151     yamt     1188: cpustats(int *ovflwp)
1.1       cgd      1189: {
1.38      mrg      1190:        int state;
1.129     dsl      1191:        double pcnt, total;
1.120     dbj      1192:        double stat_us, stat_sy, stat_id;
1.151     yamt     1193:        int ovflw = *ovflwp;
1.1       cgd      1194:
                   1195:        total = 0;
                   1196:        for (state = 0; state < CPUSTATES; ++state)
1.29      thorpej  1197:                total += cur.cp_time[state];
1.1       cgd      1198:        if (total)
1.129     dsl      1199:                pcnt = 100 / total;
1.1       cgd      1200:        else
1.129     dsl      1201:                pcnt = 0;
                   1202:        stat_us = (cur.cp_time[CP_USER] + cur.cp_time[CP_NICE]) * pcnt;
                   1203:        stat_sy = (cur.cp_time[CP_SYS] + cur.cp_time[CP_INTR]) * pcnt;
                   1204:        stat_id = cur.cp_time[CP_IDLE] * pcnt;
1.151     yamt     1205:        PRWORD(ovflw, " %*.0f", ((stat_sy >= 100) ? 2 : 3), 1, stat_us);
                   1206:        PRWORD(ovflw, " %*.0f", ((stat_us >= 100 || stat_id >= 100) ? 2 : 3), 1,
                   1207:            stat_sy);
                   1208:        PRWORD(ovflw, " %*.0f", 3, 1, stat_id);
                   1209:        *ovflwp = ovflw;
1.1       cgd      1210: }
                   1211:
                   1212: void
1.66      cgd      1213: dointr(int verbose)
1.1       cgd      1214: {
1.138     nonaka   1215:        unsigned long *intrcnt, *ointrcnt;
1.85      enami    1216:        unsigned long long inttotal, uptime;
1.38      mrg      1217:        int nintr, inamlen;
1.138     nonaka   1218:        char *intrname, *ointrname;
1.1       cgd      1219:
1.133     chs      1220:        inttotal = 0;
1.1       cgd      1221:        uptime = getuptime();
1.133     chs      1222:        nintr = intrnl[X_EINTRCNT].n_value - intrnl[X_INTRCNT].n_value;
                   1223:        inamlen = intrnl[X_EINTRNAMES].n_value - intrnl[X_INTRNAMES].n_value;
                   1224:        if (nintr != 0 && inamlen != 0) {
1.216     ryo      1225:                (void)printf("%-34s %16s %8s\n", "interrupt", "total", "rate");
                   1226:
1.138     nonaka   1227:                ointrcnt = intrcnt = malloc((size_t)nintr);
                   1228:                ointrname = intrname = malloc((size_t)inamlen);
1.133     chs      1229:                if (intrcnt == NULL || intrname == NULL)
                   1230:                        errx(1, "%s", "");
                   1231:                kread(intrnl, X_INTRCNT, intrcnt, (size_t)nintr);
                   1232:                kread(intrnl, X_INTRNAMES, intrname, (size_t)inamlen);
                   1233:                nintr /= sizeof(long);
                   1234:                while (--nintr >= 0) {
                   1235:                        if (*intrcnt || verbose)
                   1236:                                (void)printf("%-34s %16llu %8llu\n", intrname,
                   1237:                                             (unsigned long long)*intrcnt,
                   1238:                                             (unsigned long long)
                   1239:                                             (*intrcnt / uptime));
                   1240:                        intrname += strlen(intrname) + 1;
                   1241:                        inttotal += *intrcnt++;
                   1242:                }
1.138     nonaka   1243:                free(ointrcnt);
                   1244:                free(ointrname);
1.1       cgd      1245:        }
1.133     chs      1246:
1.176     matt     1247:        doevcnt(verbose, EVCNT_TYPE_INTR);
1.66      cgd      1248: }
                   1249:
                   1250: void
1.176     matt     1251: doevcnt(int verbose, int type)
1.66      cgd      1252: {
1.176     matt     1253:        static const char * const evtypes [] = { "misc", "intr", "trap" };
                   1254:        uint64_t counttotal, uptime;
1.66      cgd      1255:        struct evcntlist allevents;
                   1256:        struct evcnt evcnt, *evptr;
1.216     ryo      1257:        size_t evlen_max, total_max, rate_max;
1.66      cgd      1258:        char evgroup[EVCNT_STRING_MAX], evname[EVCNT_STRING_MAX];
                   1259:
1.176     matt     1260:        counttotal = 0;
1.66      cgd      1261:        uptime = getuptime();
1.176     matt     1262:
                   1263:        if (memf == NULL) do {
                   1264:                const int mib[4] = { CTL_KERN, KERN_EVCNT, type,
                   1265:                    verbose ? KERN_EVCNT_COUNT_ANY : KERN_EVCNT_COUNT_NONZERO };
1.216     ryo      1266:                size_t buflen0, buflen = 0;
                   1267:                void *buf0, *buf = NULL;
1.176     matt     1268:                const struct evcnt_sysctl *evs, *last_evs;
                   1269:                for (;;) {
                   1270:                        size_t newlen;
                   1271:                        int error;
                   1272:                        if (buflen)
                   1273:                                buf = malloc(buflen);
                   1274:                        error = sysctl(mib, __arraycount(mib),
                   1275:                            buf, &newlen, NULL, 0);
                   1276:                        if (error) {
1.193     joerg    1277:                                err(1, "kern.evcnt");
1.176     matt     1278:                                if (buf)
                   1279:                                        free(buf);
                   1280:                                return;
                   1281:                        }
                   1282:                        if (newlen <= buflen) {
                   1283:                                buflen = newlen;
                   1284:                                break;
                   1285:                        }
                   1286:                        if (buf)
                   1287:                                free(buf);
                   1288:                        buflen = newlen;
                   1289:                }
1.216     ryo      1290:                buflen0 = buflen;
                   1291:                evs = buf0 = buf;
                   1292:                last_evs = (void *)((char *)buf + buflen);
                   1293:                buflen /= sizeof(uint64_t);
                   1294:                /* calc columns */
                   1295:                evlen_max = 0;
                   1296:                total_max = sizeof("total") - 1;
                   1297:                rate_max = sizeof("rate") - 1;
                   1298:                while (evs < last_evs
                   1299:                    && buflen >= sizeof(*evs)/sizeof(uint64_t)
                   1300:                    && buflen >= evs->ev_len) {
                   1301:                        char cbuf[64];
                   1302:                        size_t len;
                   1303:                        len = strlen(evs->ev_strings + evs->ev_grouplen + 1);
                   1304:                        len += evs->ev_grouplen + 1;
                   1305:                        if (evlen_max < len)
                   1306:                                evlen_max= len;
                   1307:                        len = snprintf(cbuf, sizeof(cbuf), "%"PRIu64,
                   1308:                            evs->ev_count);
                   1309:                        if (total_max < len)
                   1310:                                total_max = len;
                   1311:                        len = snprintf(cbuf, sizeof(cbuf), "%"PRIu64,
                   1312:                            evs->ev_count / uptime);
                   1313:                        if (rate_max < len)
                   1314:                                rate_max = len;
                   1315:                        buflen -= evs->ev_len;
                   1316:                        evs = (const void *)
                   1317:                            ((const uint64_t *)evs + evs->ev_len);
                   1318:                }
                   1319:
                   1320:                (void)printf(type == EVCNT_TYPE_ANY ?
                   1321:                    "%-*s  %*s %*s %s\n" :
                   1322:                    "%-*s  %*s %*s\n",
                   1323:                    (int)evlen_max, "interrupt",
                   1324:                    (int)total_max, "total",
                   1325:                    (int)rate_max, "rate",
                   1326:                    "type");
                   1327:
                   1328:                buflen = buflen0;
                   1329:                evs = buf0;
1.176     matt     1330:                last_evs = (void *)((char *)buf + buflen);
                   1331:                buflen /= sizeof(uint64_t);
                   1332:                while (evs < last_evs
                   1333:                    && buflen >= sizeof(*evs)/sizeof(uint64_t)
                   1334:                    && buflen >= evs->ev_len) {
1.180     nakayama 1335:                        (void)printf(type == EVCNT_TYPE_ANY ?
1.216     ryo      1336:                            "%s %s%*s  %*"PRIu64" %*"PRIu64" %s\n" :
                   1337:                            "%s %s%*s  %*"PRIu64" %*"PRIu64"\n",
1.176     matt     1338:                            evs->ev_strings,
                   1339:                            evs->ev_strings + evs->ev_grouplen + 1,
1.216     ryo      1340:                            (int)evlen_max - (evs->ev_grouplen + 1
                   1341:                            + evs->ev_namelen), "",
                   1342:                            (int)total_max, evs->ev_count,
                   1343:                            (int)rate_max, evs->ev_count / uptime,
1.176     matt     1344:                            (evs->ev_type < __arraycount(evtypes) ?
1.216     ryo      1345:                            evtypes[evs->ev_type] : "?"));
1.176     matt     1346:                        buflen -= evs->ev_len;
1.180     nakayama 1347:                        counttotal += evs->ev_count;
1.216     ryo      1348:                        evs = (const void *)
                   1349:                            ((const uint64_t *)evs + evs->ev_len);
1.176     matt     1350:                }
                   1351:                free(buf);
                   1352:                if (type != EVCNT_TYPE_ANY)
1.216     ryo      1353:                        (void)printf("%-*s  %*"PRIu64" %*"PRIu64"\n",
                   1354:                            (int)evlen_max, "Total",
                   1355:                            (int)total_max, counttotal,
                   1356:                            (int)rate_max, counttotal / uptime);
1.176     matt     1357:                return;
                   1358:        } while (/*CONSTCOND*/ 0);
                   1359:
1.216     ryo      1360:        if (type == EVCNT_TYPE_ANY)
                   1361:                (void)printf("%-34s %16s %8s %s\n", "event", "total", "rate",
                   1362:                    "type");
                   1363:
1.133     chs      1364:        kread(namelist, X_ALLEVENTS, &allevents, sizeof allevents);
                   1365:        evptr = TAILQ_FIRST(&allevents);
1.66      cgd      1366:        while (evptr) {
1.87      lukem    1367:                deref_kptr(evptr, &evcnt, sizeof(evcnt), "event chain trashed");
1.32      cgd      1368:
1.133     chs      1369:                evptr = TAILQ_NEXT(&evcnt, ev_list);
1.66      cgd      1370:                if (evcnt.ev_count == 0 && !verbose)
                   1371:                        continue;
1.176     matt     1372:                if (type != EVCNT_TYPE_ANY && evcnt.ev_type != type)
                   1373:                        continue;
1.66      cgd      1374:
1.153     christos 1375:                deref_kptr(evcnt.ev_group, evgroup,
                   1376:                    (size_t)evcnt.ev_grouplen + 1, "event chain trashed");
                   1377:                deref_kptr(evcnt.ev_name, evname,
                   1378:                    (size_t)evcnt.ev_namelen + 1, "event chain trashed");
1.66      cgd      1379:
1.180     nakayama 1380:                (void)printf(type == EVCNT_TYPE_ANY ?
                   1381:                    "%s %s%*s %16"PRIu64" %8"PRIu64" %s\n" :
                   1382:                    "%s %s%*s %16"PRIu64" %8"PRIu64"\n",
1.176     matt     1383:                    evgroup, evname,
1.83      matt     1384:                    34 - (evcnt.ev_grouplen + 1 + evcnt.ev_namelen), "",
1.176     matt     1385:                    evcnt.ev_count,
                   1386:                    (evcnt.ev_count / uptime),
                   1387:                    (evcnt.ev_type < __arraycount(evtypes) ?
1.86      enami    1388:                        evtypes[evcnt.ev_type] : "?"));
1.176     matt     1389:
1.180     nakayama 1390:                counttotal += evcnt.ev_count;
1.18      pk       1391:        }
1.176     matt     1392:        if (type != EVCNT_TYPE_ANY)
                   1393:                (void)printf("%-34s %16"PRIu64" %8"PRIu64"\n",
                   1394:                    "Total", counttotal, counttotal / uptime);
1.1       cgd      1395: }
                   1396:
1.200     joerg    1397: static void
                   1398: dopool_sysctl(int verbose, int wide)
                   1399: {
                   1400:        uint64_t total, inuse, this_total, this_inuse;
                   1401:        struct {
                   1402:                uint64_t pt_nget;
                   1403:                uint64_t pt_nfail;
                   1404:                uint64_t pt_nput;
                   1405:                uint64_t pt_nout;
                   1406:                uint64_t pt_nitems;
                   1407:                uint64_t pt_npagealloc;
                   1408:                uint64_t pt_npagefree;
                   1409:                uint64_t pt_npages;
                   1410:        } pool_totals;
                   1411:        size_t i, len;
                   1412:        int name_len, ovflw;
                   1413:        struct pool_sysctl *pp, *data;
                   1414:        char in_use[8], avail[8], maxp[32];
                   1415:
                   1416:        data = asysctlbyname("kern.pool", &len);
                   1417:        if (data == NULL)
                   1418:                err(1, "failed to reead kern.pool");
                   1419:
1.202     joerg    1420:        memset(&pool_totals, 0, sizeof pool_totals);
1.200     joerg    1421:        total = inuse = 0;
                   1422:        len /= sizeof(*data);
                   1423:
                   1424:        (void)printf("Memory resource pool statistics\n");
                   1425:        (void)printf(
                   1426:            "%-*s%*s%*s%5s%*s%s%s%*s%*s%6s%s%6s%6s%6s%5s%s%s\n",
                   1427:            wide ? 16 : 11, "Name",
                   1428:            wide ? 6 : 5, "Size",
                   1429:            wide ? 12 : 9, "Requests",
                   1430:            "Fail",
                   1431:            wide ? 12 : 9, "Releases",
                   1432:            wide ? "  InUse" : "",
                   1433:            wide ? " Avail" : "",
                   1434:            wide ? 7 : 6, "Pgreq",
                   1435:            wide ? 7 : 6, "Pgrel",
                   1436:            "Npage",
                   1437:            wide ? " PageSz" : "",
                   1438:            "Hiwat",
                   1439:            "Minpg",
                   1440:            "Maxpg",
                   1441:            "Idle",
                   1442:            wide ? " Flags" : "",
                   1443:            wide ? "   Util" : "");
                   1444:
                   1445:        name_len = MIN((int)sizeof(pp->pr_wchan), wide ? 16 : 11);
                   1446:        for (i = 0; i < len; ++i) {
                   1447:                pp = &data[i];
                   1448:                if (pp->pr_nget == 0 && !verbose)
                   1449:                        continue;
                   1450:                if (pp->pr_maxpages == UINT_MAX)
                   1451:                        (void)snprintf(maxp, sizeof(maxp), "inf");
                   1452:                else
                   1453:                        (void)snprintf(maxp, sizeof(maxp), "%" PRIu64,
                   1454:                            pp->pr_maxpages);
                   1455:                ovflw = 0;
                   1456:                PRWORD(ovflw, "%-*s", name_len, 0, pp->pr_wchan);
                   1457:                PRWORD(ovflw, " %*" PRIu64, wide ? 6 : 5, 1, pp->pr_size);
                   1458:                PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nget);
                   1459:                pool_totals.pt_nget += pp->pr_nget;
                   1460:                PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_nfail);
                   1461:                pool_totals.pt_nfail += pp->pr_nfail;
                   1462:                PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nput);
                   1463:                pool_totals.pt_nput += pp->pr_nput;
                   1464:                if (wide) {
                   1465:                        PRWORD(ovflw, " %*" PRIu64, 7, 1, pp->pr_nout);
                   1466:                        pool_totals.pt_nout += pp->pr_nout;
                   1467:                }
                   1468:                if (wide) {
                   1469:                        PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_nitems);
                   1470:                        pool_totals.pt_nitems += pp->pr_nitems;
                   1471:                }
                   1472:                PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 6, 1, pp->pr_npagealloc);
                   1473:                pool_totals.pt_npagealloc += pp->pr_npagealloc;
                   1474:                PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 6, 1, pp->pr_npagefree);
                   1475:                pool_totals.pt_npagefree += pp->pr_npagefree;
                   1476:                PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_npages);
                   1477:                pool_totals.pt_npages += pp->pr_npages;
                   1478:                if (wide)
                   1479:                        PRWORD(ovflw, " %*" PRIu64, 7, 1, pp->pr_pagesize);
                   1480:                PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_hiwat);
                   1481:                PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_minpages);
                   1482:                PRWORD(ovflw, " %*s", 6, 1, maxp);
                   1483:                PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_nidle);
                   1484:                if (wide)
                   1485:                        PRWORD(ovflw, " 0x%0*" PRIx64, 4, 1,
                   1486:                            pp->pr_flags);
                   1487:
                   1488:                this_inuse = pp->pr_nout * pp->pr_size;
                   1489:                this_total = pp->pr_npages * pp->pr_pagesize;
                   1490:                if (pp->pr_flags & PR_RECURSIVE) {
                   1491:                        /*
                   1492:                         * Don't count in-use memory, since it's part
                   1493:                         * of another pool and will be accounted for
                   1494:                         * there.
                   1495:                         */
                   1496:                        total += (this_total - this_inuse);
                   1497:                } else {
                   1498:                        inuse += this_inuse;
                   1499:                        total += this_total;
                   1500:                }
                   1501:                if (wide) {
                   1502:                        if (this_total == 0)
                   1503:                                (void)printf("   ---");
                   1504:                        else
                   1505:                                (void)printf(" %5.1f%%",
                   1506:                                    (100.0 * this_inuse) / this_total);
                   1507:                }
                   1508:                (void)printf("\n");
                   1509:        }
                   1510:        if (wide) {
                   1511:                snprintf(in_use, sizeof in_use, "%7"PRId64, pool_totals.pt_nout);
                   1512:                snprintf(avail, sizeof avail, "%6"PRId64, pool_totals.pt_nitems);
                   1513:        } else {
                   1514:                in_use[0] = '\0';
                   1515:                avail[0] = '\0';
                   1516:        }
                   1517:        (void)printf(
                   1518:            "%-*s%*s%*"PRId64"%5"PRId64"%*"PRId64"%s%s%*"PRId64"%*"PRId64"%6"PRId64"\n",
                   1519:            wide ? 16 : 11, "Totals",
                   1520:            wide ? 6 : 5, "",
                   1521:            wide ? 12 : 9, pool_totals.pt_nget,
                   1522:            pool_totals.pt_nfail,
                   1523:            wide ? 12 : 9, pool_totals.pt_nput,
                   1524:            in_use,
                   1525:            avail,
                   1526:            wide ? 7 : 6, pool_totals.pt_npagealloc,
                   1527:            wide ? 7 : 6, pool_totals.pt_npagefree,
                   1528:            pool_totals.pt_npages);
                   1529:
                   1530:        inuse /= KILO;
                   1531:        total /= KILO;
                   1532:        (void)printf(
1.201     joerg    1533:            "\nIn use %" PRIu64 "K, "
                   1534:            "total allocated %" PRIu64 "K; utilization %.1f%%\n",
1.200     joerg    1535:            inuse, total, (100.0 * inuse) / total);
                   1536:
                   1537:        free(data);
                   1538: }
                   1539:
1.51      pk       1540: void
1.126     simonb   1541: dopool(int verbose, int wide)
1.51      pk       1542: {
1.69      enami    1543:        int first, ovflw;
1.87      lukem    1544:        void *addr;
1.126     simonb   1545:        long total, inuse, this_total, this_inuse;
1.189     mrg      1546:        struct {
                   1547:                uint64_t pt_nget;
                   1548:                uint64_t pt_nfail;
                   1549:                uint64_t pt_nput;
                   1550:                uint64_t pt_nout;
                   1551:                uint64_t pt_nitems;
                   1552:                uint64_t pt_npagealloc;
                   1553:                uint64_t pt_npagefree;
                   1554:                uint64_t pt_npages;
                   1555:        } pool_totals;
                   1556:        char in_use[8];
                   1557:        char avail[8];
1.157     ad       1558:        TAILQ_HEAD(,pool) pool_head;
1.51      pk       1559:        struct pool pool, *pp = &pool;
1.98      christos 1560:        struct pool_allocator pa;
1.87      lukem    1561:        char name[32], maxp[32];
1.51      pk       1562:
1.200     joerg    1563:        if (memf == NULL)
                   1564:                return dopool_sysctl(verbose, wide);
                   1565:
1.189     mrg      1566:        memset(&pool_totals, 0, sizeof pool_totals);
1.133     chs      1567:        kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head));
1.157     ad       1568:        addr = TAILQ_FIRST(&pool_head);
1.51      pk       1569:
1.126     simonb   1570:        total = inuse = 0;
                   1571:
1.157     ad       1572:        for (first = 1; addr != NULL; addr = TAILQ_NEXT(pp, pr_poollist) ) {
1.87      lukem    1573:                deref_kptr(addr, pp, sizeof(*pp), "pool chain trashed");
1.98      christos 1574:                deref_kptr(pp->pr_alloc, &pa, sizeof(pa),
1.125     dsainty  1575:                    "pool allocator trashed");
1.87      lukem    1576:                deref_kptr(pp->pr_wchan, name, sizeof(name),
1.98      christos 1577:                    "pool wait channel trashed");
1.87      lukem    1578:                name[sizeof(name)-1] = '\0';
1.51      pk       1579:
                   1580:                if (first) {
                   1581:                        (void)printf("Memory resource pool statistics\n");
                   1582:                        (void)printf(
1.126     simonb   1583:                            "%-*s%*s%*s%5s%*s%s%s%*s%*s%6s%s%6s%6s%6s%5s%s%s\n",
                   1584:                            wide ? 16 : 11, "Name",
                   1585:                            wide ? 6 : 5, "Size",
                   1586:                            wide ? 12 : 9, "Requests",
1.75      enami    1587:                            "Fail",
1.126     simonb   1588:                            wide ? 12 : 9, "Releases",
1.148     simonb   1589:                            wide ? "  InUse" : "",
1.126     simonb   1590:                            wide ? " Avail" : "",
                   1591:                            wide ? 7 : 6, "Pgreq",
                   1592:                            wide ? 7 : 6, "Pgrel",
1.75      enami    1593:                            "Npage",
1.126     simonb   1594:                            wide ? " PageSz" : "",
1.75      enami    1595:                            "Hiwat",
                   1596:                            "Minpg",
                   1597:                            "Maxpg",
1.126     simonb   1598:                            "Idle",
                   1599:                            wide ? " Flags" : "",
                   1600:                            wide ? "   Util" : "");
1.51      pk       1601:                        first = 0;
                   1602:                }
1.113     dsl      1603:                if (pp->pr_nget == 0 && !verbose)
                   1604:                        continue;
1.51      pk       1605:                if (pp->pr_maxpages == UINT_MAX)
1.153     christos 1606:                        (void)snprintf(maxp, sizeof(maxp), "inf");
1.51      pk       1607:                else
1.153     christos 1608:                        (void)snprintf(maxp, sizeof(maxp), "%u",
                   1609:                            pp->pr_maxpages);
1.69      enami    1610:                ovflw = 0;
1.126     simonb   1611:                PRWORD(ovflw, "%-*s", wide ? 16 : 11, 0, name);
                   1612:                PRWORD(ovflw, " %*u", wide ? 6 : 5, 1, pp->pr_size);
                   1613:                PRWORD(ovflw, " %*lu", wide ? 12 : 9, 1, pp->pr_nget);
1.189     mrg      1614:                pool_totals.pt_nget += pp->pr_nget;
1.69      enami    1615:                PRWORD(ovflw, " %*lu", 5, 1, pp->pr_nfail);
1.189     mrg      1616:                pool_totals.pt_nfail += pp->pr_nfail;
1.126     simonb   1617:                PRWORD(ovflw, " %*lu", wide ? 12 : 9, 1, pp->pr_nput);
1.189     mrg      1618:                pool_totals.pt_nput += pp->pr_nput;
                   1619:                if (wide) {
1.148     simonb   1620:                        PRWORD(ovflw, " %*u", 7, 1, pp->pr_nout);
1.189     mrg      1621:                        pool_totals.pt_nout += pp->pr_nout;
                   1622:                }
                   1623:                if (wide) {
1.126     simonb   1624:                        PRWORD(ovflw, " %*u", 6, 1, pp->pr_nitems);
1.189     mrg      1625:                        pool_totals.pt_nitems += pp->pr_nitems;
                   1626:                }
1.126     simonb   1627:                PRWORD(ovflw, " %*lu", wide ? 7 : 6, 1, pp->pr_npagealloc);
1.189     mrg      1628:                pool_totals.pt_npagealloc += pp->pr_npagealloc;
1.126     simonb   1629:                PRWORD(ovflw, " %*lu", wide ? 7 : 6, 1, pp->pr_npagefree);
1.189     mrg      1630:                pool_totals.pt_npagefree += pp->pr_npagefree;
1.126     simonb   1631:                PRWORD(ovflw, " %*u", 6, 1, pp->pr_npages);
1.189     mrg      1632:                pool_totals.pt_npages += pp->pr_npages;
1.126     simonb   1633:                if (wide)
                   1634:                        PRWORD(ovflw, " %*u", 7, 1, pa.pa_pagesz);
                   1635:                PRWORD(ovflw, " %*u", 6, 1, pp->pr_hiwat);
                   1636:                PRWORD(ovflw, " %*u", 6, 1, pp->pr_minpages);
1.69      enami    1637:                PRWORD(ovflw, " %*s", 6, 1, maxp);
1.126     simonb   1638:                PRWORD(ovflw, " %*lu", 5, 1, pp->pr_nidle);
                   1639:                if (wide)
                   1640:                        PRWORD(ovflw, " 0x%0*x", 4, 1,
                   1641:                            pp->pr_flags | pp->pr_roflags);
1.51      pk       1642:
1.126     simonb   1643:                this_inuse = pp->pr_nout * pp->pr_size;
                   1644:                this_total = pp->pr_npages * pa.pa_pagesz;
1.84      bjh21    1645:                if (pp->pr_roflags & PR_RECURSIVE) {
                   1646:                        /*
                   1647:                         * Don't count in-use memory, since it's part
                   1648:                         * of another pool and will be accounted for
                   1649:                         * there.
                   1650:                         */
1.126     simonb   1651:                        total += (this_total - this_inuse);
1.84      bjh21    1652:                } else {
1.126     simonb   1653:                        inuse += this_inuse;
                   1654:                        total += this_total;
1.84      bjh21    1655:                }
1.126     simonb   1656:                if (wide) {
                   1657:                        if (this_total == 0)
1.153     christos 1658:                                (void)printf("   ---");
1.126     simonb   1659:                        else
1.153     christos 1660:                                (void)printf(" %5.1f%%",
1.126     simonb   1661:                                    (100.0 * this_inuse) / this_total);
                   1662:                }
1.153     christos 1663:                (void)printf("\n");
1.51      pk       1664:        }
1.189     mrg      1665:        if (wide) {
                   1666:                snprintf(in_use, sizeof in_use, "%7"PRId64, pool_totals.pt_nout);
                   1667:                snprintf(avail, sizeof avail, "%6"PRId64, pool_totals.pt_nitems);
                   1668:        } else {
                   1669:                in_use[0] = '\0';
                   1670:                avail[0] = '\0';
                   1671:        }
                   1672:        (void)printf(
                   1673:            "%-*s%*s%*"PRId64"%5"PRId64"%*"PRId64"%s%s%*"PRId64"%*"PRId64"%6"PRId64"\n",
                   1674:            wide ? 16 : 11, "Totals",
                   1675:            wide ? 6 : 5, "",
                   1676:            wide ? 12 : 9, pool_totals.pt_nget,
                   1677:            pool_totals.pt_nfail,
                   1678:            wide ? 12 : 9, pool_totals.pt_nput,
                   1679:            in_use,
                   1680:            avail,
                   1681:            wide ? 7 : 6, pool_totals.pt_npagealloc,
                   1682:            wide ? 7 : 6, pool_totals.pt_npagefree,
                   1683:            pool_totals.pt_npages);
1.51      pk       1684:
1.152     christos 1685:        inuse /= KILO;
                   1686:        total /= KILO;
1.153     christos 1687:        (void)printf(
                   1688:            "\nIn use %ldK, total allocated %ldK; utilization %.1f%%\n",
1.126     simonb   1689:            inuse, total, (100.0 * inuse) / total);
1.1       cgd      1690: }
1.96      enami    1691:
1.200     joerg    1692: static void
                   1693: dopoolcache_sysctl(int verbose)
                   1694: {
                   1695:        struct pool_sysctl *data, *pp;
                   1696:        size_t i, len;
                   1697:        bool first = true;
                   1698:        int ovflw;
                   1699:        uint64_t tot;
1.208     christos 1700:        double p;
1.200     joerg    1701:
                   1702:        data = asysctlbyname("kern.pool", &len);
                   1703:        if (data == NULL)
                   1704:                err(1, "failed to reead kern.pool");
                   1705:        len /= sizeof(*data);
                   1706:
                   1707:        for (i = 0; i < len; ++i) {
                   1708:                pp = &data[i];
                   1709:                if (pp->pr_cache_meta_size == 0)
                   1710:                        continue;
                   1711:
                   1712:                if (pp->pr_cache_nmiss_global == 0 && !verbose)
                   1713:                        continue;
                   1714:
                   1715:                if (first) {
                   1716:                        (void)printf("Pool cache statistics.\n");
                   1717:                        (void)printf("%-*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n",
                   1718:                            12, "Name",
                   1719:                            6, "Spin",
                   1720:                            6, "GrpSz",
                   1721:                            5, "Full",
                   1722:                            5, "Emty",
                   1723:                            10, "PoolLayer",
                   1724:                            11, "CacheLayer",
                   1725:                            6, "Hit%",
                   1726:                            12, "CpuLayer",
                   1727:                            6, "Hit%"
                   1728:                        );
                   1729:                        first = false;
                   1730:                }
                   1731:
                   1732:                ovflw = 0;
                   1733:                PRWORD(ovflw, "%-*s", MIN((int)sizeof(pp->pr_wchan), 13), 1,
                   1734:                    pp->pr_wchan);
                   1735:                PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_cache_ncontended);
                   1736:                PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_cache_meta_size);
                   1737:                PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_cache_nfull);
                   1738:                PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_cache_nempty);
                   1739:                PRWORD(ovflw, " %*" PRIu64, 10, 1, pp->pr_cache_nmiss_global);
                   1740:
                   1741:                tot = pp->pr_cache_nhit_global + pp->pr_cache_nmiss_global;
                   1742:                p = pp->pr_cache_nhit_global * 100.0 / tot;
                   1743:                PRWORD(ovflw, " %*" PRIu64, 11, 1, tot);
                   1744:                PRWORD(ovflw, " %*.1f", 6, 1, p);
                   1745:
                   1746:                tot = pp->pr_cache_nhit_pcpu + pp->pr_cache_nmiss_pcpu;
                   1747:                p = pp->pr_cache_nhit_pcpu * 100.0 / tot;
                   1748:                PRWORD(ovflw, " %*" PRIu64, 12, 1, tot);
                   1749:                PRWORD(ovflw, " %*.1f", 6, 1, p);
                   1750:                printf("\n");
                   1751:        }
                   1752: }
                   1753:
1.96      enami    1754: void
1.182     yamt     1755: dopoolcache(int verbose)
1.96      enami    1756: {
                   1757:        struct pool_cache pool_cache, *pc = &pool_cache;
1.154     ad       1758:        pool_cache_cpu_t cache_cpu, *cc = &cache_cpu;
1.157     ad       1759:        TAILQ_HEAD(,pool) pool_head;
1.154     ad       1760:        struct pool pool, *pp = &pool;
                   1761:        char name[32];
                   1762:        uint64_t cpuhit, cpumiss, tot;
                   1763:        void *addr;
1.165     lukem    1764:        int first, ovflw;
                   1765:        size_t i;
1.154     ad       1766:        double p;
1.96      enami    1767:
1.200     joerg    1768:        if (memf == NULL)
                   1769:                return dopoolcache_sysctl(verbose);
                   1770:
1.154     ad       1771:        kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head));
1.157     ad       1772:        addr = TAILQ_FIRST(&pool_head);
1.96      enami    1773:
1.157     ad       1774:        for (first = 1; addr != NULL; addr = TAILQ_NEXT(pp, pr_poollist) ) {
1.154     ad       1775:                deref_kptr(addr, pp, sizeof(*pp), "pool chain trashed");
                   1776:                if (pp->pr_cache == NULL)
1.96      enami    1777:                        continue;
1.154     ad       1778:                deref_kptr(pp->pr_wchan, name, sizeof(name),
                   1779:                    "pool wait channel trashed");
                   1780:                deref_kptr(pp->pr_cache, pc, sizeof(*pc), "pool cache trashed");
1.182     yamt     1781:                if (pc->pc_misses == 0 && !verbose)
                   1782:                        continue;
1.154     ad       1783:                name[sizeof(name)-1] = '\0';
                   1784:
                   1785:                cpuhit = 0;
                   1786:                cpumiss = 0;
1.184     jym      1787:                for (i = 0; i < __arraycount(pc->pc_cpus); i++) {
1.154     ad       1788:                        if ((addr = pc->pc_cpus[i]) == NULL)
                   1789:                                continue;
                   1790:                        deref_kptr(addr, cc, sizeof(*cc),
                   1791:                            "pool cache cpu trashed");
                   1792:                        cpuhit += cc->cc_hits;
                   1793:                        cpumiss += cc->cc_misses;
1.137     chs      1794:                }
1.154     ad       1795:
                   1796:                if (first) {
                   1797:                        (void)printf("Pool cache statistics.\n");
1.156     ad       1798:                        (void)printf("%-*s%*s%*s%*s%*s%*s%*s%*s%*s%*s\n",
1.154     ad       1799:                            12, "Name",
                   1800:                            6, "Spin",
1.156     ad       1801:                            6, "GrpSz",
                   1802:                            5, "Full",
                   1803:                            5, "Emty",
                   1804:                            10, "PoolLayer",
                   1805:                            11, "CacheLayer",
1.154     ad       1806:                            6, "Hit%",
                   1807:                            12, "CpuLayer",
                   1808:                            6, "Hit%"
                   1809:                        );
                   1810:                        first = 0;
1.96      enami    1811:                }
1.154     ad       1812:
                   1813:                ovflw = 0;
                   1814:                PRWORD(ovflw, "%-*s", 13, 1, name);
                   1815:                PRWORD(ovflw, " %*llu", 6, 1, (long long)pc->pc_contended);
1.156     ad       1816:                PRWORD(ovflw, " %*u", 6, 1, pc->pc_pcgsize);
                   1817:                PRWORD(ovflw, " %*u", 5, 1, pc->pc_nfull);
                   1818:                PRWORD(ovflw, " %*u", 5, 1, pc->pc_nempty);
                   1819:                PRWORD(ovflw, " %*llu", 10, 1, (long long)pc->pc_misses);
1.154     ad       1820:
                   1821:                tot = pc->pc_hits + pc->pc_misses;
                   1822:                p = pc->pc_hits * 100.0 / (tot);
1.156     ad       1823:                PRWORD(ovflw, " %*llu", 11, 1, (long long)tot);
1.154     ad       1824:                PRWORD(ovflw, " %*.1f", 6, 1, p);
                   1825:
                   1826:                tot = cpuhit + cpumiss;
                   1827:                p = cpuhit * 100.0 / (tot);
                   1828:                PRWORD(ovflw, " %*llu", 12, 1, (long long)tot);
                   1829:                PRWORD(ovflw, " %*.1f", 6, 1, p);
                   1830:                printf("\n");
1.96      enami    1831:        }
                   1832: }
1.90      lukem    1833:
1.87      lukem    1834: enum hashtype {                        /* from <sys/systm.h> */
                   1835:        HASH_LIST,
                   1836:        HASH_TAILQ
                   1837: };
                   1838:
                   1839: struct uidinfo {               /* XXX: no kernel header file */
                   1840:        LIST_ENTRY(uidinfo) ui_hash;
                   1841:        uid_t   ui_uid;
                   1842:        long    ui_proccnt;
                   1843: };
                   1844:
                   1845: struct kernel_hash {
1.90      lukem    1846:        const char *    description;    /* description */
                   1847:        int             hashsize;       /* nlist index for hash size */
                   1848:        int             hashtbl;        /* nlist index for hash table */
                   1849:        enum hashtype   type;           /* type of hash table */
1.101     sommerfe 1850:        size_t          offset;         /* offset of {LIST,TAILQ}_NEXT */
1.87      lukem    1851: } khashes[] =
                   1852: {
                   1853:        {
1.90      lukem    1854:                "buffer hash",
                   1855:                X_BUFHASH, X_BUFHASHTBL,
                   1856:                HASH_LIST, offsetof(struct buf, b_hash)
                   1857:        }, {
                   1858:                "ipv4 address -> interface hash",
1.87      lukem    1859:                X_IFADDRHASH, X_IFADDRHASHTBL,
                   1860:                HASH_LIST, offsetof(struct in_ifaddr, ia_hash),
1.90      lukem    1861:        }, {
                   1862:                "name cache hash",
1.89      lukem    1863:                X_NCHASH, X_NCHASHTBL,
                   1864:                HASH_LIST, offsetof(struct namecache, nc_hash),
1.90      lukem    1865:        }, {
                   1866:                "name cache directory hash",
1.89      lukem    1867:                X_NCVHASH, X_NCVHASHTBL,
                   1868:                HASH_LIST, offsetof(struct namecache, nc_vhash),
1.90      lukem    1869:        }, {
                   1870:                "user info (uid -> used processes) hash",
                   1871:                X_UIHASH, X_UIHASHTBL,
                   1872:                HASH_LIST, offsetof(struct uidinfo, ui_hash),
                   1873:        }, {
                   1874:                NULL, -1, -1, 0, 0,
1.87      lukem    1875:        }
                   1876: };
                   1877:
                   1878: void
1.88      lukem    1879: dohashstat(int verbose, int todo, const char *hashname)
1.101     sommerfe 1880: {
1.87      lukem    1881:        LIST_HEAD(, generic)    *hashtbl_list;
                   1882:        TAILQ_HEAD(, generic)   *hashtbl_tailq;
                   1883:        struct kernel_hash      *curhash;
1.118     itojun   1884:        void    *hashaddr, *hashbuf, *nhashbuf, *nextaddr;
1.87      lukem    1885:        size_t  elemsize, hashbufsize, thissize;
1.165     lukem    1886:        u_long  hashsize, i;
                   1887:        int     used, items, chain, maxchain;
1.87      lukem    1888:
                   1889:        hashbuf = NULL;
                   1890:        hashbufsize = 0;
1.88      lukem    1891:
                   1892:        if (todo & HASHLIST) {
1.153     christos 1893:                (void)printf("Supported hashes:\n");
1.90      lukem    1894:                for (curhash = khashes; curhash->description; curhash++) {
1.101     sommerfe 1895:                        if (hashnl[curhash->hashsize].n_value == 0 ||
1.90      lukem    1896:                            hashnl[curhash->hashtbl].n_value == 0)
                   1897:                                continue;
1.153     christos 1898:                        (void)printf("\t%-16s%s\n",
1.90      lukem    1899:                            hashnl[curhash->hashsize].n_name + 1,
                   1900:                            curhash->description);
1.88      lukem    1901:                }
                   1902:                return;
                   1903:        }
                   1904:
                   1905:        if (hashname != NULL) {
1.90      lukem    1906:                for (curhash = khashes; curhash->description; curhash++) {
                   1907:                        if (strcmp(hashnl[curhash->hashsize].n_name + 1,
                   1908:                            hashname) == 0 &&
1.101     sommerfe 1909:                            hashnl[curhash->hashsize].n_value != 0 &&
1.90      lukem    1910:                            hashnl[curhash->hashtbl].n_value != 0)
1.88      lukem    1911:                                break;
                   1912:                }
1.90      lukem    1913:                if (curhash->description == NULL) {
                   1914:                        warnx("%s: no such hash", hashname);
                   1915:                        return;
                   1916:                }
1.88      lukem    1917:        }
                   1918:
1.153     christos 1919:        (void)printf(
1.88      lukem    1920:            "%-16s %8s %8s %8s %8s %8s %8s\n"
                   1921:            "%-16s %8s %8s %8s %8s %8s %8s\n",
                   1922:            "", "total", "used", "util", "num", "average", "maximum",
                   1923:            "hash table", "buckets", "buckets", "%", "items", "chain",
                   1924:            "chain");
1.87      lukem    1925:
1.90      lukem    1926:        for (curhash = khashes; curhash->description; curhash++) {
1.101     sommerfe 1927:                if (hashnl[curhash->hashsize].n_value == 0 ||
1.90      lukem    1928:                    hashnl[curhash->hashtbl].n_value == 0)
                   1929:                        continue;
1.88      lukem    1930:                if (hashname != NULL &&
1.90      lukem    1931:                    strcmp(hashnl[curhash->hashsize].n_name + 1, hashname))
1.88      lukem    1932:                        continue;
1.87      lukem    1933:                elemsize = curhash->type == HASH_LIST ?
                   1934:                    sizeof(*hashtbl_list) : sizeof(*hashtbl_tailq);
1.90      lukem    1935:                deref_kptr((void *)hashnl[curhash->hashsize].n_value,
                   1936:                    &hashsize, sizeof(hashsize),
                   1937:                    hashnl[curhash->hashsize].n_name);
1.87      lukem    1938:                hashsize++;
1.90      lukem    1939:                deref_kptr((void *)hashnl[curhash->hashtbl].n_value,
                   1940:                    &hashaddr, sizeof(hashaddr),
                   1941:                    hashnl[curhash->hashtbl].n_name);
1.87      lukem    1942:                if (verbose)
1.153     christos 1943:                        (void)printf(
                   1944:                            "%s %lu, %s %p, offset %ld, elemsize %llu\n",
1.90      lukem    1945:                            hashnl[curhash->hashsize].n_name + 1, hashsize,
                   1946:                            hashnl[curhash->hashtbl].n_name + 1, hashaddr,
1.101     sommerfe 1947:                            (long)curhash->offset,
1.91      jmc      1948:                            (unsigned long long)elemsize);
1.87      lukem    1949:                thissize = hashsize * elemsize;
1.144     christos 1950:                if (hashbuf == NULL || thissize > hashbufsize) {
1.118     itojun   1951:                        if ((nhashbuf = realloc(hashbuf, thissize)) == NULL)
1.101     sommerfe 1952:                                errx(1, "malloc hashbuf %llu",
1.91      jmc      1953:                                    (unsigned long long)hashbufsize);
1.118     itojun   1954:                        hashbuf = nhashbuf;
                   1955:                        hashbufsize = thissize;
1.87      lukem    1956:                }
                   1957:                deref_kptr(hashaddr, hashbuf, thissize,
1.90      lukem    1958:                    hashnl[curhash->hashtbl].n_name);
1.87      lukem    1959:                used = 0;
                   1960:                items = maxchain = 0;
1.135     lukem    1961:                if (curhash->type == HASH_LIST) {
1.87      lukem    1962:                        hashtbl_list = hashbuf;
1.135     lukem    1963:                        hashtbl_tailq = NULL;
                   1964:                } else {
                   1965:                        hashtbl_list = NULL;
1.87      lukem    1966:                        hashtbl_tailq = hashbuf;
1.135     lukem    1967:                }
1.87      lukem    1968:                for (i = 0; i < hashsize; i++) {
                   1969:                        if (curhash->type == HASH_LIST)
                   1970:                                nextaddr = LIST_FIRST(&hashtbl_list[i]);
                   1971:                        else
                   1972:                                nextaddr = TAILQ_FIRST(&hashtbl_tailq[i]);
                   1973:                        if (nextaddr == NULL)
                   1974:                                continue;
                   1975:                        if (verbose)
1.165     lukem    1976:                                (void)printf("%5lu: %p\n", i, nextaddr);
1.87      lukem    1977:                        used++;
                   1978:                        chain = 0;
                   1979:                        do {
                   1980:                                chain++;
                   1981:                                deref_kptr((char *)nextaddr + curhash->offset,
                   1982:                                    &nextaddr, sizeof(void *),
                   1983:                                    "hash chain corrupted");
                   1984:                                if (verbose > 1)
1.153     christos 1985:                                        (void)printf("got nextaddr as %p\n",
1.87      lukem    1986:                                            nextaddr);
                   1987:                        } while (nextaddr != NULL);
                   1988:                        items += chain;
                   1989:                        if (verbose && chain > 1)
1.153     christos 1990:                                (void)printf("\tchain = %d\n", chain);
1.87      lukem    1991:                        if (chain > maxchain)
                   1992:                                maxchain = chain;
                   1993:                }
1.153     christos 1994:                (void)printf("%-16s %8ld %8d %8.2f %8d %8.2f %8d\n",
1.90      lukem    1995:                    hashnl[curhash->hashsize].n_name + 1,
1.87      lukem    1996:                    hashsize, used, used * 100.0 / hashsize,
1.93      lukem    1997:                    items, used ? (double)items / used : 0.0, maxchain);
1.87      lukem    1998:        }
                   1999: }
                   2000:
1.1       cgd      2001: /*
1.147     kardel   2002:  * kreadc like kread but returns 1 if sucessful, 0 otherwise
                   2003:  */
                   2004: int
                   2005: kreadc(struct nlist *nl, int nlx, void *addr, size_t size)
                   2006: {
                   2007:        const char *sym;
                   2008:
                   2009:        sym = nl[nlx].n_name;
                   2010:        if (*sym == '_')
                   2011:                ++sym;
                   2012:        if (nl[nlx].n_type == 0 || nl[nlx].n_value == 0)
                   2013:                return 0;
                   2014:        deref_kptr((void *)nl[nlx].n_value, addr, size, sym);
                   2015:        return 1;
                   2016: }
                   2017:
                   2018: /*
1.90      lukem    2019:  * kread reads something from the kernel, given its nlist index in namelist[].
1.1       cgd      2020:  */
                   2021: void
1.133     chs      2022: kread(struct nlist *nl, int nlx, void *addr, size_t size)
1.1       cgd      2023: {
1.50      mycroft  2024:        const char *sym;
1.1       cgd      2025:
1.133     chs      2026:        sym = nl[nlx].n_name;
1.87      lukem    2027:        if (*sym == '_')
                   2028:                ++sym;
1.133     chs      2029:        if (nl[nlx].n_type == 0 || nl[nlx].n_value == 0)
1.87      lukem    2030:                errx(1, "symbol %s not defined", sym);
1.133     chs      2031:        deref_kptr((void *)nl[nlx].n_value, addr, size, sym);
1.87      lukem    2032: }
                   2033:
                   2034: /*
1.101     sommerfe 2035:  * Dereference the kernel pointer `kptr' and fill in the local copy
1.87      lukem    2036:  * pointed to by `ptr'.  The storage space must be pre-allocated,
                   2037:  * and the size of the copy passed in `len'.
                   2038:  */
                   2039: void
                   2040: deref_kptr(const void *kptr, void *ptr, size_t len, const char *msg)
                   2041: {
                   2042:
                   2043:        if (*msg == '_')
                   2044:                msg++;
1.165     lukem    2045:        if ((size_t)kvm_read(kd, (u_long)kptr, (char *)ptr, len) != len)
1.87      lukem    2046:                errx(1, "kptr %lx: %s: %s", (u_long)kptr, msg, kvm_geterr(kd));
1.1       cgd      2047: }
                   2048:
1.45      thorpej  2049: /*
1.181     mrg      2050:  * Traverse the kernel history buffers, performing the requested action.
1.45      thorpej  2051:  *
                   2052:  * Note, we assume that if we're not listing, we're dumping.
                   2053:  */
                   2054: void
1.73      simonb   2055: hist_traverse(int todo, const char *histname)
1.45      thorpej  2056: {
1.210     pgoyette 2057:        struct kern_history_head histhead;
                   2058:        struct kern_history hist, *histkva;
                   2059:        char *name = NULL;
                   2060:        size_t namelen = 0;
                   2061:
                   2062:        if (histnl[0].n_value == 0) {
                   2063:                warnx("kernel history is not compiled into the kernel.");
                   2064:                return;
                   2065:        }
                   2066:
                   2067:        deref_kptr((void *)histnl[X_KERN_HISTORIES].n_value, &histhead,
                   2068:            sizeof(histhead), histnl[X_KERN_HISTORIES].n_name);
                   2069:
                   2070:        if (histhead.lh_first == NULL) {
                   2071:                warnx("No active kernel history logs.");
                   2072:                return;
                   2073:        }
                   2074:
                   2075:        if (todo & HISTLIST)
                   2076:                (void)printf("Active kernel histories:");
                   2077:
                   2078:        for (histkva = LIST_FIRST(&histhead); histkva != NULL;
                   2079:            histkva = LIST_NEXT(&hist, list)) {
                   2080:                deref_kptr(histkva, &hist, sizeof(hist), "histkva");
                   2081:                if (name == NULL || hist.namelen > namelen) {
                   2082:                        if (name != NULL)
                   2083:                                free(name);
                   2084:                        namelen = hist.namelen;
                   2085:                        if ((name = malloc(namelen + 1)) == NULL)
                   2086:                                err(1, "malloc history name");
                   2087:                }
                   2088:
                   2089:                deref_kptr(hist.name, name, namelen, "history name");
                   2090:                name[namelen] = '\0';
                   2091:                if (todo & HISTLIST)
                   2092:                        (void)printf(" %s", name);
                   2093:                else {
                   2094:                        /*
                   2095:                         * If we're dumping all histories, do it, else
                   2096:                         * check to see if this is the one we want.
                   2097:                         */
                   2098:                        if (histname == NULL || strcmp(histname, name) == 0) {
                   2099:                                if (histname == NULL)
                   2100:                                        (void)printf(
                   2101:                                            "\nkernel history `%s':\n", name);
                   2102:                                hist_dodump(&hist);
                   2103:                        }
                   2104:                }
                   2105:        }
                   2106:
                   2107:        if (todo & HISTLIST)
                   2108:                (void)putchar('\n');
                   2109:
                   2110:        if (name != NULL)
                   2111:                free(name);
                   2112: }
                   2113:
                   2114: /*
                   2115:  * Actually dump the history buffer at the specified KVA.
                   2116:  */
                   2117: void
                   2118: hist_dodump(struct kern_history *histp)
                   2119: {
                   2120:        struct kern_history_ent *histents, *e;
1.215     pgoyette 2121:        struct timeval tv;
1.210     pgoyette 2122:        size_t histsize;
                   2123:        char *fmt = NULL, *fn = NULL;
                   2124:        size_t fmtlen = 0, fnlen = 0;
                   2125:        unsigned i;
                   2126:
                   2127:        histsize = sizeof(struct kern_history_ent) * histp->n;
                   2128:
                   2129:        if ((histents = malloc(histsize)) == NULL)
                   2130:                err(1, "malloc history entries");
                   2131:
                   2132:        (void)memset(histents, 0, histsize);
                   2133:
1.211     pgoyette 2134:        (void)printf("%"PRIu32" entries, next is %"PRIu32"\n",
                   2135:            histp->n, histp->f);
                   2136:
1.210     pgoyette 2137:        deref_kptr(histp->e, histents, histsize, "history entries");
                   2138:        i = histp->f;
                   2139:        do {
                   2140:                e = &histents[i];
                   2141:                if (e->fmt != NULL) {
                   2142:                        if (fmt == NULL || e->fmtlen > fmtlen) {
                   2143:                                if (fmt != NULL)
                   2144:                                        free(fmt);
                   2145:                                fmtlen = e->fmtlen;
                   2146:                                if ((fmt = malloc(fmtlen + 1)) == NULL)
                   2147:                                        err(1, "malloc printf format");
                   2148:                        }
                   2149:                        if (fn == NULL || e->fnlen > fnlen) {
                   2150:                                if (fn != NULL)
                   2151:                                        free(fn);
                   2152:                                fnlen = e->fnlen;
                   2153:                                if ((fn = malloc(fnlen + 1)) == NULL)
                   2154:                                        err(1, "malloc function name");
                   2155:                        }
                   2156:
                   2157:                        deref_kptr(e->fmt, fmt, fmtlen, "printf format");
                   2158:                        fmt[fmtlen] = '\0';
                   2159:
                   2160:                        deref_kptr(e->fn, fn, fnlen, "function name");
                   2161:                        fn[fnlen] = '\0';
                   2162:
1.215     pgoyette 2163:                        bintime2timeval(&e->bt, &tv);
                   2164:                        (void)printf("%06ld.%06ld ", (long int)tv.tv_sec,
                   2165:                            (long int)tv.tv_usec);
1.216.6.2! snj      2166:                        (void)printf("%s#%" PRId32 "@%" PRId32 "d: ",
        !          2167:                            fn, e->call, e->cpunum);
1.210     pgoyette 2168:                        (void)printf(fmt, e->v[0], e->v[1], e->v[2], e->v[3]);
                   2169:                        (void)putchar('\n');
                   2170:                }
                   2171:                i = (i + 1) % histp->n;
                   2172:        } while (i != histp->f);
                   2173:
                   2174:        free(histents);
                   2175:        if (fmt != NULL)
                   2176:                free(fmt);
                   2177:        if (fn != NULL)
                   2178:                free(fn);
                   2179: }
                   2180:
                   2181: void
                   2182: hist_traverse_sysctl(int todo, const char *histname)
                   2183: {
1.209     pgoyette 2184:        int error;
                   2185:        int mib[4];
                   2186:        unsigned int i;
                   2187:        size_t len, miblen;
                   2188:        struct sysctlnode query, histnode[32];
                   2189:
                   2190:        /* retrieve names of available histories */
                   2191:        miblen = __arraycount(mib);
                   2192:        error = sysctlnametomib("kern.hist", mib, &miblen);
                   2193:        if (error != 0) {
1.214     pgoyette 2194:                if (errno == ENOENT) {
                   2195:                        warnx("kernel history is not compiled into the kernel.");
                   2196:                        return;
                   2197:                } else
                   2198:                        err(EXIT_FAILURE, "nametomib failed");
1.209     pgoyette 2199:        }
1.210     pgoyette 2200:
1.209     pgoyette 2201:        /* get the list of nodenames below kern.hist */
                   2202:        mib[2] = CTL_QUERY;
                   2203:        memset(&query, 0, sizeof(query));
                   2204:        query.sysctl_flags = SYSCTL_VERSION;
                   2205:        len = sizeof(histnode);
                   2206:        error = sysctl(mib, 3, &histnode[0], &len, &query, sizeof(query));
                   2207:        if (error != 0) {
                   2208:                err(1, "query failed");
                   2209:                return;
                   2210:        }
                   2211:        if (len == 0) {
1.210     pgoyette 2212:                warnx("No active kernel history logs.");
                   2213:                return;
                   2214:        }
                   2215:
1.209     pgoyette 2216:        len = len / sizeof(histnode[0]);        /* get # of entries returned */
                   2217:
1.210     pgoyette 2218:        if (todo & HISTLIST)
                   2219:                (void)printf("Active kernel histories:");
                   2220:
1.209     pgoyette 2221:        for (i = 0; i < len; i++) {
1.210     pgoyette 2222:                if (todo & HISTLIST)
1.209     pgoyette 2223:                        (void)printf(" %s", histnode[i].sysctl_name);
1.210     pgoyette 2224:                else {
                   2225:                        /*
                   2226:                         * If we're dumping all histories, do it, else
                   2227:                         * check to see if this is the one we want.
                   2228:                         */
1.209     pgoyette 2229:                        if (histname == NULL ||
                   2230:                            strcmp(histname, histnode[i].sysctl_name) == 0) {
1.210     pgoyette 2231:                                if (histname == NULL)
                   2232:                                        (void)printf(
1.209     pgoyette 2233:                                            "\nkernel history `%s':\n",
                   2234:                                            histnode[i].sysctl_name);
                   2235:                                mib[2] = histnode[i].sysctl_num;
                   2236:                                mib[3] = CTL_EOL;
1.210     pgoyette 2237:                                hist_dodump_sysctl(mib, 4);
                   2238:                        }
                   2239:                }
                   2240:        }
                   2241:
                   2242:        if (todo & HISTLIST)
                   2243:                (void)putchar('\n');
1.216.6.2! snj      2244:        else if (mib[2] == CTL_QUERY)
        !          2245:                warnx("history %s not found", histname);
1.210     pgoyette 2246:  }
                   2247:
                   2248:  /*
                   2249:   * Actually dump the history buffer at the specified KVA.
                   2250:   */
                   2251:  void
                   2252: hist_dodump_sysctl(int mib[], unsigned int miblen)
                   2253:  {
1.209     pgoyette 2254:        struct sysctl_history *hist;
1.215     pgoyette 2255:        struct timeval tv;
1.209     pgoyette 2256:        struct sysctl_history_event *e;
1.210     pgoyette 2257:        size_t histsize;
1.209     pgoyette 2258:        char *strp;
1.210     pgoyette 2259:        unsigned i;
1.45      thorpej  2260:        char *fmt = NULL, *fn = NULL;
1.210     pgoyette 2261:
1.209     pgoyette 2262:        hist = NULL;
                   2263:        histsize = 0;
1.210     pgoyette 2264:        do {
1.209     pgoyette 2265:                errno = 0;
                   2266:                if (sysctl(mib, miblen, hist, &histsize, NULL, 0) == 0)
                   2267:                        break;
                   2268:                if (errno != ENOMEM)
                   2269:                        break;
                   2270:                if ((hist = realloc(hist, histsize)) == NULL)
                   2271:                        errx(1, "realloc history buffer");
                   2272:        } while (errno == ENOMEM);
                   2273:        if (errno != 0)
                   2274:                err(1, "sysctl failed");
1.210     pgoyette 2275:
1.216.6.2! snj      2276:        /* Make sure we've got matching versions */
        !          2277:        if (hist->sh_version != KERNHIST_SYSCTL_VERSION ||
        !          2278:            hist->sh_arglen != sizeof(uintmax_t))
        !          2279:                errx(1, "Kernel version or argument length mismatch!");
        !          2280:
        !          2281:        strp = (char *)(&hist->sh_events[hist->sh_numentries]);
1.210     pgoyette 2282:
1.209     pgoyette 2283:        (void)printf("%"PRIu32" entries, next is %"PRIu32"\n",
1.216.6.2! snj      2284:            hist->sh_numentries,
        !          2285:            hist->sh_nextfree);
1.210     pgoyette 2286:
1.216.6.2! snj      2287:        i = hist->sh_nextfree;
1.45      thorpej  2288:
                   2289:        do {
1.209     pgoyette 2290:                e = &hist->sh_events[i];
                   2291:                if (e->she_fmtoffset != 0) {
                   2292:                        fmt = &strp[e->she_fmtoffset];
                   2293:                        fn = &strp[e->she_funcoffset];
1.215     pgoyette 2294:                        bintime2timeval(&e->she_bintime, &tv);
1.216.6.2! snj      2295:                        (void)printf("%06ld.%06ld %s#%"PRIu32"@%"PRIu32": ",
1.215     pgoyette 2296:                            (long int)tv.tv_sec, (long int)tv.tv_usec,
1.213     pgoyette 2297:                            fn, e->she_callnumber, e->she_cpunum);
1.209     pgoyette 2298:                        (void)printf(fmt, e->she_values[0], e->she_values[1],
                   2299:                             e->she_values[2], e->she_values[3]);
1.210     pgoyette 2300:                        (void)putchar('\n');
                   2301:                }
1.216.6.2! snj      2302:                i = (i + 1) % hist->sh_numentries;
        !          2303:        } while (i != hist->sh_nextfree);
1.210     pgoyette 2304:
1.209     pgoyette 2305:        free(hist);
1.210     pgoyette 2306:  }
1.45      thorpej  2307:
1.183     joerg    2308: static void
1.73      simonb   2309: usage(void)
1.1       cgd      2310: {
1.47      mrg      2311:
1.1       cgd      2312:        (void)fprintf(stderr,
1.155     yamt     2313:            "usage: %s [-CefHiLlmstUvW] [-c count] [-h hashname] [-M core] [-N system]\n"
1.127     wiz      2314:            "\t\t[-u histname] [-w wait] [disks]\n", getprogname());
1.1       cgd      2315:        exit(1);
                   2316: }

CVSweb <webmaster@jp.NetBSD.org>