file reorg, pathnames.h, paths.h
[unix-history] / usr / src / usr.bin / vmstat / vmstat.c
index ca7f464..4611856 100644 (file)
@@ -1,32 +1,44 @@
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
 #ifndef lint
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
  All rights reserved.\n";
  All rights reserved.\n";
-#endif not lint
+#endif /* not lint */
 
 #ifndef lint
 
 #ifndef lint
-static char sccsid[] = "@(#)vmstat.c   5.4 (Berkeley) %G%";
-#endif not lint
-
-#include <stdio.h>
-#include <ctype.h>
-#include <nlist.h>
+static char sccsid[] = "@(#)vmstat.c   5.13 (Berkeley) %G%";
+#endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/vm.h>
 
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/vm.h>
-#include <sys/dk.h>
+#include <sys/dkstat.h>
 #include <sys/buf.h>
 #include <sys/dir.h>
 #include <sys/inode.h>
 #include <sys/namei.h>
 #include <sys/text.h>
 #include <sys/buf.h>
 #include <sys/dir.h>
 #include <sys/inode.h>
 #include <sys/namei.h>
 #include <sys/text.h>
+#include <sys/malloc.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <nlist.h>
+#include <paths.h>
 
 struct nlist nl[] = {
 #define        X_CPTIME        0
 
 struct nlist nl[] = {
 #define        X_CPTIME        0
@@ -71,19 +83,23 @@ struct nlist nl[] = {
        { "_dk_ndrive" },
 #define        X_XSTATS        20
        { "_xstats" },
        { "_dk_ndrive" },
 #define        X_XSTATS        20
        { "_xstats" },
+#define        X_KMEMSTAT      21
+       { "_kmemstats" },
+#define        X_KMEMBUCKETS   22
+       { "_bucket" },
 #ifdef vax
 #define X_MBDINIT      (X_XSTATS+1)
        { "_mbdinit" },
 #define X_UBDINIT      (X_XSTATS+2)
        { "_ubdinit" },
 #endif
 #ifdef vax
 #define X_MBDINIT      (X_XSTATS+1)
        { "_mbdinit" },
 #define X_UBDINIT      (X_XSTATS+2)
        { "_ubdinit" },
 #endif
-#ifdef sun
-#define X_MBDINIT      (X_XSTATS+1)
-       { "_mbdinit" },
-#endif
 #ifdef tahoe
 #define        X_VBDINIT       (X_XSTATS+1)
        { "_vbdinit" },
 #ifdef tahoe
 #define        X_VBDINIT       (X_XSTATS+1)
        { "_vbdinit" },
+#define        X_CKEYSTATS     (X_XSTATS+2)
+       { "_ckeystats" },
+#define        X_DKEYSTATS     (X_XSTATS+3)
+       { "_dkeystats" },
 #endif
        { "" },
 };
 #endif
        { "" },
 };
@@ -120,7 +136,6 @@ struct {
 #define        forkstat        s.Forkstat
 
 struct vmmeter osum;
 #define        forkstat        s.Forkstat
 
 struct vmmeter osum;
-int    zero;
 int    deficit;
 double etime;
 int    mf;
 int    deficit;
 double etime;
 int    mf;
@@ -128,25 +143,26 @@ time_t    now, boottime;
 int    printhdr();
 int    lines = 1;
 
 int    printhdr();
 int    lines = 1;
 
+#define        INTS(x) ((x) - (hz + phz))
+
 main(argc, argv)
        int argc;
        char **argv;
 {
        extern char *ctime();
 main(argc, argv)
        int argc;
        char **argv;
 {
        extern char *ctime();
-       register i,j;
+       register i;
        int iter, nintv, iflag = 0;
        int iter, nintv, iflag = 0;
-       double f1, f2;
        long t;
        long t;
-       char *arg, **cp, name[6], buf[BUFSIZ];
+       char *arg, **cp, buf[BUFSIZ];
 
 
-       nlist("/vmunix", nl);
+       nlist(_PATH_UNIX, nl);
        if(nl[0].n_type == 0) {
        if(nl[0].n_type == 0) {
-               printf("no /vmunix namelist\n");
+               fprintf(stderr, "vmstat: no %s namelist\n", _PATH_UNIX);
                exit(1);
        }
                exit(1);
        }
-       mf = open("/dev/kmem", 0);
+       mf = open(_PATH_KMEM, 0);
        if(mf < 0) {
        if(mf < 0) {
-               printf("cannot open /dev/kmem\n");
+               fprintf(stderr, "vmstat: cannot open %s\n", _PATH_KMEM);
                exit(1);
        }
        iter = 0;
                exit(1);
        }
        iter = 0;
@@ -162,7 +178,7 @@ main(argc, argv)
 
                case 'z':
                        close(mf);
 
                case 'z':
                        close(mf);
-                       mf = open("/dev/kmem", 2);
+                       mf = open(_PATH_KMEM, 2);
                        lseek(mf, (long)nl[X_SUM].n_value, L_SET);
                        write(mf, &z.Sum, sizeof z.Sum);
                        exit(0);
                        lseek(mf, (long)nl[X_SUM].n_value, L_SET);
                        write(mf, &z.Sum, sizeof z.Sum);
                        exit(0);
@@ -171,6 +187,10 @@ main(argc, argv)
                        doforkst();
                        exit(0);
                
                        doforkst();
                        exit(0);
                
+               case 'm':
+                       domem();
+                       exit(0);
+
                case 's':
                        dosum();
                        exit(0);
                case 's':
                        dosum();
                        exit(0);
@@ -181,7 +201,7 @@ main(argc, argv)
 
                default:
                        fprintf(stderr,
 
                default:
                        fprintf(stderr,
-                           "usage: vmstat [ -fsi ] [ interval ] [ count]\n");
+                           "usage: vmstat [ -fsim ] [ interval ] [ count]\n");
                        exit(1);
                }
        }
                        exit(1);
                }
        }
