share read_names with vmstat(1); use kvm library, ANSI/lint
[unix-history] / usr / src / usr.sbin / iostat / iostat.c
index 22c021d..2796355 100644 (file)
@@ -12,7 +12,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)iostat.c   5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)iostat.c   5.3 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/types.h>
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -25,60 +25,55 @@ static char sccsid[] = "@(#)iostat.c        5.2 (Berkeley) %G%";
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <paths.h>
 #include <string.h>
 #include <paths.h>
+#include <kvm.h>
 
 struct nlist nl[] = {
 
 struct nlist nl[] = {
-       { "_dk_busy" },
 #define        X_DK_BUSY       0
 #define        X_DK_BUSY       0
-       { "_dk_time" },
+       { "_dk_busy" },
 #define        X_DK_TIME       1
 #define        X_DK_TIME       1
-       { "_dk_xfer" },
+       { "_dk_time" },
 #define        X_DK_XFER       2
 #define        X_DK_XFER       2
-       { "_dk_wds" },
+       { "_dk_xfer" },
 #define        X_DK_WDS        3
 #define        X_DK_WDS        3
-       { "_tk_nin" },
+       { "_dk_wds" },
 #define        X_TK_NIN        4
 #define        X_TK_NIN        4
-       { "_tk_nout" },
+       { "_tk_nin" },
 #define        X_TK_NOUT       5
 #define        X_TK_NOUT       5
-       { "_dk_seek" },
+       { "_tk_nout" },
 #define        X_DK_SEEK       6
 #define        X_DK_SEEK       6
-       { "_cp_time" },
+       { "_dk_seek" },
 #define        X_CP_TIME       7
 #define        X_CP_TIME       7
-       { "_dk_wpms" },
+       { "_cp_time" },
 #define        X_DK_WPMS       8
 #define        X_DK_WPMS       8
-       { "_hz" },
+       { "_dk_wpms" },
 #define        X_HZ            9
 #define        X_HZ            9
-       { "_phz" },
+       { "_hz" },
 #define        X_PHZ           10
 #define        X_PHZ           10
-       { "_dk_ndrive" },
+       { "_phz" },
 #define        X_DK_NDRIVE     11
 #define        X_DK_NDRIVE     11
-#ifdef vax
-       { "_mbdinit" },
-#define X_MBDINIT      (X_DK_NDRIVE+1)
-       { "_ubdinit" },
-#define X_UBDINIT      (X_DK_NDRIVE+2)
+       { "_dk_ndrive" },
+#define        X_END           11
+#ifdef hp300
+#define        X_HPDINIT       (X_END+1)
+       { "_hp_dinit" },
 #endif
 #ifdef tahoe
 #endif
 #ifdef tahoe
-#define        X_VBDINIT       (X_DK_NDRIVE+1)
+#define        X_VBDINIT       (X_END+1)
        { "_vbdinit" },
 #endif
        { "_vbdinit" },
 #endif
-       { 0 },
-};
-
-double etime;
-long *dk_wpms;
-int *dr_select;
-int dk_ndrive, hz, kmemfd, ndrives;
-char **dr_name;
-
 #ifdef vax
 #ifdef vax
-char   *defdrives[] = { "hp0", "hp1", "hp2",  0 };
-#else
-char   *defdrives[] = { 0 };
+       { "_mbdinit" },
+#define X_MBDINIT      (X_END+1)
+       { "_ubdinit" },
+#define X_UBDINIT      (X_END+2)
 #endif
 #endif
+       { 0 },
+};
 
 
-struct {
+struct _disk {
        int     dk_busy;
        long    cp_time[CPUSTATES];
        long    *dk_time;
        int     dk_busy;
        long    cp_time[CPUSTATES];
        long    *dk_time;
@@ -87,7 +82,17 @@ struct {
        long    *dk_xfer;
        long    tk_nin;
        long    tk_nout;
        long    *dk_xfer;
        long    tk_nin;
        long    tk_nout;
-} s, s1;
+} cur, last;
+
+double etime;
+long *dk_wpms;
+int dk_ndrive, *dr_select, hz, kmemfd, ndrives;
+char **dr_name;
+
+#include "names.c"                             /* XXX */
+
+#define nlread(x, v) \
+       kvm_read(nl[x].n_value, (void *)&(v), sizeof(v))
 
 main(argc, argv)
        int argc;
 
 main(argc, argv)
        int argc;
@@ -95,13 +100,14 @@ main(argc, argv)
 {
        extern int optind;
        register int i;
 {
        extern int optind;
        register int i;
-       long t;
+       long tmp;
        int ch, hdrcnt, reps, interval, phz, ndrives;
        int ch, hdrcnt, reps, interval, phz, ndrives;
-       char *arg, **cp, buf[BUFSIZ];
-       void printhdr(), read_names(), stats(), stat1(), usage();
+       char *arg, **cp, *memfile, *namelist, buf[30];
+       void printhdr(), read_names(), stats(), stat1(), usage(), error();
 
        interval = reps = 0;
 
        interval = reps = 0;
-       while ((ch = getopt(argc, argv, "c:i:")) != EOF)
+       namelist = memfile = NULL;
+       while ((ch = getopt(argc, argv, "c:i:M:N:")) != EOF)
                switch(ch) {
                case 'c':
                        reps = atoi(optarg);
                switch(ch) {
                case 'c':
                        reps = atoi(optarg);
@@ -109,6 +115,12 @@ main(argc, argv)
                case 'i':
                        interval = atoi(optarg);
                        break;
                case 'i':
                        interval = atoi(optarg);
                        break;
+               case 'M':
+                       memfile = optarg;
+                       break;
+               case 'N':
+                       namelist = optarg;
+                       break;
                case '?':
                default:
                        usage();
                case '?':
                default:
                        usage();
@@ -116,40 +128,36 @@ main(argc, argv)
        argc -= optind;
        argv += optind;
 
        argc -= optind;
        argv += optind;
 
-       nlist(_PATH_UNIX, nl);
-       if (nl[X_DK_BUSY].n_type == 0) {
-               (void)fprintf(stderr,
-                   "iostat: dk_busy not found in %s namelist\n",
-                   _PATH_UNIX);
+       if (kvm_openfiles(namelist, memfile, NULL) == -1) {
+               error("kvm_openfiles: %s", kvm_geterr());
                exit(1);
        }
                exit(1);
        }
-       kmemfd = open(_PATH_KMEM, O_RDONLY);
-       if (kmemfd < 0) {
-               (void)fprintf(stderr, "iostat: cannot open %s\n", _PATH_KMEM);
+       if (kvm_nlist(nl) == -1) {
+               error("kvm_nlist: %s", kvm_geterr());
                exit(1);
        }
                exit(1);
        }
-
-       if (nl[X_DK_NDRIVE].n_value == 0) {
-               (void)fprintf(stderr,
-                   "iostat: dk_ndrive not found in %s namelist\n",
-                   _PATH_UNIX);
+       if (nl[X_DK_BUSY].n_type == 0) {
+               error("dk_busy not found namelist");
                exit(1);
        }
                exit(1);
        }
-       (void)lseek(kmemfd, nl[X_DK_NDRIVE].n_value, L_SET);
-       (void)read(kmemfd, &dk_ndrive, sizeof(dk_ndrive));
+       if (nl[X_DK_NDRIVE].n_type == 0) {
+               error("dk_ndrive not found in namelist");
+               exit(1);
+       }
+       (void)nlread(X_DK_NDRIVE, dk_ndrive);
        if (dk_ndrive <= 0) {
        if (dk_ndrive <= 0) {
-               (void)fprintf(stderr, "iostat: dk_ndrive %d\n", dk_ndrive);
+               error("invalid dk_ndrive %d\n", dk_ndrive);
                exit(1);
        }
 
                exit(1);
        }
 
-       s.dk_time = calloc(dk_ndrive, sizeof(long));
-       s.dk_wds = calloc(dk_ndrive, sizeof(long));
-       s.dk_seek = calloc(dk_ndrive, sizeof(long));
-       s.dk_xfer = calloc(dk_ndrive, sizeof(long));
-       s1.dk_time = calloc(dk_ndrive, sizeof(long));
-       s1.dk_wds = calloc(dk_ndrive, sizeof(long));
-       s1.dk_seek = calloc(dk_ndrive, sizeof(long));
-       s1.dk_xfer = calloc(dk_ndrive, sizeof(long));
+       cur.dk_time = calloc(dk_ndrive, sizeof(long));
+       cur.dk_wds = calloc(dk_ndrive, sizeof(long));
+       cur.dk_seek = calloc(dk_ndrive, sizeof(long));
+       cur.dk_xfer = calloc(dk_ndrive, sizeof(long));
+       last.dk_time = calloc(dk_ndrive, sizeof(long));
+       last.dk_wds = calloc(dk_ndrive, sizeof(long));
+       last.dk_seek = calloc(dk_ndrive, sizeof(long));
+       last.dk_xfer = calloc(dk_ndrive, sizeof(long));
        dr_select = calloc(dk_ndrive, sizeof(int));
        dr_name = calloc(dk_ndrive, sizeof(char *));
        dk_wpms = calloc(dk_ndrive, sizeof(long));
        dr_select = calloc(dk_ndrive, sizeof(int));
        dr_name = calloc(dk_ndrive, sizeof(char *));
        dk_wpms = calloc(dk_ndrive, sizeof(long));
@@ -160,14 +168,12 @@ main(argc, argv)
                arg += strlen(dr_name[i]) + 1;
        }
        read_names();
                arg += strlen(dr_name[i]) + 1;
        }
        read_names();
-       (void)lseek(kmemfd, (long)nl[X_HZ].n_value, L_SET);
-       (void)read(kmemfd, &hz, sizeof(hz));
-       (void)lseek(kmemfd, (long)nl[X_PHZ].n_value, L_SET);
-       (void)read(kmemfd, &phz, sizeof(phz));
+       (void)nlread(X_HZ, hz);
+       (void)nlread(X_PHZ, phz);
        if (phz)
                hz = phz;
        if (phz)
                hz = phz;
-       (void)lseek(kmemfd, (long)nl[X_DK_WPMS].n_value, L_SET);
-       (void)read(kmemfd, dk_wpms, dk_ndrive * sizeof(dk_wpms));
+       (void)kvm_read(nl[X_DK_WPMS].n_value, dk_wpms,
+               dk_ndrive * sizeof(dk_wpms));
 
        /*
         * Choose drives to be displayed.  Priority goes to (in order) drives
 
        /*
         * Choose drives to be displayed.  Priority goes to (in order) drives
@@ -222,46 +228,46 @@ main(argc, argv)
                        printhdr();
                        hdrcnt = 20;
                }
                        printhdr();
                        hdrcnt = 20;
                }
-               (void)lseek(kmemfd, (long)nl[X_DK_BUSY].n_value, L_SET);
-               (void)read(kmemfd, &s.dk_busy, sizeof(s.dk_busy));
-               (void)lseek(kmemfd, (long)nl[X_DK_TIME].n_value, L_SET);
-               (void)read(kmemfd, s.dk_time, dk_ndrive * sizeof(long));
-               (void)lseek(kmemfd, (long)nl[X_DK_XFER].n_value, L_SET);
-               (void)read(kmemfd, s.dk_xfer, dk_ndrive * sizeof(long));
-               (void)lseek(kmemfd, (long)nl[X_DK_WDS].n_value, L_SET);
-               (void)read(kmemfd, s.dk_wds, dk_ndrive * sizeof(long));
-               (void)lseek(kmemfd, (long)nl[X_DK_SEEK].n_value, L_SET);
-               (void)read(kmemfd, s.dk_seek, dk_ndrive * sizeof(long));
-               (void)lseek(kmemfd, (long)nl[X_TK_NIN].n_value, L_SET);
-               (void)read(kmemfd, &s.tk_nin, sizeof(s.tk_nin));
-               (void)lseek(kmemfd, (long)nl[X_TK_NOUT].n_value, L_SET);
-               (void)read(kmemfd, &s.tk_nout, sizeof(s.tk_nout));
-               (void)lseek(kmemfd, (long)nl[X_CP_TIME].n_value, L_SET);
-               (void)read(kmemfd, s.cp_time, sizeof(s.cp_time));
+               (void)nlread(X_DK_BUSY, cur.dk_busy);
+               (void)kvm_read(nl[X_DK_TIME].n_value,
+                   cur.dk_time, dk_ndrive * sizeof(long));
+               (void)kvm_read(nl[X_DK_XFER].n_value,
+                   cur.dk_xfer, dk_ndrive * sizeof(long));
+               (void)kvm_read(nl[X_DK_WDS].n_value,
+                   cur.dk_wds, dk_ndrive * sizeof(long));
+               (void)kvm_read(nl[X_DK_SEEK].n_value,
+                   cur.dk_seek, dk_ndrive * sizeof(long));
+               (void)kvm_read(nl[X_TK_NIN].n_value,
+                   &cur.tk_nin, sizeof(cur.tk_nin));
+               (void)kvm_read(nl[X_TK_NOUT].n_value,
+                   &cur.tk_nout, sizeof(cur.tk_nout));
+               (void)kvm_read(nl[X_CP_TIME].n_value,
+                   cur.cp_time, sizeof(cur.cp_time));
                for (i = 0; i < dk_ndrive; i++) {
                        if (!dr_select[i])
                                continue;
                for (i = 0; i < dk_ndrive; i++) {
                        if (!dr_select[i])
                                continue;
-#define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
+#define X(fld) tmp = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = tmp
                        X(dk_xfer);
                        X(dk_seek);
                        X(dk_wds);
                        X(dk_time);
                }
                        X(dk_xfer);
                        X(dk_seek);
                        X(dk_wds);
                        X(dk_time);
                }
-               t = s.tk_nin;
-               s.tk_nin -= s1.tk_nin;
-               s1.tk_nin = t;
-               t = s.tk_nout;
-               s.tk_nout -= s1.tk_nout;
-               s1.tk_nout = t;
+               tmp = cur.tk_nin;
+               cur.tk_nin -= last.tk_nin;
+               last.tk_nin = tmp;
+               tmp = cur.tk_nout;
+               cur.tk_nout -= last.tk_nout;
+               last.tk_nout = tmp;
                etime = 0;
                for (i = 0; i < CPUSTATES; i++) {
                        X(cp_time);
                etime = 0;
                for (i = 0; i < CPUSTATES; i++) {
                        X(cp_time);
-                       etime += s.cp_time[i];
+                       etime += cur.cp_time[i];
                }
                if (etime == 0.0)
                        etime = 1.0;
                }
                if (etime == 0.0)
                        etime = 1.0;
-               etime /= (float) hz;
-               (void)printf("%4.0f%5.0f", s.tk_nin / etime, s.tk_nout / etime);
+               etime /= (float)hz;
+               (void)printf("%4.0f%5.0f",
+                   cur.tk_nin / etime, cur.tk_nout / etime);
                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);
@@ -304,9 +310,9 @@ stats(dn)
                (void)printf("%4.0f%4.0f%5.1f ", 0.0, 0.0, 0.0);
                return;
        }
                (void)printf("%4.0f%4.0f%5.1f ", 0.0, 0.0, 0.0);
                return;
        }
-       atime = s.dk_time[dn];
+       atime = cur.dk_time[dn];
        atime /= (float)hz;
        atime /= (float)hz;
-       words = s.dk_wds[dn] * 32.0;    /* number of words transferred */
+       words = cur.dk_wds[dn] * 32.0;  /* number of words transferred */
        xtime = words / dk_wpms[dn];    /* transfer time */
        itime = atime - xtime;          /* time not transferring */
        if (xtime < 0)
        xtime = words / dk_wpms[dn];    /* transfer time */
        itime = atime - xtime;          /* time not transferring */
        if (xtime < 0)
@@ -314,9 +320,9 @@ stats(dn)
        if (itime < 0)
                xtime += itime, itime = 0;
        (void)printf("%4.0f", words / 512 / etime);
        if (itime < 0)
                xtime += itime, itime = 0;
        (void)printf("%4.0f", words / 512 / etime);
-       (void)printf("%4.0f", s.dk_xfer[dn] / etime);
+       (void)printf("%4.0f", cur.dk_xfer[dn] / etime);
        (void)printf("%5.1f ",
        (void)printf("%5.1f ",
-           s.dk_seek[dn] ? itime * 1000. / s.dk_seek[dn] : 0.0);
+           cur.dk_seek[dn] ? itime * 1000. / cur.dk_seek[dn] : 0.0);
 }
 
 void
 }
 
 void
@@ -328,98 +334,29 @@ stat1(state)
 
        time = 0;
        for (i = 0; i < CPUSTATES; i++)
 
        time = 0;
        for (i = 0; i < CPUSTATES; i++)
-               time += s.cp_time[i];
+               time += cur.cp_time[i];
        if (time == 0.0)
                time = 1.0;
        if (time == 0.0)
                time = 1.0;
-       (void)printf("%3.0f", 100. * s.cp_time[state] / time);
+       (void)printf("%3.0f", 100. * cur.cp_time[state] / time);
 }
 
 void
 usage()
 {
        (void)fprintf(stderr,
 }
 
 void
 usage()
 {
        (void)fprintf(stderr,
-           "usage: iostat [-c count] [-i interval] [drives]\n");
+"usage: iostat [-c count] [-i interval] [-M core] [-N system] [drives]\n");
        exit(1);
 }
 
        exit(1);
 }
 
