1*9249Ssam static char *sccsid = "@(#)vmstat.c 4.8 (Berkeley) 11/15/82"; 21155Sbill #include <stdio.h> 31155Sbill #include <sys/param.h> 41155Sbill #include <sys/vm.h> 51155Sbill #include <sys/dk.h> 61155Sbill #include <nlist.h> 73162Stoy #include <sys/buf.h> 8*9249Ssam #include <vaxuba/ubavar.h> 9*9249Ssam #include <vaxmba/mbavar.h> 101155Sbill 111155Sbill struct nlist nl[] = { 121448Sbill #define X_CPTIME 0 131448Sbill { "_cp_time" }, 141448Sbill #define X_RATE 1 151155Sbill { "_rate" }, 161448Sbill #define X_TOTAL 2 171155Sbill { "_total" }, 181448Sbill #define X_DEFICIT 3 191155Sbill { "_deficit" }, 201448Sbill #define X_FORKSTAT 4 211155Sbill { "_forkstat" }, 221448Sbill #define X_SUM 5 231155Sbill { "_sum" }, 241448Sbill #define X_FIRSTFREE 6 251155Sbill { "_firstfree" }, 261448Sbill #define X_MAXFREE 7 271155Sbill { "_maxfree" }, 28*9249Ssam #define X_BOOTTIME 8 29*9249Ssam { "_boottime" }, 301448Sbill #define X_DKXFER 9 311448Sbill { "_dk_xfer" }, 323162Stoy #define X_MBDINIT 10 333162Stoy { "_mbdinit" }, 343162Stoy #define X_UBDINIT 11 353162Stoy { "_ubdinit" }, 363162Stoy #define X_REC 12 371155Sbill { "_rectime" }, 383162Stoy #define X_PGIN 13 391155Sbill { "_pgintime" }, 403162Stoy #define X_HZ 14 413162Stoy { "_hz" }, 421155Sbill { 0 }, 431155Sbill }; 441155Sbill 453162Stoy char dr_name[DK_NDRIVE][10]; 463162Stoy char dr_unit[DK_NDRIVE]; 471155Sbill double stat1(); 481155Sbill int firstfree, maxfree; 493162Stoy int hz; 501155Sbill struct 511155Sbill { 521155Sbill int busy; 531448Sbill long time[CPUSTATES]; 541448Sbill long xfer[DK_NDRIVE]; 551155Sbill struct vmmeter Rate; 561155Sbill struct vmtotal Total; 571155Sbill struct vmmeter Sum; 581155Sbill struct forkstat Forkstat; 591155Sbill unsigned rectime; 601155Sbill unsigned pgintime; 611155Sbill } s, s1, z; 621155Sbill #define rate s.Rate 631155Sbill #define total s.Total 641155Sbill #define sum s.Sum 651155Sbill #define forkstat s.Forkstat 661155Sbill 671155Sbill int zero; 681155Sbill int deficit; 691155Sbill double etime; 701155Sbill int mf; 711155Sbill 721155Sbill main(argc, argv) 731155Sbill char **argv; 741155Sbill { 751155Sbill time_t now; 761155Sbill int lines; 771155Sbill extern char *ctime(); 781155Sbill register i,j; 791155Sbill int iter, nintv; 80*9249Ssam time_t boottime; 811155Sbill double f1, f2; 821155Sbill long t; 831155Sbill extern char _sobuf[]; 841155Sbill 851155Sbill setbuf(stdout, _sobuf); 861155Sbill nlist("/vmunix", nl); 871155Sbill if(nl[0].n_type == 0) { 881155Sbill printf("no /vmunix namelist\n"); 891155Sbill exit(1); 901155Sbill } 911155Sbill mf = open("/dev/kmem", 0); 921155Sbill if(mf < 0) { 931155Sbill printf("cannot open /dev/kmem\n"); 941155Sbill exit(1); 951155Sbill } 961155Sbill iter = 0; 971155Sbill argc--, argv++; 981155Sbill while (argc>0 && argv[0][0]=='-') { 991155Sbill char *cp = *argv++; 1001155Sbill argc--; 1011155Sbill while (*++cp) switch (*cp) { 1021155Sbill 1031155Sbill case 't': 1041155Sbill dotimes(); 1051155Sbill exit(0); 1061155Sbill case 'z': 1071155Sbill close(mf); 1081155Sbill mf = open("/dev/kmem", 2); 1091155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 1101155Sbill write(mf, &z.Sum, sizeof z.Sum); 1111155Sbill exit(0); 1121155Sbill 1131155Sbill case 'f': 1141155Sbill doforkst(); 1151155Sbill exit(0); 1161155Sbill 1171155Sbill case 's': 1181155Sbill dosum(); 1191155Sbill exit(0); 1201155Sbill 1211155Sbill default: 1221155Sbill fprintf(stderr, "usage: vmstat [ -fs ] [ interval ] [ count]\n"); 1231155Sbill exit(1); 1241155Sbill } 1251155Sbill } 1261155Sbill if(argc > 1) 1271155Sbill iter = atoi(argv[1]); 1281155Sbill lseek(mf, (long)nl[X_FIRSTFREE].n_value, 0); 1291155Sbill read(mf, &firstfree, sizeof firstfree); 1301155Sbill lseek(mf, (long)nl[X_MAXFREE].n_value, 0); 1311155Sbill read(mf, &maxfree, sizeof maxfree); 132*9249Ssam lseek(mf, (long)nl[X_BOOTTIME].n_value, 0); 133*9249Ssam read(mf, &boottime, sizeof boottime); 1343162Stoy lseek(mf, (long)nl[X_HZ].n_value, 0); 1353162Stoy read(mf, &hz, sizeof hz); 1363612Sroot for (i = 0; i < DK_NDRIVE; i++) { 1373212Swnj strcpy(dr_name[i], "xx"); 1383162Stoy dr_unit[i] = i; 1393162Stoy } 1403162Stoy read_names(); 1411155Sbill time(&now); 142*9249Ssam nintv = now - boottime; 1431155Sbill if (nintv <= 0 || nintv > 60*60*24*365*10) { 1441155Sbill printf("Time makes no sense... namelist must be wrong.\n"); 1451155Sbill exit(1); 1461155Sbill } 1471155Sbill reprint: 1481155Sbill lines = 20; 1491155Sbill /* s1 = z; */ 1501155Sbill printf("\ 1513612Sroot procs memory page disk faults cpu\n\ 1523612Sroot r b w avm fre re at pi po fr de sr %c%d %c%d %c%d %c%d in sy cs us sy id\n\ 1533212Swnj ", dr_name[0][0], dr_unit[0], dr_name[1][0], dr_unit[1], dr_name[2][0], dr_unit[2], dr_name[3][0], dr_unit[3]); 1541155Sbill loop: 1551448Sbill lseek(mf, (long)nl[X_CPTIME].n_value, 0); 1561448Sbill read(mf, s.time, sizeof s.time); 1571448Sbill lseek(mf, (long)nl[X_DKXFER].n_value, 0); 1581448Sbill read(mf, s.xfer, sizeof s.xfer); 1591155Sbill if (nintv != 1) { 1601155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 1611155Sbill read(mf, &rate, sizeof rate); 1621155Sbill } else { 1631155Sbill lseek(mf, (long)nl[X_RATE].n_value, 0); 1641155Sbill read(mf, &rate, sizeof rate); 1651155Sbill } 1661155Sbill lseek(mf, (long)nl[X_TOTAL].n_value, 0); 1671155Sbill read(mf, &total, sizeof total); 1681155Sbill lseek(mf, (long)nl[X_DEFICIT].n_value, 0); 1691155Sbill read(mf, &deficit, sizeof deficit); 1701448Sbill etime = 0; 1711155Sbill for (i=0; i < DK_NDRIVE; i++) { 1721448Sbill t = s.xfer[i]; 1731448Sbill s.xfer[i] -= s1.xfer[i]; 1741448Sbill s1.xfer[i] = t; 1751155Sbill } 1761155Sbill for (i=0; i < CPUSTATES; i++) { 1771448Sbill t = s.time[i]; 1781448Sbill s.time[i] -= s1.time[i]; 1791448Sbill s1.time[i] = t; 1801448Sbill etime += s.time[i]; 1811155Sbill } 1821155Sbill if(etime == 0.) 1831155Sbill etime = 1.; 1843162Stoy printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw); 1853162Stoy printf("%6d%5d", total.t_avm/2, total.t_free/2); 1863612Sroot printf("%4d%3d%4d", 1871155Sbill (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, 1883612Sroot (rate.v_xsfrec+rate.v_xifrec)/nintv, rate.v_pgpgin/2/nintv); 1893612Sroot printf("%4d%4d%4d%4d", rate.v_pgpgout/2/nintv, 1903612Sroot rate.v_dfree/2/nintv, deficit/2, rate.v_scan/nintv); 1911155Sbill etime /= 60.; 1921155Sbill for(i=0; i<4; i++) 1931155Sbill stats(i); 1943162Stoy printf("%4d%4d", (rate.v_intr/nintv) - hz, rate.v_syscall/nintv); 1951155Sbill printf("%4d", rate.v_swtch/nintv); 1961155Sbill for(i=0; i<CPUSTATES; i++) { 1971155Sbill float f = stat1(i); 1981155Sbill if (i == 0) { /* US+NI */ 1991155Sbill i++; 2001155Sbill f += stat1(i); 2011155Sbill } 2021155Sbill printf("%3.0f", f); 2031155Sbill } 2041155Sbill printf("\n"); 2051155Sbill fflush(stdout); 2061155Sbill contin: 2071155Sbill nintv = 1; 2081155Sbill --iter; 2091155Sbill if(iter) 2101155Sbill if(argc > 0) { 2111155Sbill sleep(atoi(argv[0])); 2121155Sbill if (--lines <= 0) 2131155Sbill goto reprint; 2141155Sbill goto loop; 2151155Sbill } 2161155Sbill } 2171155Sbill 2181155Sbill dotimes() 2191155Sbill { 2201155Sbill 2211155Sbill lseek(mf, (long)nl[X_REC].n_value, 0); 2221155Sbill read(mf, &s.rectime, sizeof s.rectime); 2231155Sbill lseek(mf, (long)nl[X_PGIN].n_value, 0); 2241155Sbill read(mf, &s.pgintime, sizeof s.pgintime); 2251155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 2261155Sbill read(mf, &sum, sizeof sum); 2271155Sbill printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); 2281155Sbill printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); 2291155Sbill printf("\n"); 2301155Sbill printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); 2311155Sbill printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); 2321155Sbill } 2331155Sbill 2341155Sbill dosum() 2351155Sbill { 2361155Sbill 2371155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 2381155Sbill read(mf, &sum, sizeof sum); 2391155Sbill printf("%9d swap ins\n", sum.v_swpin); 2401155Sbill printf("%9d swap outs\n", sum.v_swpout); 2411155Sbill printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); 2421155Sbill printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); 2431155Sbill printf("%9d total address trans. faults taken\n", sum.v_faults); 2441155Sbill printf("%9d page ins\n", sum.v_pgin); 2451155Sbill printf("%9d page outs\n", sum.v_pgout); 2463612Sroot printf("%9d pages paged in\n", sum.v_pgpgin); 2473612Sroot printf("%9d pages paged out\n", sum.v_pgpgout); 2483612Sroot printf("%9d sequential process pages freed\n", sum.v_seqfree); 2491155Sbill printf("%9d total reclaims\n", sum.v_pgrec); 2501155Sbill printf("%9d reclaims from free list\n", sum.v_pgfrec); 2511155Sbill printf("%9d intransit blocking page faults\n", sum.v_intrans); 2521155Sbill printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); 2531155Sbill printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); 2541155Sbill printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); 2551155Sbill printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); 2561155Sbill printf("%9d swap text pages found in free list\n", sum.v_xsfrec); 2571155Sbill printf("%9d inode text pages found in free list\n", sum.v_xifrec); 2581155Sbill printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); 2591155Sbill printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); 2601155Sbill printf("%9d pages examined by the clock daemon\n", sum.v_scan); 2611155Sbill printf("%9d revolutions of the clock hand\n", sum.v_rev); 2621155Sbill printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); 2631155Sbill printf("%9d cpu context switches\n", sum.v_swtch); 2641155Sbill printf("%9d device interrupts\n", sum.v_intr); 2651155Sbill printf("%9d pseduo-dma dz interrupts\n", sum.v_pdma); 2661155Sbill printf("%9d traps\n", sum.v_trap); 2671155Sbill printf("%9d system calls\n", sum.v_syscall); 2681155Sbill } 2691155Sbill 2701155Sbill 2711155Sbill doforkst() 2721155Sbill { 2731155Sbill 2741155Sbill lseek(mf, (long)nl[X_FORKSTAT].n_value, 0); 2751155Sbill read(mf, &forkstat, sizeof forkstat); 2761155Sbill printf("%d forks, %d pages, average=%.2f\n", 2771155Sbill forkstat.cntfork, forkstat.sizfork, 2781155Sbill (float) forkstat.sizfork / forkstat.cntfork); 2791155Sbill printf("%d vforks, %d pages, average=%.2f\n", 2801155Sbill forkstat.cntvfork, forkstat.sizvfork, 2811155Sbill (float)forkstat.sizvfork / forkstat.cntvfork); 2821155Sbill } 2831155Sbill 2841155Sbill stats(dn) 2851155Sbill { 2861155Sbill 2871155Sbill if (dn >= DK_NDRIVE) { 2881155Sbill printf(" 0"); 2891155Sbill return; 2901155Sbill } 2911448Sbill printf("%3.0f", s.xfer[dn]/etime); 2921155Sbill } 2931155Sbill 2941155Sbill double 2951155Sbill stat1(row) 2961155Sbill { 2971448Sbill double t; 2981448Sbill register i; 2991155Sbill 3001155Sbill t = 0; 3011155Sbill for(i=0; i<CPUSTATES; i++) 3021448Sbill t += s.time[i]; 3031448Sbill if(t == 0.) 3041448Sbill t = 1.; 3051448Sbill return(s.time[row]*100./t); 3061155Sbill } 3071155Sbill 3081155Sbill pct(top, bot) 3091155Sbill { 3101155Sbill 3111155Sbill if (bot == 0) 3121155Sbill return (0); 3131155Sbill return ((top * 100) / bot); 3141155Sbill } 3153162Stoy 3163162Stoy /* 3173162Stoy * Read the drive names out of kmem. 3183162Stoy * ARGH ARGH ARGH ARGH !!!!!!!!!!!! 3193162Stoy */ 3203162Stoy 3213162Stoy #define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var); 3223162Stoy read_names() 3233162Stoy { 3243162Stoy struct mba_device mdev; 3253162Stoy register struct mba_device *mp; 3263162Stoy struct mba_driver mdrv; 3273162Stoy short two_char; 3283162Stoy char *cp = (char *) &two_char; 3293162Stoy struct uba_device udev, *up; 3303162Stoy struct uba_driver udrv; 3313162Stoy 3323162Stoy mp = (struct mba_device *) nl[X_MBDINIT].n_value; 3333162Stoy up = (struct uba_device *) nl[X_UBDINIT].n_value; 3343492Sroot if (up == 0) { 3353162Stoy fprintf(stderr, "iostat: Disk init info not in namelist\n"); 3363162Stoy exit(1); 3373162Stoy } 3383492Sroot if (mp) for (;;) { 3393162Stoy steal(mp++, mdev); 3403162Stoy if (mdev.mi_driver == 0) 3413162Stoy break; 3423162Stoy if (mdev.mi_dk < 0 || mdev.mi_alive == 0) 3433162Stoy continue; 3443162Stoy steal(mdev.mi_driver, mdrv); 3453162Stoy steal(mdrv.md_dname, two_char); 3463162Stoy sprintf(dr_name[mdev.mi_dk], "%c%c", cp[0], cp[1]); 3473162Stoy dr_unit[mdev.mi_dk] = mdev.mi_unit; 3483162Stoy } 3493492Sroot for (;;) { 3503162Stoy steal(up++, udev); 3513162Stoy if (udev.ui_driver == 0) 3523162Stoy break; 3533162Stoy if (udev.ui_dk < 0 || udev.ui_alive == 0) 3543162Stoy continue; 3553162Stoy steal(udev.ui_driver, udrv); 3563162Stoy steal(udrv.ud_dname, two_char); 3573162Stoy sprintf(dr_name[udev.ui_dk], "%c%c", cp[0], cp[1]); 3583162Stoy dr_unit[udev.ui_dk] = udev.ui_unit; 3593162Stoy } 3603162Stoy } 361