@@ -198,14 +218,14 @@ main(argc, argv)
                read(mf, &phz, sizeof phz);
        }
        HZ = phz ? phz : hz;
                read(mf, &phz, sizeof phz);
        }
        HZ = phz ? phz : hz;
-       if (nl[DK_NDRIVE].n_value == 0) {
-               printf("dk_ndrive undefined in system\n");
+       if (nl[X_DK_NDRIVE].n_value == 0) {
+               fprintf(stderr, "dk_ndrive undefined in system\n");
                exit(1);
        }
        lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET);
        read(mf, &dk_ndrive, sizeof (dk_ndrive));
        if (dk_ndrive <= 0) {
                exit(1);
        }
        lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET);
        read(mf, &dk_ndrive, sizeof (dk_ndrive));
        if (dk_ndrive <= 0) {
-               printf("dk_ndrive %d\n", dk_ndrive);
+               fprintf(stderr, "dk_ndrive %d\n", dk_ndrive);
                exit(1);
        }
        dr_select = (int *)calloc(dk_ndrive, sizeof (int));
                exit(1);
        }
        dr_select = (int *)calloc(dk_ndrive, sizeof (int));
@@ -223,7 +243,8 @@ main(argc, argv)
        time(&now);
        nintv = now - boottime;
        if (nintv <= 0 || nintv > 60*60*24*365*10) {
        time(&now);
        nintv = now - boottime;
        if (nintv <= 0 || nintv > 60*60*24*365*10) {
-               printf("Time makes no sense... namelist must be wrong.\n");
+               fprintf(stderr,
+                   "Time makes no sense... namelist must be wrong.\n");
                exit(1);
        }
        if (iflag) {
                exit(1);
        }
        if (iflag) {
@@ -301,7 +322,7 @@ loop:
                etime = 1.;
        printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw);
 #define pgtok(a) ((a)*NBPG/1024)
                etime = 1.;
        printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw);
 #define pgtok(a) ((a)*NBPG/1024)