-#define        steal(where, var) \
-       (void)lseek(kmemfd, (where), L_SET); \
-       (void)read(kmemfd, &var, sizeof(var));
-
-#ifdef vax
-#include <vax/uba/ubavar.h>
-#include <vax/mba/mbavar.h>
-
 void
 void
-read_names()
+error(fmt)
+       char *fmt;
 {
 {
-       struct mba_device mdev;
-       register struct mba_device *mp;
-       struct mba_driver mdrv;
-       short two_char;
-       char *cp = (char *) &two_char;
-       struct uba_device udev, *up;
-       struct uba_driver udrv;
+       va_list ap;
 
 
-       mp = (struct mba_device *) nl[X_MBDINIT].n_value;
-       up = (struct uba_device *) nl[X_UBDINIT].n_value;
-       if (up == 0) {
-               (void)fprintf(stderr,
-                   "iostat: disk init info not in namelist\n");
-               exit(1);
-       }
-       if (mp) for (;;) {
-               steal(mp++, mdev);
-               if (mdev.mi_driver == 0)
-                       break;
-               if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
-                       continue;
-               steal(mdev.mi_driver, mdrv);
-               steal(mdrv.md_dname, two_char);
-               (void)sprintf(dr_name[mdev.mi_dk], "%c%c%d",
-                   cp[0], cp[1], mdev.mi_unit);
-       }
-       if (up) for (;;) {
-               steal(up++, udev);
-               if (udev.ui_driver == 0)
-                       break;
-               if (udev.ui_dk < 0 || udev.ui_alive == 0)
-                       continue;
-               steal(udev.ui_driver, udrv);
-               steal(udrv.ud_dname, two_char);
-               (void)sprintf(dr_name[udev.ui_dk], "%c%c%d",
-                   cp[0], cp[1], udev.ui_unit);
-       }
-}
-#endif /* vax */
-
-#ifdef tahoe
-#include <tahoe/vba/vbavar.h>
-
-void
-read_names()
-{
-       struct vba_device udev, *up;
-       struct vba_driver udrv;
-       short two_char;
-       char *cp = (char *)&two_char;
-
-       up = (struct vba_device *)nl[X_VBDINIT].n_value;
-       if (up == 0) {
-               (void)fprintf(stderr,
-                   "iostat: disk init info not in namelist\n");
-               exit(1);
-       }
-       for (;;) {
-               steal(up++, udev);
-               if (udev.ui_driver == 0)
-                       break;
-               if (udev.ui_dk < 0 || udev.ui_alive == 0)
-                       continue;
-               steal(udev.ui_driver, udrv);
-               steal(udrv.ud_dname, two_char);
-               (void)sprintf(dr_name[udev.ui_dk], "%c%c%d",
-                    cp[0], cp[1], udev.ui_unit);
-       }
+        va_start(ap, fmt);
+        (void)fprintf(stderr, "iostat: ");
+        (void)vfprintf(stderr, fmt, ap);
+        (void)fprintf(stderr, "\n");
+        va_end(ap);
 }
 }
-#endif /* tahoe */