static char *sccsid = "@(#)iostat.c 4.6 (Berkeley) 81/04/21"; /* * iostat */ #include <stdio.h> #include <nlist.h> #include <sys/types.h> #include <sys/buf.h> #include <sys/ubavar.h> #include <sys/mbavar.h> #include <sys/dk.h> struct nlist nl[] = { { "_dk_busy" }, #define X_DK_BUSY 0 { "_dk_time" }, #define X_DK_TIME 1 { "_dk_xfer" }, #define X_DK_XFER 2 { "_dk_wds" }, #define X_DK_WDS 3 { "_tk_nin" }, #define X_TK_NIN 4 { "_tk_nout" }, #define X_TK_NOUT 5 { "_dk_seek" }, #define X_DK_SEEK 6 { "_cp_time" }, #define X_CP_TIME 7 { "_dk_mspw" }, #define X_DK_MSPW 8 { "_mbdinit" }, #define X_MBDINIT 9 { "_ubdinit" }, #define X_UBDINIT 10 { 0 }, }; char dr_name[DK_NDRIVE][10]; struct { int dk_busy; long cp_time[CPUSTATES]; long dk_time[DK_NDRIVE]; long dk_wds[DK_NDRIVE]; long dk_seek[DK_NDRIVE]; long dk_xfer[DK_NDRIVE]; float dk_mspw[DK_NDRIVE]; long tk_nin; long tk_nout; } s, s1; int mf; double etime; main(argc, argv) char *argv[]; { extern char *ctime(); register i; int iter; double f1, f2; long t; int tohdr = 1; nlist("/unix", nl); if(nl[X_DK_BUSY].n_type == 0) { printf("dk_busy not found in /unix namelist\n"); exit(1); } mf = open("/dev/kmem", 0); if(mf < 0) { printf("cannot open /dev/kmem\n"); exit(1); } iter = 0; while (argc>1&&argv[1][0]=='-') { argc--; argv++; } lseek(mf, (long)nl[X_DK_MSPW].n_value, 0); read(mf, s.dk_mspw, sizeof s.dk_mspw); for (i = 0; i < DK_NDRIVE; i++) sprintf(dr_name[i], "dk%d", i); read_names(); if(argc > 2) iter = atoi(argv[2]); loop: if (--tohdr == 0) { printf(" tty"); for (i = 0; i < DK_NDRIVE; i++) if (s.dk_mspw[i] != 0.0) printf(" %3.3s ", dr_name[i]); printf(" cpu\n"); printf(" tin tout"); for (i = 0; i < DK_NDRIVE; i++) if (s.dk_mspw[i] != 0.0) printf(" sps tps msps "); printf(" us ni sy id\n"); tohdr = 19; } lseek(mf, (long)nl[X_DK_BUSY].n_value, 0); read(mf, &s.dk_busy, sizeof s.dk_busy); lseek(mf, (long)nl[X_DK_TIME].n_value, 0); read(mf, s.dk_time, sizeof s.dk_time); lseek(mf, (long)nl[X_DK_XFER].n_value, 0); read(mf, s.dk_xfer, sizeof s.dk_xfer); lseek(mf, (long)nl[X_DK_WDS].n_value, 0); read(mf, s.dk_wds, sizeof s.dk_wds); lseek(mf, (long)nl[X_TK_NIN].n_value, 0); read(mf, &s.tk_nin, sizeof s.tk_nin); lseek(mf, (long)nl[X_TK_NOUT].n_value, 0); read(mf, &s.tk_nout, sizeof s.tk_nout); lseek(mf, (long)nl[X_DK_SEEK].n_value, 0); read(mf, s.dk_seek, sizeof s.dk_seek); lseek(mf, (long)nl[X_CP_TIME].n_value, 0); read(mf, s.cp_time, sizeof s.cp_time); lseek(mf, (long)nl[X_DK_MSPW].n_value, 0); read(mf, s.dk_mspw, sizeof s.dk_mspw); for (i = 0; i < DK_NDRIVE; i++) { #define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t 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; etime = 0; for(i=0; i<CPUSTATES; i++) { X(cp_time); etime += s.cp_time[i]; } if (etime == 0.0) etime = 1.0; etime /= 60.0; printf("%4.0f%5.0f", s.tk_nin/etime, s.tk_nout/etime); for (i=0; i<DK_NDRIVE; i++) if (s.dk_mspw[i] != 0.0) stats(i); for (i=0; i<CPUSTATES; i++) stat1(i); printf("\n"); contin: --iter; if(iter) if(argc > 1) { sleep(atoi(argv[1])); goto loop; } } stats(dn) { register i; double atime, words, xtime, itime; if (s.dk_mspw[dn] == 0.0) { printf("%4.0f%4.0f%5.1f ", 0.0, 0.0, 0.0); return; } atime = s.dk_time[dn]; atime /= 60.0; words = s.dk_wds[dn]*32.0; /* number of words transferred */ xtime = s.dk_mspw[dn]*words; /* transfer time */ itime = atime - xtime; /* time not transferring */ /* printf("\ndn %d, words %8.2f, atime %6.2f, xtime %6.2f, itime %6.2f\n", dn, words, atime, xtime, itime); */ if (xtime < 0) itime += xtime, xtime = 0; if (itime < 0) xtime += itime, itime = 0; printf("%4.0f", s.dk_seek[dn]/etime); printf("%4.0f", s.dk_xfer[dn]/etime); printf("%5.1f ", s.dk_seek[dn] ? itime*1000./s.dk_seek[dn] : 0.0); /* printf("%4.1f", s.dk_xfer[dn] ? xtime*1000./s.dk_xfer[dn] : 0.0); */ } stat1(o) { register i; double time; time = 0; for(i=0; i<CPUSTATES; i++) time += s.cp_time[i]; if (time == 0.0) time = 1.0; printf("%3.0f", 100*s.cp_time[o]/time); } /* * Read the drive names out of kmem. * ARGH ARGH ARGH ARGH !!!!!!!!!!!! */ #define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var); read_names() { 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; mp = (struct mba_device *) nl[X_MBDINIT].n_value; up = (struct uba_device *) nl[X_UBDINIT].n_value; if (up == 0) { fprintf(stderr, "iostat: Disk init info not in namelist\n"); exit(1); } if (mp) while(1) { 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); sprintf(dr_name[mdev.mi_dk], "%c%c%d", cp[0], cp[1], mdev.mi_unit); } while(1) { 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); sprintf(dr_name[udev.ui_dk], "%c%c%d", cp[0], cp[1], udev.ui_unit); } }