-       printf("%6d%5d", pgtok(total.t_avm), pgtok(total.t_free));
+       printf("%6d%6d", pgtok(total.t_avm), pgtok(total.t_free));
        printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv,
            (rate.v_xsfrec+rate.v_xifrec)/nintv);
        printf("%4d", pgtok(rate.v_pgpgin)/nintv);
        printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv,
            (rate.v_xsfrec+rate.v_xifrec)/nintv);
        printf("%4d", pgtok(rate.v_pgpgin)/nintv);
@@ -311,7 +332,6 @@ loop:
        for (i = 0; i < dk_ndrive; i++)
                if (dr_select[i])
                        stats(i);
        for (i = 0; i < dk_ndrive; i++)
                if (dr_select[i])
                        stats(i);
-#define        INTS(x) ((x) - (hz + phz))
        printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv,
            rate.v_swtch/nintv);
        for(i=0; i<CPUSTATES; i++) {
        printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv,
            rate.v_swtch/nintv);
        for(i=0; i<CPUSTATES; i++) {
@@ -324,7 +344,6 @@ loop:
        }
        printf("\n");
        fflush(stdout);
        }
        printf("\n");
        fflush(stdout);
-contin:
        nintv = 1;
        if (--iter &&argc > 0) {
                sleep(atoi(argv[0]));
        nintv = 1;
        if (--iter &&argc > 0) {
                sleep(atoi(argv[0]));
@@ -336,7 +355,7 @@ printhdr()
 {
        register int i, j;
 
 {
        register int i, j;
 
-       printf(" procs    memory              page           ");
+       printf(" procs     memory              page           ");
        i = (ndrives * 3 - 6) / 2;
        if (i < 0)
                i = 0;
        i = (ndrives * 3 - 6) / 2;
        if (i < 0)
                i = 0;
@@ -347,7 +366,7 @@ printhdr()
        for (j = 0; j < i; j++)
                putchar(' ');
        printf("               cpu\n");
        for (j = 0; j < i; j++)
                putchar(' ');
        printf("               cpu\n");
-       printf(" r b w   avm  fre  re at  pi  po  fr  de  sr ");
+       printf(" r b w   avm   fre  re at  pi  po  fr  de  sr ");
        for (i = 0; i < dk_ndrive; i++)
                if (dr_select[i])
                        printf("%c%c ", dr_name[i][0], dr_name[i][2]);  
        for (i = 0; i < dk_ndrive; i++)
                if (dr_select[i])
                        printf("%c%c ", dr_name[i][0], dr_name[i][2]);  
@@ -371,11 +390,18 @@ dotimes()
        printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0));
 }
 
        printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0));
 }
 
+#if defined(tahoe)
+#include <tahoe/cpu.h>
+#endif
+
 dosum()
 {
        struct nchstats nchstats;
 dosum()
 {
        struct nchstats nchstats;
-       struct xstats  xstats;
+       struct xstats xstats;
        long nchtotal;
        long nchtotal;
+#if defined(tahoe)
+       struct keystats keystats;
+#endif
 
        lseek(mf, (long)nl[X_SUM].n_value, L_SET);
        read(mf, &sum, sizeof sum);
 
        lseek(mf, (long)nl[X_SUM].n_value, L_SET);
        read(mf, &sum, sizeof sum);
@@ -389,9 +415,8 @@ dosum()
        printf("%9d pages paged in\n", sum.v_pgpgin);
        printf("%9d pages paged out\n", sum.v_pgpgout);
        printf("%9d sequential process pages freed\n", sum.v_seqfree);
        printf("%9d pages paged in\n", sum.v_pgpgin);
        printf("%9d pages paged out\n", sum.v_pgpgout);
        printf("%9d sequential process pages freed\n", sum.v_seqfree);
-#define        nz(x)   ((x) ? (x) : 1)
        printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec,
        printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec,
-           (sum.v_fastpgrec * 100) / nz(sum.v_pgrec));
+           pct(sum.v_fastpgrec, sum.v_pgrec));
        printf("%9d reclaims from free list\n", sum.v_pgfrec);
        printf("%9d intransit blocking page faults\n", sum.v_intrans);
        printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE);
        printf("%9d reclaims from free list\n", sum.v_pgfrec);
        printf("%9d intransit blocking page faults\n", sum.v_intrans);
        printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE);
