|
|
1.1 root 1: /*
2: * iostat
3: */
4: #include <curses.h>
5: #include <signal.h>
6: #include <stdio.h>
7: #include <nlist.h>
8: #include <sys/types.h>
9: #include <sys/buf.h>
10: #include <sys/dk.h>
11: #include <vba/vbavar.h>
1.1.1.2 ! root 12: #include <setjmp.h>
1.1 root 13: #include <vba/vddc.h>
14:
15: struct nlist nli[] = {
16: { "_dk_busy" },
17: #define X_DK_BUSY 0
18: { "_dk_time" },
19: #define X_DK_TIME 1
20: { "_dk_xfer" },
21: #define X_DK_XFER 2
22: { "_dk_wds" },
23: #define X_DK_WDS 3
24: { "_tk_nin" },
25: #define X_TK_NIN 4
26: { "_tk_nout" },
27: #define X_TK_NOUT 5
28: { "_dk_seek" },
29: #define X_DK_SEEK 6
30: { "_cp_time" },
31: #define X_CP_TIME 7
32: { "_dk_mspw" },
33: #define X_DK_MSPW 8
34: { "_hz" },
35: #define X_HZ 9
36: { "_vbdinit" },
37: #define X_VBDINIT 10
38: { "_vdst" },
39: #define X_VDST 11
40: { "_nvddrv" },
41: #define X_NVDDRV 12
42: { 0 },
43: };
1.1.1.2 ! root 44: #define PART 16 /* 16 drives displayed in one mounted set */
! 45: #define MAX_PART ((int)((DK_NDRIVE+(PART-1))/PART))
1.1 root 46:
47: char dr_name[DK_NDRIVE][10];
1.1.1.2 ! root 48: int dr_win[DK_NDRIVE];
1.1 root 49:
50: fs_tab *vdinfo,*vdinfo_save;
51: long name;
52:
53: struct
54: {
55: int dk_busy;
1.1.1.2 ! root 56: long cp_time[CPUSTATES];
1.1 root 57: long dk_time[DK_NDRIVE];
58: long dk_wds[DK_NDRIVE];
59: long dk_seek[DK_NDRIVE];
60: long dk_xfer[DK_NDRIVE];
61: float dk_mspw[DK_NDRIVE];
62: long tk_nin;
63: long tk_nout;
64: } s, s1;
65:
66: #define CPUSTE 4
67: #define NCOLS 80
68: #define NLINES 24
69: #define MAXRPT 4
70: #define UNIX "/vmunix"
71:
72: struct
73: {
74: float tin;
75: float tout;
76: float syste[CPUSTE];
77: float bps[DK_NDRIVE];
78: float tps[DK_NDRIVE];
1.1.1.2 ! root 79: float mspt[DK_NDRIVE];
1.1 root 80: } rec[MAXRPT];
81:
82: int mf;
83: int hz;
84: int nodktyp;
85: int count,repcnt, iter;
86:
87: double etime;
88: extern char *malloc();
1.1.1.2 ! root 89: int wno;
! 90: jmp_buf jb;
! 91: int timer();
! 92: int max_win, recurflg;
1.1 root 93:
94: main(argc, argv)
1.1.1.2 ! root 95: int argc;
1.1 root 96: char *argv[];
97: {
98: extern char *ctime();
99: register i;
100: int iter;
101: int j, totrep;
102: double f1, f2;
103: long t;
1.1.1.2 ! root 104: int beg_i, end_i,head[MAX_PART],hd;
1.1 root 105: int tohdr = 1;
106: int die();
107: int dietty();
108: int ptoutput();
109: int shiftarray();
110: int TERM;
1.1.1.2 ! root 111: /* addition variables for windowing implementation */
! 112: WINDOW *win[MAX_PART], *window, *newwin();
! 113: register w;
! 114: int w_sv;
! 115: int deft=0;
! 116: int brkflg;
! 117: int wsleep, wrnd;
! 118: int sleeptime;
! 119: char ch;
1.1 root 120:
121: TERM = isatty(1);
122: nlist(UNIX, nli);
123: if(nli[X_DK_BUSY].n_value == 0) {
124: printf("dk_busy not found in %s namelist\n",UNIX);
125: exit(1);
126: }
127: mf = open("/dev/kmem", 0);
128: if(mf < 0) {
129: printf("cannot open /dev/kmem\n");
130: exit(1);
131: }
132: lseek(mf, (long)nli[X_DK_MSPW].n_value, 0);
133: read(mf, s.dk_mspw, sizeof s.dk_mspw);
1.1.1.2 ! root 134: for (i = 0; i < DK_NDRIVE; i++){
! 135: sprintf (dr_name[i],"?%x",i);
! 136: dr_win[i] = -1;
! 137: }
1.1 root 138: lseek(mf, (long)nli[X_NVDDRV].n_value, 0);
139: read(mf, &nodktyp, sizeof nodktyp);
140: vdinfo = (fs_tab *)malloc(nodktyp*sizeof(fs_tab));
141: lseek(mf, (long)nli[X_VDST].n_value, 0);
142: read(mf, (char *)vdinfo, nodktyp*sizeof(fs_tab));
143: vdinfo_save = vdinfo;
144: for (i = 0; i < nodktyp; vdinfo++, i++) {
145: name = (long)vdinfo->type_name;
146: vdinfo->type_name = malloc(3);
147: lseek(mf, (long)name, 0);
148: read(mf, vdinfo->type_name, 3);
149: }
150: vdinfo = vdinfo_save;
151: read_names();
1.1.1.2 ! root 152: max_win=wno+1;
! 153: argc--, argv++;
! 154: while (argc>0 && argv[0][0]=='-') {
! 155: char *cp= *argv++;
! 156: argc--;
! 157: while (*++cp) switch (*cp){
! 158:
! 159: case '0':
! 160: case '1':
! 161: case '2':
! 162: case '3':
! 163: case '4':
! 164: case '5':
! 165: case '6':
! 166: case '7':
! 167: case '8':
! 168: case '9':
! 169: if (TERM) deft=(*cp)-'0';
! 170: if(deft >= max_win) deft=0;
! 171: break;
! 172:
! 173: case 'A':
! 174: case 'B':
! 175: case 'C':
! 176: case 'D':
! 177: case 'E':
! 178: case 'F':
! 179: if (TERM) deft=(*cp) -'A' +10;
! 180: if(deft > max_win) deft=0;
! 181: break;
! 182:
! 183: case 'r':
! 184: if(TERM && max_win > 0 )
! 185: recurflg++;
! 186: break;
! 187:
! 188: default:
! 189: fprintf(stderr,"usage:iostat");
! 190: if(max_win > 0 )
! 191: if(max_win <10)
! 192: fprintf(stderr,"[-[0-%x][r]",max_win);
! 193: else if (max_win >=10 && max_win < 16)
! 194: fprintf(stderr,"[-[0-9A%x][r]",max_win);
! 195: else;
! 196: fprintf(stderr," [interval] [count] \n");
! 197: exit(1);
! 198: }
! 199:
! 200: }
1.1 root 201:
202: totrep = 1;
1.1.1.2 ! root 203: if(argc > 1)
1.1 root 204: totrep = atoi(argv[2]);
1.1.1.2 ! root 205: if (argc ==1)
1.1 root 206: totrep = -1;
207: iter = 0;
208: if ((totrep < 0) || (totrep > MAXRPT))
209: repcnt = MAXRPT;
210: else
211: repcnt = totrep;
212: if (TERM){
213: initscr();
214: signal(SIGINT,dietty);
1.1.1.2 ! root 215: signal(SIGBUS,dietty);
! 216: signal(SIGALRM, timer);
1.1 root 217: nonl();
218: crmode();
219: noecho();
220: leaveok(stdscr, TRUE);
221: scrollok(stdscr,FALSE);
1.1.1.2 ! root 222: for(w=0; w < max_win; w++){
! 223: win[w]=newwin(NLINES,NCOLS,0,0);
! 224: }
1.1 root 225: }
226: else
227: signal(SIGINT,die);
228: loop:
1.1.1.2 ! root 229: for (w=0; w < max_win; w++)
! 230: head[w] = 4;
1.1 root 231: end_i = 0;
232: hd=0;
233: lseek(mf, (long)nli[X_DK_BUSY].n_value, 0);
234: read(mf, &s.dk_busy, sizeof s.dk_busy);
235: lseek(mf, (long)nli[X_DK_TIME].n_value, 0);
236: read(mf, s.dk_time, sizeof s.dk_time);
237: lseek(mf, (long)nli[X_DK_XFER].n_value, 0);
238: read(mf, s.dk_xfer, sizeof s.dk_xfer);
239: lseek(mf, (long)nli[X_DK_WDS].n_value, 0);
240: read(mf, s.dk_wds, sizeof s.dk_wds);
241: lseek(mf, (long)nli[X_TK_NIN].n_value, 0);
242: read(mf, &s.tk_nin, sizeof s.tk_nin);
243: lseek(mf, (long)nli[X_TK_NOUT].n_value, 0);
244: read(mf, &s.tk_nout, sizeof s.tk_nout);
245: lseek(mf, (long)nli[X_DK_SEEK].n_value, 0);
246: read(mf, s.dk_seek, sizeof s.dk_seek);
247: lseek(mf, (long)nli[X_CP_TIME].n_value, 0);
248: read(mf, s.cp_time, sizeof s.cp_time);
249: lseek(mf, (long)nli[X_DK_MSPW].n_value, 0);
250: read(mf, s.dk_mspw, sizeof s.dk_mspw);
251: lseek(mf, (long)nli[X_HZ].n_value, 0);
252: read(mf, &hz, sizeof hz);
253: for (i = 0; i < DK_NDRIVE; i++) {
254: #define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
255: X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
256: }
257: t = s.tk_nin; s.tk_nin -= s1.tk_nin; s1.tk_nin = t;
258: t = s.tk_nout; s.tk_nout -= s1.tk_nout; s1.tk_nout = t;
259: etime = 0;
260: for(i=0; i<CPUSTATES; i++) {
1.1.1.2 ! root 261: #define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
1.1 root 262: X(cp_time);
263: etime += s.cp_time[i];
264: }
265: if (etime == 0.0)
266: etime = 1.0;
267: etime /= (float) hz;
268: rec[iter].tin = s.tk_nin/etime;
269: rec[iter].tout = s.tk_nout/etime;
270: for (i=0; i<DK_NDRIVE; i++){
271: if(dr_name[i][0] != '?'){
272: stats(i,iter);
273: }
274: }
1.1.1.2 ! root 275: for (i=0; i<CPUSTATES; i++){
1.1 root 276: stat1(i,iter);
1.1.1.2 ! root 277: }
1.1 root 278: count++;
279: prt_loop:
280: beg_i = hd;
281: if (TERM) {
282: for (i = hd; i < DK_NDRIVE; i++){
283: if (dr_name[i][0] != '?'){
1.1.1.2 ! root 284: w = dr_win[i];
! 285: if (head[w] == 4){
! 286: wmove(win[w],0,0);
! 287: wprintw(win[w]," tty tin tout cpu us ni sy id ");
! 288: }
! 289: wprintw(win[w]," %3.3s ",dr_name[i]);
! 290: head[w]++;
! 291: w_sv=w;
! 292: brkflg++;
! 293: for(j=i+1; j < DK_NDRIVE; j++){
! 294: if(dr_win[j] == w_sv){
! 295: brkflg=0;
! 296: break;
! 297: }
! 298: }
! 299: if ((head[w] % 5 == 0) || (brkflg!=0 )){
! 300: if(head[w_sv] !=5 )
! 301: wprintw(win[w_sv],"\n");
1.1 root 302: break;
1.1.1.2 ! root 303: }
1.1 root 304: }
305: }
306: if (i == DK_NDRIVE)
307: i--;
308: end_i = i;
309: for (i = beg_i; i <= end_i; i++)
1.1.1.2 ! root 310: if(dr_name[i][0] != '?'){
! 311: wprintw(win[dr_win[i]]," bps tps mspt");
! 312: }
! 313: wprintw (win[w_sv],"\n");
1.1 root 314: for(i = 0; i < (iter+1); i++){
1.1.1.2 ! root 315: if (head[w_sv] == 5){
! 316: wprintw(win[w_sv]," %4.0f%5.0f ",rec[i].tin,rec[i].tout);
1.1 root 317: for (j = 0; j < CPUSTE; j++)
1.1.1.2 ! root 318: wprintw(win[w_sv],"%3.0f",rec[i].syste[j]);
! 319: wprintw(win[w_sv]," ");
1.1 root 320: }
321: for (j = beg_i; j <= end_i; j++)
322: if (dr_name[j][0] != '?')
1.1.1.2 ! root 323: wprintw(win[dr_win[j]],"%4.0f%4.0f %5.1f",
! 324: rec[i].bps[j], rec[i].tps[j],
! 325: rec[i].mspt[j]);
! 326: wprintw (win[w_sv],"\n");
1.1 root 327: }
328: for(i=(iter+1); i<repcnt; i++)
1.1.1.2 ! root 329: wprintw(win[w_sv],"\n");
1.1 root 330: if (end_i < (DK_NDRIVE-1) ){
331: hd = end_i+1;
332: goto prt_loop;
333: }
1.1.1.2 ! root 334: for(w=0; w < max_win; w++){
! 335: if(max_win >1){
! 336: wmove(win[w],NLINES-1,0);
! 337: wprintw(win[w],"More mounted disk set display: type [0-%x] to select or [r] to rotate", (max_win-1));
! 338: }
! 339: wmove(win[w],0,0);
! 340: }
! 341: window = win[deft];
! 342: touchwin(window);
! 343: wrefresh(window);
1.1 root 344: }
345: else
346: if ((count >= MAXRPT) &&( (count % MAXRPT ) == 0))
347: ptoutput(iter+1);
348:
349: if (totrep > 0 )
350: totrep--;
351: iter++;
352:
353: if (count >= MAXRPT ){
354: for(i=0; i < (MAXRPT -1); i++){
355: shiftarray(i,1);
356: }
357: iter = MAXRPT-1;
358: }
359: if (totrep != 0 ){
1.1.1.2 ! root 360: if(argc > 0) {
! 361: sleeptime=atoi(argv[0]);
! 362: if (TERM){
! 363: w_sv=deft;
! 364: if (recurflg){
! 365: wrnd=(max_win-deft);
! 366: wsleep=(int)(sleeptime/(wrnd+1));
! 367: if (wsleep < 1 ) recurflg = 0;
! 368: else{
! 369: for(w=0; w< wrnd; w++){
! 370: w_sv=wtimed_ch(window,wsleep);
! 371: window=win[w+deft];
! 372: touchwin(window);
! 373: wrefresh(window);
! 374: }
! 375: }
! 376: w_sv=wtimed_ch(window,sleeptime-(wrnd*wsleep));
! 377: }
! 378: else {
! 379: w_sv=wtimed_ch(window,sleeptime);
! 380: }
! 381: if(w_sv >= 0 && w_sv < max_win) deft=w_sv;
! 382: if(recurflg && deft == max_win-1) recurflg=0;
! 383: }
! 384: else
! 385: sleep(sleeptime);
! 386: goto loop;
1.1 root 387: }
388: }
389: if(TERM)
390: dietty();
391: else
392: die();
393: }
394:
395: stats(dn,cnt)
1.1.1.2 ! root 396: int dn, cnt;
1.1 root 397: {
398: register i;
399: double atime, words, xtime, itime;
400: atime = s.dk_time[dn];
401: atime /= (float) hz;
402: words = s.dk_wds[dn]*32.0; /* number of words transferred */
403: xtime = s.dk_mspw[dn]*words; /* transfer time */
404: itime = atime - xtime; /* time not transferring */
405: if (xtime < 0)
406: itime += xtime, xtime = 0;
407: if (itime < 0)
408: xtime += itime, itime = 0;
1.1.1.2 ! root 409: rec[cnt].bps[dn] = words/512.0/etime;
1.1 root 410: rec[cnt].tps[dn] = s.dk_xfer[dn]/etime;
1.1.1.2 ! root 411: rec[cnt].mspt[dn] = s.dk_seek[dn] ? (itime*1000./s.dk_seek[dn])+8.0 : 0.0;
1.1 root 412: }
413:
414: stat1(o,ict)
1.1.1.2 ! root 415: int o,ict;
1.1 root 416: {
417: register i;
1.1.1.2 ! root 418: float time;
1.1 root 419:
420: time = 0;
421: for(i=0; i<CPUSTATES; i++)
422: time += s.cp_time[i];
423: if (time == 0.0)
424: time = 1.0;
1.1.1.2 ! root 425: rec[ict].syste[o] = (100.0*s.cp_time[o])/time;
1.1 root 426: }
427:
428: #define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var);
429:
430: read_names()
431: {
432: struct vba_device udev, *up;
433: struct vba_driver udrv;
434: int unit, i;
1.1.1.2 ! root 435: int wcnt;
! 436: wno=0;
! 437: wcnt=0;
1.1 root 438:
439: up = (struct vba_device *) nli[X_VBDINIT].n_value;
440: if (up == 0)
441: {
442: fprintf(stderr, "iostat: Disk init info not in namelist\n");
443: exit(1);
444: }
445: vdinfo_save = vdinfo;
446: for (;;) {
447: steal(up++, udev);
448: if (udev.ui_driver == 0)
449: break;
450: if (udev.ui_dk <= 0 || udev.ui_alive == 0)
451: continue;
452: unit = (udev.ui_ctlr * 4) + udev.ui_slave;
453: if(udev.ui_type >= nodktyp){
454: fprintf(stderr,"iostat : disk type in unit %d not supported \n",unit);
455: exit(1);
456: }
1.1.1.2 ! root 457: if (wcnt >=PART){
! 458: wcnt=0;
! 459: wno++;
! 460: }
! 461: if(wno > MAX_PART){
! 462: fprintf(stderr, "iostat : maximum mounted disk set of display exceeded \n");
! 463: exit(1);
! 464: }
1.1 root 465: vdinfo = vdinfo_save;
466: for(i=0; i < udev.ui_type; i++)
467: vdinfo++;
468: dr_name[unit][0] = vdinfo->type_name[0];
1.1.1.2 ! root 469: /* dr_name[unit][1] = vdinfo->type_name[1]; */
! 470: dr_win[unit]=wno;
! 471: wcnt++;
1.1 root 472: }
473: }
474: die()
475: {
476: int i,j,k;
477: iter--;
478: signal(SIGINT,SIG_IGN);
479: i = count % MAXRPT;
480: if (count >= MAXRPT){
481: k = MAXRPT - i;
482: for (j=0; j <i; j++)
483: shiftarray(0,k);
484: }
485: ptoutput(i);
486: exit(0);
487: }
488: dietty()
489: {
490: signal(SIGINT, SIG_IGN);
1.1.1.2 ! root 491: mvcur(0,NCOLS-1, NLINES-1,0);
1.1 root 492: endwin();
493: exit(0);
494: }
495: ptoutput(reptot)
496: int reptot;
497: {
498: register i,j;
499: int doneflg,head,end_i,beg_i;
500: head = 4;
501: beg_i = 0;
502: doneflg=0;
503: printf(" tty tin tout cpu us ni sy id ");
504: while (!doneflg){
505: for (i = beg_i; i < DK_NDRIVE; i++){
506: if (dr_name[i][0] != '?'){
507: printf(" %3.3s ",dr_name[i]);
508: head++;
509: if ((head % 5 )== 0)
510: break;
511: }
512: }
513: if (head !=5 )
514: printf ("\n");
515: if (i == DK_NDRIVE){
516: i--;
517: doneflg++;
518: }
519: end_i = i;
520: for (i = beg_i; i <= end_i; i++)
521: if(dr_name[i][0] != '?')
1.1.1.2 ! root 522: printf(" bps tps mspt");
1.1 root 523: printf ("\n");
524: for(i = 0; i < reptot; i++){
525: if (head == 5){
526: printf(" %4.0f%5.0f ",
527: rec[i].tin,rec[i].tout);
528: for (j = 0; j < CPUSTE; j++)
529: printf("%3.0f",rec[i].syste[j]);
530: printf(" ");
531: }
532: for (j = beg_i; j <= end_i; j++)
533: if (dr_name[j][0] != '?'){
534: printf("%4.0f%4.0f %5.1f", rec[i].bps[j],
1.1.1.2 ! root 535: rec[i].tps[j],rec[i].mspt[j]);
1.1 root 536: }
537: printf ("\n");
538: }
539: for(i=reptot; i<repcnt; i++)
540: printf("\n");
541: beg_i = end_i;
542: }
543: }
544: shiftarray(srtary,offset)
545: int srtary; /* starting array to be shifted */
546: int offset; /* offset to be skip in shifting array */
547: {
548: register j;
549: rec[srtary].tin = rec[srtary+offset].tin;
550: rec[srtary].tout = rec[srtary+offset].tout;
551: for(j=0; j < CPUSTATES; j++)
552: rec[srtary].syste[j] = rec[srtary+offset].syste[j];
553: for(j=0; j< DK_NDRIVE; j++){
554: rec[srtary].bps[j] =rec[srtary+offset].bps[j];
555: rec[srtary].tps[j] =rec[srtary+offset].tps[j];
1.1.1.2 ! root 556: rec[srtary].mspt[j] =rec[srtary+offset].mspt[j];
1.1 root 557: }
558: }
1.1.1.2 ! root 559: timer()
! 560: {
! 561: signal(SIGALRM, timer);
! 562: longjmp(jb,1);
! 563: }
! 564:
! 565: int wtimed_ch(win, seconds)
! 566: WINDOW *win;
! 567: int seconds;
! 568: {
! 569: int ch = '\0';
! 570: int w;
! 571: int deft = -1;
! 572:
! 573: if(setjmp(jb) == 0)
! 574: {
! 575: do{
! 576: alarm(seconds);
! 577: ch = wgetch(win);
! 578: if(ch == 'r') {
! 579: deft= -2;
! 580: recurflg++;
! 581: }
! 582: w=ch-'0';
! 583: if (w < max_win && w >=0) {
! 584: recurflg=0;
! 585: deft=w;
! 586: }
! 587: w=ch -'A' +10;
! 588: if (w < max_win && w >10){
! 589: recurflg=0;
! 590: deft=w;
! 591: }
! 592: else ;
! 593: seconds = alarm(0);
! 594:
! 595: } while (ch != 'r'|| deft <0 );
! 596: }
! 597: return(deft);
! 598: }
! 599:
! 600: terminate() /* SIGINT handler */
! 601: {
! 602: endwin();
! 603: exit(0);
! 604: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.