|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)vmstat.c 4.11 (Berkeley) 9/25/83"; ! 3: #endif ! 4: ! 5: #include <curses.h> ! 6: #include <signal.h> ! 7: #include <stdio.h> ! 8: #include <sys/param.h> ! 9: #include <sys/vm.h> ! 10: #include <sys/dk.h> ! 11: #include <nlist.h> ! 12: #include <sys/buf.h> ! 13: #include <vba/vbavar.h> ! 14: #include <vba/vddc.h> ! 15: ! 16: struct nlist nli[] = { ! 17: #define X_CPTIME 0 ! 18: { "_cp_time" }, ! 19: #define X_RATE 1 ! 20: { "_rate" }, ! 21: #define X_TOTAL 2 ! 22: { "_total" }, ! 23: #define X_DEFICIT 3 ! 24: { "_deficit" }, ! 25: #define X_FORKSTAT 4 ! 26: { "_forkstat" }, ! 27: #define X_SUM 5 ! 28: { "_sum" }, ! 29: #define X_FIRSTFREE 6 ! 30: { "_firstfree" }, ! 31: #define X_MAXFREE 7 ! 32: { "_maxfree" }, ! 33: #define X_BOOTTIME 8 ! 34: { "_boottime" }, ! 35: #define X_DKXFER 9 ! 36: { "_dk_xfer" }, ! 37: #define X_VBDINIT 10 ! 38: { "_vbdinit" }, ! 39: #define X_REC 11 ! 40: { "_rectime" }, ! 41: #define X_PGIN 12 ! 42: { "_pgintime" }, ! 43: #define X_HZ 13 ! 44: { "_hz" }, ! 45: #define X_NVDDRV 14 ! 46: { "_nvddrv" }, ! 47: #define X_VDST 15 ! 48: { "_vdst" }, ! 49: { "" }, ! 50: }; ! 51: ! 52: #define UNIX "/vmunix" ! 53: char dr_name[DK_NDRIVE][10]; ! 54: double stat1(); ! 55: int firstfree, maxfree; ! 56: int hz; ! 57: int nodktyp; ! 58: struct ! 59: { ! 60: int busy; ! 61: long time[CPUSTATES]; ! 62: long xfer[DK_NDRIVE]; ! 63: struct vmmeter Rate; ! 64: struct vmtotal Total; ! 65: struct vmmeter Sum; ! 66: struct forkstat Forkstat; ! 67: unsigned rectime; ! 68: unsigned pgintime; ! 69: } s, s1, z; ! 70: #define rate s.Rate ! 71: #define total s.Total ! 72: #define sum s.Sum ! 73: #define forkstat s.Forkstat ! 74: #define MAXRPT 10 ! 75: #define NCOLS 80 ! 76: #define NLINES 24 ! 77: ! 78: struct vmmeter osum; ! 79: int zero; ! 80: int deficit; ! 81: double etime; ! 82: int mf; ! 83: int swflag; ! 84: float f; ! 85: int iter,count,repcnt; ! 86: ! 87: fs_tab *vdinfo, *vdinfo_save; ! 88: long name; ! 89: ! 90: struct ! 91: { ! 92: int r; ! 93: int b; ! 94: int w; ! 95: int avm; ! 96: int fre; ! 97: int pgre; ! 98: int pgat; ! 99: int pi; ! 100: int po; ! 101: int fr; ! 102: int de; ! 103: int sr; ! 104: float dk[DK_NDRIVE]; ! 105: int in; ! 106: int sy; ! 107: int cs; ! 108: float syste[(CPUSTATES-1)]; ! 109: /* ! 110: int us; ! 111: int sy; ! 112: int id; ! 113: */ ! 114: } rec[MAXRPT]; ! 115: ! 116: extern char *malloc(); ! 117: ! 118: main(argc, argv) ! 119: int argc; ! 120: char **argv; ! 121: { ! 122: extern char *ctime(); ! 123: register i,j; ! 124: int nintv; ! 125: int totrep; ! 126: time_t boottime; ! 127: double f1, f2; ! 128: long t; ! 129: extern char _sobuf[]; ! 130: int die(); ! 131: int ptoutput(); ! 132: int shiftarray(); ! 133: int dietty(); ! 134: int TERM; ! 135: time_t now; ! 136: ! 137: TERM = isatty(1); ! 138: setbuf(stdout, _sobuf); ! 139: nlist(UNIX, nli); ! 140: if(nli[0].n_value == 0) { ! 141: printf("no %s namelist\n",UNIX); ! 142: exit(1); ! 143: } ! 144: mf = open("/dev/kmem", 0); ! 145: if(mf < 0) { ! 146: printf("cannot open /dev/kmem\n"); ! 147: exit(1); ! 148: } ! 149: iter = 0; ! 150: argc--, argv++; ! 151: while (argc>0 && argv[0][0]=='-') { ! 152: char *cp = *argv++; ! 153: argc--; ! 154: while (*++cp) switch (*cp) { ! 155: ! 156: case 'S': ! 157: swflag = 1 - swflag; ! 158: break; ! 159: ! 160: ! 161: case 't': ! 162: dotimes(); ! 163: exit(0); ! 164: ! 165: case 'z': ! 166: close(mf); ! 167: mf = open("/dev/kmem", 2); ! 168: lseek(mf, (long)nli[X_SUM].n_value, 0); ! 169: write(mf, &z.Sum, sizeof z.Sum); ! 170: exit(0); ! 171: ! 172: case 'f': ! 173: doforkst(); ! 174: exit(0); ! 175: ! 176: case 's': ! 177: dosum(); ! 178: exit(0); ! 179: ! 180: default: ! 181: fprintf(stderr, "usage: vmstat [ -fs ] [ interval ] [ count]\n"); ! 182: exit(1); ! 183: } ! 184: } ! 185: totrep = 1; ! 186: if(argc > 1) ! 187: totrep = atoi(argv[1]); ! 188: if(argc ==1) ! 189: totrep = -1; ! 190: iter = 0; ! 191: if ((totrep <0 ) || (totrep > MAXRPT)) ! 192: repcnt = MAXRPT; ! 193: else ! 194: repcnt = totrep; ! 195: lseek(mf, (long)nli[X_FIRSTFREE].n_value, 0); ! 196: read(mf, &firstfree, sizeof firstfree); ! 197: lseek(mf, (long)nli[X_MAXFREE].n_value, 0); ! 198: read(mf, &maxfree, sizeof maxfree); ! 199: lseek(mf, (long)nli[X_BOOTTIME].n_value, 0); ! 200: read(mf, &boottime, sizeof boottime); ! 201: lseek(mf, (long)nli[X_HZ].n_value, 0); ! 202: read(mf, &hz, sizeof hz); ! 203: lseek(mf, (long)nli[X_NVDDRV].n_value, 0); ! 204: read(mf, &nodktyp, sizeof nodktyp); ! 205: vdinfo = (fs_tab *)malloc(nodktyp*sizeof(fs_tab)); ! 206: lseek(mf, (long)nli[X_VDST].n_value, 0); ! 207: read(mf, (char *)vdinfo, nodktyp*sizeof(fs_tab)); ! 208: vdinfo_save = vdinfo; ! 209: for (i = 0; i < nodktyp; vdinfo++, i++) { ! 210: name = (long)vdinfo->type_name; ! 211: vdinfo->type_name = malloc(3); ! 212: lseek(mf, (long)name, 0); ! 213: read(mf, vdinfo->type_name, 3); ! 214: } ! 215: vdinfo = vdinfo_save; ! 216: for (i = 0; i < DK_NDRIVE; i++) ! 217: sprintf(dr_name[i],"??%x",i); ! 218: read_names(); ! 219: time(&now); ! 220: nintv = now - boottime; ! 221: if (nintv <= 0 || nintv > 60*60*24*365*10) { ! 222: printf("Time makes no sense... namelist must be wrong.\n"); ! 223: exit(1); ! 224: } ! 225: if (TERM){ ! 226: initscr(); ! 227: signal(SIGINT,dietty); ! 228: nonl(); ! 229: crmode(); ! 230: noecho(); ! 231: leaveok(stdscr,TRUE); ! 232: scrollok(stdscr,FALSE); ! 233: } ! 234: else ! 235: signal(SIGINT,die); ! 236: reprint: ! 237: loop: ! 238: lseek(mf, (long)nli[X_CPTIME].n_value, 0); ! 239: read(mf, s.time, sizeof s.time); ! 240: lseek(mf, (long)nli[X_DKXFER].n_value, 0); ! 241: read(mf, s.xfer, sizeof s.xfer); ! 242: if (nintv != 1) { ! 243: lseek(mf, (long)nli[X_SUM].n_value, 0); ! 244: read(mf, &rate, sizeof rate); ! 245: } else { ! 246: lseek(mf, (long)nli[X_RATE].n_value, 0); ! 247: read(mf, &rate, sizeof rate); ! 248: } ! 249: lseek(mf, (long)nli[X_TOTAL].n_value, 0); ! 250: read(mf, &total, sizeof total); ! 251: osum = sum; ! 252: lseek(mf, (long)nli[X_SUM].n_value, 0); ! 253: read(mf, &sum, sizeof sum); ! 254: lseek(mf, (long)nli[X_DEFICIT].n_value, 0); ! 255: read(mf, &deficit, sizeof deficit); ! 256: etime = 0; ! 257: for (i=0; i < DK_NDRIVE; i++) { ! 258: t = s.xfer[i]; ! 259: s.xfer[i] -= s1.xfer[i]; ! 260: s1.xfer[i] = t; ! 261: } ! 262: for (i=0; i < CPUSTATES; i++) { ! 263: t = s.time[i]; ! 264: s.time[i] -= s1.time[i]; ! 265: s1.time[i] = t; ! 266: etime += s.time[i]; ! 267: } ! 268: if(etime == 0.) ! 269: etime = 1.; ! 270: rec[iter].r = total.t_rq; ! 271: rec[iter].b = total.t_dw+total.t_pw; ! 272: rec[iter].w = total.t_sw; ! 273: rec[iter].avm= total.t_avm; ! 274: rec[iter].fre = total.t_free; ! 275: if(swflag){ ! 276: rec[iter].pgre= sum.v_swpin-osum.v_swpin ; ! 277: rec[iter].pgat = sum.v_swpout-osum.v_swpout ; ! 278: } ! 279: else { ! 280: ! 281: rec[iter].pgre = (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv; ! 282: rec[iter].pgat = (rate.v_xsfrec+rate.v_xifrec)/nintv; ! 283: } ! 284: rec[iter].pi = rate.v_pgpgin/nintv; ! 285: rec[iter].po= rate.v_pgpgout/nintv; ! 286: rec[iter].fr= rate.v_dfree/nintv; ! 287: rec[iter].de = deficit; ! 288: rec[iter].sr = rate.v_scan/nintv; ! 289: etime /= (float) hz; ! 290: for(i=0; i < DK_NDRIVE; i++){ ! 291: rec[iter].dk[i] = s.xfer[i]/etime; ! 292: } ! 293: rec[iter].in= (rate.v_intr/nintv) - hz; ! 294: rec[iter].sy = rate.v_syscall/nintv; ! 295: rec[iter].cs = rate.v_swtch/nintv; ! 296: for(i=0; i<CPUSTATES; i++) { ! 297: f = stat1(i); ! 298: if (i == 0) { /* US+NI */ ! 299: i++; ! 300: f += stat1(i); ! 301: } ! 302: rec[iter].syste[i-1] = f; ! 303: } ! 304: nintv = 1; ! 305: count++; ! 306: if (count >= MAXRPT) ! 307: if ( (count % MAXRPT) == 0) ! 308: if(TERM == 0) ! 309: ptoutput(iter+1); ! 310: if(TERM) ! 311: { ! 312: printw("mem[avm fre] pag[%5s pi po fr de sr] fault[in sy cs] cpu[us sy id]\n", swflag ? "si so" : "re at"); ! 313: for(i=0; i < (iter+1); i++){ ! 314: printw("%7d%7d %4d%3d%4d%4d%4d%4d%4d %5d%4d%4d ", ! 315: rec[i].avm,rec[i].fre, rec[i].pgre,rec[i].pgat, ! 316: rec[i].pi,rec[i].po,rec[i].fr, rec[i].de,rec[i].sr, ! 317: rec[i].in,rec[i].sy,rec[i].cs); ! 318: for(j=0; j<( CPUSTATES -1); j++) ! 319: printw("%3.0f",rec[i].syste[j]); ! 320: printw("\n"); ! 321: } ! 322: for(i=(iter+1); i<repcnt; i++) ! 323: printw("\n"); ! 324: printw("proc[r b w]Dsk["); ! 325: for (i=0; i < DK_NDRIVE; i++) ! 326: if(dr_name[i][0] !='?') ! 327: printw("%3.3s ",dr_name[i]); ! 328: printw("]\n"); ! 329: for(i=0; i < (iter+1); i++){ ! 330: printw(" %2d%2d%2d ",rec[i].r,rec[i].b,rec[i].w); ! 331: for(j=0; j<DK_NDRIVE; j++) ! 332: if(dr_name[j][0] !='?') ! 333: printw("%3.0f ",rec[i].dk[j]); ! 334: printw("\n"); ! 335: } ! 336: for (i=(iter+1); i< repcnt; i++) ! 337: printw("\n"); ! 338: refresh(); ! 339: move(0,0); ! 340: } ! 341: if (totrep > 0) ! 342: totrep--; ! 343: iter++; ! 344: if (count >= MAXRPT ){ ! 345: for(i=0; i < (MAXRPT -1); i++){ ! 346: shiftarray(i,1); ! 347: } ! 348: iter = MAXRPT-1; ! 349: } ! 350: ! 351: if (totrep != 0){ ! 352: if(argc > 0) { ! 353: sleep(atoi(argv[0])); ! 354: goto loop; ! 355: } ! 356: } ! 357: if(TERM) ! 358: dietty(); ! 359: else { ! 360: die(); ! 361: } ! 362: } ! 363: ! 364: dotimes() ! 365: { ! 366: ! 367: lseek(mf, (long)nli[X_REC].n_value, 0); ! 368: read(mf, &s.rectime, sizeof s.rectime); ! 369: lseek(mf, (long)nli[X_PGIN].n_value, 0); ! 370: read(mf, &s.pgintime, sizeof s.pgintime); ! 371: lseek(mf, (long)nli[X_SUM].n_value, 0); ! 372: read(mf, &sum, sizeof sum); ! 373: printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); ! 374: printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); ! 375: printf("\n"); ! 376: printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); ! 377: printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); ! 378: } ! 379: ! 380: dosum() ! 381: { ! 382: ! 383: lseek(mf, (long)nli[X_SUM].n_value, 0); ! 384: read(mf, &sum, sizeof sum); ! 385: printf("%9d swap ins\n", sum.v_swpin); ! 386: printf("%9d swap outs\n", sum.v_swpout); ! 387: printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); ! 388: printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); ! 389: printf("%9d total address trans. faults taken\n", sum.v_faults); ! 390: printf("%9d page ins\n", sum.v_pgin); ! 391: printf("%9d page outs\n", sum.v_pgout); ! 392: printf("%9d pages paged in\n", sum.v_pgpgin); ! 393: printf("%9d pages paged out\n", sum.v_pgpgout); ! 394: printf("%9d sequential process pages freed\n", sum.v_seqfree); ! 395: printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec, ! 396: (sum.v_fastpgrec * 100) / (sum.v_pgrec == 0 ? 1 : sum.v_pgrec)); ! 397: printf("%9d reclaims from free list\n", sum.v_pgfrec); ! 398: printf("%9d intransit blocking page faults\n", sum.v_intrans); ! 399: printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); ! 400: printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); ! 401: printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); ! 402: printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); ! 403: printf("%9d swap text pages found in free list\n", sum.v_xsfrec); ! 404: printf("%9d inode text pages found in free list\n", sum.v_xifrec); ! 405: printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); ! 406: printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); ! 407: printf("%9d pages examined by the clock daemon\n", sum.v_scan); ! 408: printf("%9d revolutions of the clock hand\n", sum.v_rev); ! 409: printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); ! 410: printf("%9d cpu context switches\n", sum.v_swtch); ! 411: printf("%9d device interrupts\n", sum.v_intr); ! 412: printf("%9d pseduo-dma dz interrupts\n", sum.v_pdma); ! 413: printf("%9d traps\n", sum.v_trap); ! 414: printf("%9d system calls\n", sum.v_syscall); ! 415: } ! 416: ! 417: doforkst() ! 418: { ! 419: ! 420: lseek(mf, (long)nli[X_FORKSTAT].n_value, 0); ! 421: read(mf, &forkstat, sizeof forkstat); ! 422: printf("%d forks, %d pages, average=%.2f\n", ! 423: forkstat.cntfork, forkstat.sizfork, ! 424: (float) forkstat.sizfork / forkstat.cntfork); ! 425: printf("%d vforks, %d pages, average=%.2f\n", ! 426: forkstat.cntvfork, forkstat.sizvfork, ! 427: (float)forkstat.sizvfork / forkstat.cntvfork); ! 428: } ! 429: ! 430: stats(dn) ! 431: { ! 432: ! 433: if (dn >= DK_NDRIVE) { ! 434: printf(" 0"); ! 435: return; ! 436: } ! 437: printf("%3.0f", s.xfer[dn]/etime); ! 438: } ! 439: ! 440: double ! 441: stat1(row) ! 442: { ! 443: double t; ! 444: register i; ! 445: ! 446: t = 0; ! 447: for(i=0; i<CPUSTATES; i++) ! 448: t += s.time[i]; ! 449: if(t == 0.) ! 450: t = 1.; ! 451: return(s.time[row]*100./t); ! 452: } ! 453: ! 454: pct(top, bot) ! 455: { ! 456: ! 457: if (bot == 0) ! 458: return (0); ! 459: return ((top * 100) / bot); ! 460: } ! 461: ! 462: #define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var); ! 463: ! 464: read_names() ! 465: { ! 466: struct vba_device udev, *up; ! 467: struct vba_driver udrv; ! 468: int unit, i; ! 469: ! 470: up = (struct vba_device *) nli[X_VBDINIT].n_value; ! 471: if (up == 0) ! 472: { ! 473: fprintf(stderr, "vmstat: Disk init info not in namelist\n"); ! 474: exit(1); ! 475: } ! 476: vdinfo_save = vdinfo; ! 477: for (;;) { ! 478: steal(up++, udev); ! 479: unit = (udev.ui_ctlr * 4) + udev.ui_slave; ! 480: if (udev.ui_driver == 0) ! 481: break; ! 482: if (udev.ui_dk <= 0 || udev.ui_alive == 0) ! 483: continue; ! 484: if(udev.ui_type >= nodktyp){ ! 485: fprintf(stderr,"vmstat : disk type in unit %d not supported \n",unit); ! 486: exit(1); ! 487: } ! 488: vdinfo = vdinfo_save; ! 489: for(i=0; i < udev.ui_type; i++) ! 490: vdinfo++; ! 491: dr_name[unit][0] = vdinfo->type_name[0]; ! 492: dr_name[unit][1] = vdinfo->type_name[1]; ! 493: } ! 494: } ! 495: die() ! 496: { ! 497: int i,j,k; ! 498: iter--; ! 499: signal(SIGINT,SIG_IGN); ! 500: i = count % MAXRPT; ! 501: if (count >= MAXRPT){ ! 502: k = MAXRPT - i; ! 503: for (j=0; j <i; j++) ! 504: shiftarray(0,k); ! 505: } ! 506: ptoutput(i); ! 507: exit(0); ! 508: } ! 509: dietty() ! 510: { ! 511: signal(SIGINT,SIG_IGN); ! 512: mvcur(0,COLS-1, LINES-1,0); ! 513: endwin(); ! 514: exit(0); ! 515: } ! 516: ptoutput(reptot) ! 517: int reptot; ! 518: { ! 519: register i,j; ! 520: printf("mem[avm fre] pag[%5s pi po fr de sr] fault[in sy cs] cpu[us sy id]\n", swflag ? "si so" : "re at"); ! 521: for(i=0; i < (reptot); i++){ ! 522: printf(" %6d%5d %4d%3d%4d%4d%4d%4d%4d %4d%4d%4d ", ! 523: rec[i].avm,rec[i].fre, rec[i].pgre,rec[i].pgat, ! 524: rec[i].pi,rec[i].po,rec[i].fr, rec[i].de,rec[i].sr, ! 525: rec[i].in,rec[i].sy,rec[i].cs); ! 526: for(j=0; j<( CPUSTATES -1); j++) ! 527: printf("%3.0f",rec[i].syste[j]); ! 528: printf("\n"); ! 529: } ! 530: for(i=(reptot); i<repcnt; i++) ! 531: printf("\n"); ! 532: ! 533: printf("proc[r b w]Dsk["); ! 534: ! 535: for (i=0; i < DK_NDRIVE; i++) ! 536: if(dr_name[i][0] !='?') ! 537: printf("%3.3s ",dr_name[i]); ! 538: printf("]\n"); ! 539: for(i=0; i < (reptot); i++){ ! 540: printf(" %2d%2d%2d ",rec[i].r,rec[i].b,rec[i].w); ! 541: for(j=0; j<DK_NDRIVE; j++) ! 542: if(dr_name[j][0] !='?') ! 543: printf("%3.0f ",rec[i].dk[j]); ! 544: printf("\n"); ! 545: } ! 546: for (i=(reptot); i< repcnt; i++) ! 547: printf("\n"); ! 548: } ! 549: shiftarray(srtary,offset) ! 550: int srtary; /* starting array to be shifted */ ! 551: int offset; /* offset to be skip in shifting array */ ! 552: { ! 553: register j; ! 554: rec[srtary].r = rec[srtary+offset].r; ! 555: rec[srtary].b = rec[srtary+offset].b; ! 556: rec[srtary].w = rec[srtary+offset].w; ! 557: rec[srtary].avm = rec[srtary+offset].avm; ! 558: rec[srtary].fre = rec[srtary+offset].fre; ! 559: rec[srtary].pgre = rec[srtary+offset].pgre; ! 560: rec[srtary].pgat = rec[srtary+offset].pgat; ! 561: rec[srtary].pi = rec[srtary+offset].pi; ! 562: rec[srtary].po = rec[srtary+offset].po; ! 563: rec[srtary].fr = rec[srtary+offset].fr; ! 564: rec[srtary].de = rec[srtary+offset].de; ! 565: rec[srtary].sr = rec[srtary+offset].sr; ! 566: for(j=0; j < DK_NDRIVE; j++) ! 567: rec[srtary].dk[j] = rec[srtary+offset].dk[j]; ! 568: rec[srtary].in = rec[srtary+offset].in; ! 569: rec[srtary].sy = rec[srtary+offset].sy; ! 570: rec[srtary].cs = rec[srtary+offset].cs; ! 571: for(j=0; j < (CPUSTATES-1); j++) ! 572: rec[srtary].syste[j] = rec[srtary+offset].syste[j]; ! 573: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.