@@ -419,19 +444,37 @@ dosum()
            nchstats.ncs_falsehits + nchstats.ncs_miss + nchstats.ncs_long;
        printf("%9d total name lookups", nchtotal);
        printf(" (cache hits %d%% system %d%% per-process)\n",
            nchstats.ncs_falsehits + nchstats.ncs_miss + nchstats.ncs_long;
        printf("%9d total name lookups", nchtotal);
        printf(" (cache hits %d%% system %d%% per-process)\n",
-           nchstats.ncs_goodhits * 100 / nz(nchtotal),
-           nchstats.ncs_pass2 * 100 / nz(nchtotal));
+           pct(nchstats.ncs_goodhits, nchtotal),
+           pct(nchstats.ncs_pass2, nchtotal));
        printf("%9s badhits %d, falsehits %d, toolong %d\n", "",
            nchstats.ncs_badhits, nchstats.ncs_falsehits, nchstats.ncs_long);
        lseek(mf, (long)nl[X_XSTATS].n_value, 0);
        read(mf, &xstats, sizeof xstats);
        printf("%9d total calls to xalloc (cache hits %d%%)\n",
        printf("%9s badhits %d, falsehits %d, toolong %d\n", "",
            nchstats.ncs_badhits, nchstats.ncs_falsehits, nchstats.ncs_long);
        lseek(mf, (long)nl[X_XSTATS].n_value, 0);
        read(mf, &xstats, sizeof xstats);
        printf("%9d total calls to xalloc (cache hits %d%%)\n",
-           xstats.alloc, xstats.alloc_cachehit * 100 / nz(xstats.alloc));
+           xstats.alloc, pct(xstats.alloc_cachehit, xstats.alloc));
        printf("%9s sticky %d flushed %d unused %d\n", "",
            xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused);
        printf("%9d total calls to xfree", xstats.free);
        printf(" (sticky %d cached %d swapped %d)\n",
            xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap);
        printf("%9s sticky %d flushed %d unused %d\n", "",
            xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused);
        printf("%9d total calls to xfree", xstats.free);
        printf(" (sticky %d cached %d swapped %d)\n",
            xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap);
+#if defined(tahoe)
+       lseek(mf, (long)nl[X_CKEYSTATS].n_value, 0);
+       read(mf, &keystats, sizeof keystats);
+       printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
+           keystats.ks_allocs, "code cache keys allocated",
+           pct(keystats.ks_allocfree, keystats.ks_allocs),
+           pct(keystats.ks_norefs, keystats.ks_allocs),
+           pct(keystats.ks_taken, keystats.ks_allocs),
+           pct(keystats.ks_shared, keystats.ks_allocs));
+       lseek(mf, (long)nl[X_DKEYSTATS].n_value, 0);
+       read(mf, &keystats, sizeof keystats);
+       printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
+           keystats.ks_allocs, "data cache keys allocated",
+           pct(keystats.ks_allocfree, keystats.ks_allocs),
+           pct(keystats.ks_norefs, keystats.ks_allocs),
+           pct(keystats.ks_taken, keystats.ks_allocs),
+           pct(keystats.ks_shared, keystats.ks_allocs));
+#endif
 }
 
 doforkst()
 }
 
 doforkst()
@@ -509,6 +552,78 @@ dointr(nintv)
        printf("Total        %8ld %8ld\n", inttotal, inttotal / nintv);
 }
 
        printf("Total        %8ld %8ld\n", inttotal, inttotal / nintv);
 }
 
