/* * vmstat-- report system statistics * * This version for use with the 2.9 BSD (Berkeley PDP11) system. */ #include #include #include #include #include #define TIME 5 /* number of seconds for vmrate */ #define MAXDISK 6 /* max disks that can be monitored */ struct nlist nl[] = { #define X_DKBUSY 0 "_dk_busy", 0, 0, #define X_RATE 1 "_rate", 0, 0, #define X_TOTAL 2 "_total", 0, 0, #define X_SUM 3 "_sum", 0, 0, #define X_BOOTIME 4 "_bootime", 0, 0, #define X_SYTIME 5 "_sy_time", 0, 0, #define X_DKTIME 6 "_dk_time", 0, 0, #define X_DKNUMB 7 "_dk_numb", 0, 0, #define X_NDISK 8 "_ndisk", 0, 0, "\0\0\0\0\0\0\0\0", 0, 0 }; double stat1(); struct { int busy; long sy_time[8]; long dk_time[1< 60L*60L*24L*365L*10L) { fprintf(stderr, "Time makes no sense... namelist must be wrong.\n"); exit(1); } lseek(mf, (long)nl[X_NDISK].n_value, FSEEK_ABSOLUTE); read(mf, (char *)&ndisk, sizeof ndisk); if (ndisk <= 0 || ndisk > MAXDISK) { fprintf(stderr, "Too many disks monitored (or system mismatch)\n"); exit(1); } iter = 0; argc--, argv++; while (argc>0 && argv[0][0]=='-') { char *cp = *argv++; argc--; while (*++cp) switch (*cp) { case 'z': close(mf); if (access("/dev/kmem", FACCESS_WRITE) != -1) { if ((mf = open("/dev/kmem", FATT_RDWR)) < 0) { perror("/dev/kmem"); exit(1); } lseek(mf, (long)nl[X_SUM].n_value, FSEEK_ABSOLUTE); write(mf, &sum, sizeof sum); exit(0); } else { perror("/dev/kmem"); exit(1); } case 's': dosum(); showsum++; /* exit(0);*/ break; case 'm': showmem++; break; default: fprintf(stderr, "usage: vmstat [ -sm ] [ interval ] [ count]\n"); exit(1); } } if(argc > 1) iter = atoi(argv[1]); reprint: lines = 20; if (!showmem) if (!showsum) { printf( " Procs Virtual Real Swap Disk, tps Faults/sec Cpu, %%\n"); printf( "RQ DW SW AVM TX FRE I O D0 D1 D2 D3 PD IN SY TR OV CS US NI SY ID\n"); } else exit(0); else { printf( " ----- VIRTUAL ------- ------- REAL --------- FREE\n"); printf( " VM VMTXT AVM AVMTXT RM RMT ARM ARMTXT MEM\n"); } loop: if (showmem) { domem(); goto contin; } lseek(mf, (long)nl[X_DKBUSY].n_value, FSEEK_ABSOLUTE); read(mf, (char *)&(s.busy), sizeof (s.busy)); lseek(mf, (long)nl[X_SYTIME].n_value, FSEEK_ABSOLUTE); read(mf, (char *)&(s.sy_time), sizeof (s.sy_time)); lseek(mf, (long)nl[X_DKTIME].n_value, FSEEK_ABSOLUTE); read(mf, (char *)&(s.dk_time), (1 << ndisk) * sizeof (s.dk_time[0])); lseek(mf, (long)nl[X_DKNUMB].n_value, FSEEK_ABSOLUTE); read(mf, (char *)&(s.numb), ndisk * sizeof (s.numb[0])); etime = 0; for(i=0; i < 8; i++) { t = s.sy_time[i]; s.sy_time[i] -= s1.sy_time[i]; s1.sy_time[i] = t; etime += s.sy_time[i]; } if(etime == 0.) etime = 1.; for(i=0; i < (1 << ndisk); i++) { t = s.dk_time[i]; s.dk_time[i] -= s1.dk_time[i]; s1.dk_time[i] = t; } for(i=0; i < ndisk; i++) { t = s.numb[i]; s.numb[i] -= s1.numb[i]; s1.numb[i] = t; } if (nintv != 1) { lseek(mf, (long)nl[X_SUM].n_value, FSEEK_ABSOLUTE); read(mf, &sum, sizeof sum); rate.v_swpin = sum.vs_swpin/(nintv/5); rate.v_swpout = sum.vs_swpout/(nintv/5); rate.v_intr = sum.vs_intr/nintv; rate.v_pdma = sum.vs_pdma/nintv; rate.v_trap = sum.vs_trap/nintv; rate.v_syscall = sum.vs_syscall/nintv; rate.v_ovly = sum.vs_ovly/nintv; rate.v_swtch = sum.vs_swtch/nintv; } else { lseek(mf, (long)nl[X_RATE].n_value, FSEEK_ABSOLUTE); read(mf, &rate, sizeof rate); } lseek(mf, (long)nl[X_TOTAL].n_value, FSEEK_ABSOLUTE); read(mf, &total, sizeof total); /* Procs RQ DW SW */ printf("%2d%3d%3d", total.t_rq, total.t_dw, total.t_sw); /* Memory AVM TX FRE */ printf("%6ld%3d%5d", total.t_avm/16, pct(total.t_avmtxt, total.t_avm), total.t_free); /* Swap I O */ printf("%3d%3d", rate.v_swpin, rate.v_swpout); /* Disk D0 D1 D2 D3 */ etime /= 60.; printf(" "); /* formatted for D0-D3 only; could change header above */ for(i=0; i<4; i++) stats(i); /* Faults PD IN SY TR OV */ printf("%4d%4d%4d%4d %4d", rate.v_pdma/TIME, (rate.v_intr-rate.v_trap)/TIME, rate.v_syscall/TIME, rate.v_trap/TIME, rate.v_ovly/TIME); /* context switches CS */ printf("%4d ", rate.v_swtch/TIME); /* Cpu US NI SY ID */ for(i=0; i < 8; i += 2) printf("%3.0f", stat1(i)); printf("\n"); contin: fflush(stdout); nintv = 1; --iter; if(iter) if(argc > 0) { sleep(atoi(argv[0])); if (--lines <= 0) goto reprint; goto loop; } } dosum() { lseek(mf, (long)nl[X_SUM].n_value, FSEEK_ABSOLUTE); read(mf, &sum, sizeof sum); printf("%9ld swap ins\n", sum.vs_swpin); printf("%9ld swap outs\n", sum.vs_swpout); printf("%9ld pages swapped in\n", sum.vs_pswpin / CLSIZE); printf("%9ld pages swapped out\n", sum.vs_pswpout / CLSIZE); printf("%9ld cpu context switches\n", sum.vs_swtch); printf("%9ld device interrupts\n", sum.vs_intr); printf("%9ld pseudo-DMA interrupts\n", sum.vs_pdma); printf("%9ld traps\n", sum.vs_trap); printf("%9ld system calls\n", sum.vs_syscall); printf("%9ld overlay traps\n", sum.vs_ovly); } domem() { lseek(mf, (long)nl[X_TOTAL].n_value, FSEEK_ABSOLUTE); read(mf, &total, sizeof total); printf("%6ld%6ld%6ld%6ld ", total.t_vm/16, total.t_vmtxt/16, total.t_avm/16, total.t_avmtxt/16); printf("%6d%6d%6d%6d ", total.t_rm/16, total.t_rmtxt/16, total.t_arm/16, total.t_armtxt/16); printf("%6d\n",total.t_free); } stats(dn) { if (dn >= ndisk) { printf(" 0"); return; } printf("%3.0f", s.numb[dn]/etime); } double stat1(row) { double f; f = s.sy_time[row] + s.sy_time[row+1]; return(f*100./(etime*60.)); } pct(top, bot) long top, bot; { int ret; if (bot == 0) return (0); ret = (top * 100) / bot; return ret; }