+/*
+ * These names must be kept in sync with
+ * the types defined in <sys/malloc.h>.
+ */
+char *kmemnames[] = {
+       "free",         /* 0 M_FREE */
+       "mbuf",         /* 1 M_MBUF */
+       "devbuf",       /* 2 M_DEVBUF */
+       "socket",       /* 3 M_SOCKET */
+       "pcb",          /* 4 M_PCB */
+       "routetbl",     /* 5 M_RTABLE */
+       "hosttbl",      /* 6 M_HTABLE */
+       "fragtbl",      /* 7 M_FTABLE */
+       "zombie",       /* 8 M_ZOMBIE */
+       "ifaddr",       /* 9 M_IFADDR */
+       "soopts",       /* 10 M_SOOPTS */
+       "soname",       /* 11 M_SONAME */
+       "namei",        /* 12 M_NAMEI */
+       "gprof",        /* 13 M_GPROF */
+       "ioctlops",     /* 14 M_IOCTLOPS */
+       "superblk",     /* 15 M_SUPERBLK */
+       "cred",         /* 16 M_CRED */
+       "pgrp",         /* 17 M_PGRP */
+       "session",      /* 18 M_SESSION */
+       "iov",          /* 19 M_IOV */
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0,
+       "temp",         /* 49 M_TEMP */
+};
+
+domem()
+{
+       struct kmemstats kmemstats[M_LAST];
+       struct kmembuckets buckets[MINBUCKET + 16];
+       register struct kmembuckets *kp;
+       register struct kmemstats *ks;
+       int i;
+
+       lseek(mf, (long)nl[X_KMEMBUCKETS].n_value, L_SET);
+       read(mf, buckets, sizeof buckets);
+       printf("Memory statistics by bucket size\n");
+       printf("    Size   In Use   Free   Requests  HighWater  Couldfree\n");
+       for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) {
+               if (kp->kb_calls == 0)
+                       continue;
+               printf("%8d%9d%7d%11d%8d%11d\n", 1 << i, 
+                       kp->kb_total - kp->kb_totalfree,
+                       kp->kb_totalfree, kp->kb_calls,
+                       kp->kb_highwat, kp->kb_couldfree);
+               
+       }
+       lseek(mf, (long)nl[X_KMEMSTAT].n_value, L_SET);
+       read(mf, kmemstats, sizeof kmemstats);
+       printf("Memory statistics by type\n");
+       printf("     Type   In Use  MemUse   HighUse  Limit  Requests %s\n",
+               "TypeLimit KernLimit");
+       for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
+               if (ks->ks_calls == 0)
+                       continue;
+               printf("%10s%7d%8dK%9dK%6dK%9d%7d%10d\n",
+                       kmemnames[i] ? kmemnames[i] : "undefined",
+                       ks->ks_inuse, (ks->ks_memuse + 1023) / 1024,
+                       (ks->ks_maxused + 1023) / 1024,
+                       (ks->ks_limit + 1023) / 1024, ks->ks_calls,
+                       ks->ks_limblocks, ks->ks_mapblocks);
+       }
+}
+
 #define steal(where, var) \
        lseek(mf, where, L_SET); read(mf, &var, sizeof var);
 /*
 #define steal(where, var) \
        lseek(mf, where, L_SET); read(mf, &var, sizeof var);
 /*
@@ -559,36 +674,6 @@ read_names()
 }
 #endif
 
 }
 #endif
 
-#ifdef sun
-#include <sundev/mbvar.h>
-
-read_names()
-{
-       struct mb_device mdev;
-       register struct mb_device *mp;
-       struct mb_driver mdrv;
-       short two_char;
-       char *cp = (char *) &two_char;
-
-       mp = (struct mb_device *) nl[X_MBDINIT].n_value;
-       if (mp == 0) {
-               fprintf(stderr, "vmstat: Disk init info not in namelist\n");
-               exit(1);
-       }
-       for (;;) {
-               steal(mp++, mdev);
-               if (mdev.md_driver == 0)
-                       break;
-               if (mdev.md_dk < 0 || mdev.md_alive == 0)
-                       continue;
-               steal(mdev.md_driver, mdrv);
-               steal(mdrv.mdr_dname, two_char);
-               sprintf(dr_name[mdev.md_dk], "%c%c%d",
-                    cp[0], cp[1], mdev.md_unit);
-       }
-}
-#endif
-
 #ifdef tahoe
 #include <tahoevba/vbavar.h>
 
 #ifdef tahoe
 #include <tahoevba/vbavar.h>