|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)iostat.c 4.17 (Berkeley) 89/05/29"; ! 3: #endif ! 4: ! 5: /* ! 6: * iostat ! 7: */ ! 8: #include <sys/types.h> ! 9: #include <sys/file.h> ! 10: #include <sys/buf.h> ! 11: #include <sys/dkstat.h> ! 12: #include <sys/signal.h> ! 13: #include <stdio.h> ! 14: #include <ctype.h> ! 15: #include <nlist.h> ! 16: #include <paths.h> ! 17: ! 18: struct nlist nl[] = { ! 19: { "_dk_busy" }, ! 20: #define X_DK_BUSY 0 ! 21: { "_dk_time" }, ! 22: #define X_DK_TIME 1 ! 23: { "_dk_xfer" }, ! 24: #define X_DK_XFER 2 ! 25: { "_dk_wds" }, ! 26: #define X_DK_WDS 3 ! 27: { "_tk_nin" }, ! 28: #define X_TK_NIN 4 ! 29: { "_tk_nout" }, ! 30: #define X_TK_NOUT 5 ! 31: { "_dk_seek" }, ! 32: #define X_DK_SEEK 6 ! 33: { "_cp_time" }, ! 34: #define X_CP_TIME 7 ! 35: { "_dk_wpms" }, ! 36: #define X_DK_WPMS 8 ! 37: { "_hz" }, ! 38: #define X_HZ 9 ! 39: { "_phz" }, ! 40: #define X_PHZ 10 ! 41: { "_dk_ndrive" }, ! 42: #define X_DK_NDRIVE 11 ! 43: #ifdef vax ! 44: { "_mbdinit" }, ! 45: #define X_MBDINIT (X_DK_NDRIVE+1) ! 46: { "_ubdinit" }, ! 47: #define X_UBDINIT (X_DK_NDRIVE+2) ! 48: #endif ! 49: #ifdef tahoe ! 50: #define X_VBDINIT (X_DK_NDRIVE+1) ! 51: { "_vbdinit" }, ! 52: #endif ! 53: { 0 }, ! 54: }; ! 55: ! 56: char **dr_name; ! 57: int *dr_select; ! 58: long *dk_wpms; ! 59: int dk_ndrive; ! 60: int ndrives = 0; ! 61: #ifdef vax ! 62: char *defdrives[] = { "hp0", "hp1", "hp2", 0 }; ! 63: #else ! 64: char *defdrives[] = { 0 }; ! 65: #endif ! 66: ! 67: struct { ! 68: int dk_busy; ! 69: long cp_time[CPUSTATES]; ! 70: long *dk_time; ! 71: long *dk_wds; ! 72: long *dk_seek; ! 73: long *dk_xfer; ! 74: long tk_nin; ! 75: long tk_nout; ! 76: } s, s1; ! 77: ! 78: int mf; ! 79: int hz; ! 80: int phz; ! 81: double etime; ! 82: int tohdr = 1; ! 83: int printhdr(); ! 84: ! 85: main(argc, argv) ! 86: char *argv[]; ! 87: { ! 88: extern char *ctime(); ! 89: register i; ! 90: int iter, ndrives; ! 91: double f1, f2; ! 92: long t; ! 93: char *arg, **cp, name[6], buf[BUFSIZ]; ! 94: ! 95: nlist(_PATH_UNIX, nl); ! 96: if(nl[X_DK_BUSY].n_type == 0) { ! 97: fprintf(stderr, "iostat: dk_busy not found in %s namelist\n", ! 98: _PATH_UNIX); ! 99: exit(1); ! 100: } ! 101: mf = open(_PATH_KMEM, 0); ! 102: if(mf < 0) { ! 103: fprintf(stderr, "iostat: cannot open %s\n", _PATH_KMEM); ! 104: exit(1); ! 105: } ! 106: iter = 0; ! 107: for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) ! 108: ; ! 109: if (nl[X_DK_NDRIVE].n_value == 0) { ! 110: printf("dk_ndrive undefined in system\n"); ! 111: exit(1); ! 112: } ! 113: lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET); ! 114: read(mf, &dk_ndrive, sizeof (dk_ndrive)); ! 115: if (dk_ndrive <= 0) { ! 116: printf("dk_ndrive %d\n", dk_ndrive); ! 117: exit(1); ! 118: } ! 119: dr_select = (int *)calloc(dk_ndrive, sizeof (int)); ! 120: dr_name = (char **)calloc(dk_ndrive, sizeof (char *)); ! 121: dk_wpms = (long *)calloc(dk_ndrive, sizeof (long)); ! 122: #define allocate(e, t) \ ! 123: s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ ! 124: s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); ! 125: allocate(dk_time, long); ! 126: allocate(dk_wds, long); ! 127: allocate(dk_seek, long); ! 128: allocate(dk_xfer, long); ! 129: for (arg = buf, i = 0; i < dk_ndrive; i++) { ! 130: dr_name[i] = arg; ! 131: sprintf(dr_name[i], "dk%d", i); ! 132: arg += strlen(dr_name[i]) + 1; ! 133: } ! 134: read_names(); ! 135: lseek(mf, (long)nl[X_HZ].n_value, L_SET); ! 136: read(mf, &hz, sizeof hz); ! 137: lseek(mf, (long)nl[X_PHZ].n_value, L_SET); ! 138: read(mf, &phz, sizeof phz); ! 139: if (phz) ! 140: hz = phz; ! 141: lseek(mf, (long)nl[X_DK_WPMS].n_value, L_SET); ! 142: read(mf, dk_wpms, dk_ndrive*sizeof (dk_wpms)); ! 143: /* ! 144: * Choose drives to be displayed. Priority ! 145: * goes to (in order) drives supplied as arguments, ! 146: * default drives. If everything isn't filled ! 147: * in and there are drives not taken care of, ! 148: * display the first few that fit. ! 149: */ ! 150: ndrives = 0; ! 151: while (argc > 0 && !isdigit(argv[0][0])) { ! 152: for (i = 0; i < dk_ndrive; i++) { ! 153: if (strcmp(dr_name[i], argv[0])) ! 154: continue; ! 155: dr_select[i] = 1; ! 156: ndrives++; ! 157: } ! 158: argc--, argv++; ! 159: } ! 160: for (i = 0; i < dk_ndrive && ndrives < 4; i++) { ! 161: if (dr_select[i] || dk_wpms[i] == 0) ! 162: continue; ! 163: for (cp = defdrives; *cp; cp++) ! 164: if (strcmp(dr_name[i], *cp) == 0) { ! 165: dr_select[i] = 1; ! 166: ndrives++; ! 167: break; ! 168: } ! 169: } ! 170: for (i = 0; i < dk_ndrive && ndrives < 4; i++) { ! 171: if (dr_select[i]) ! 172: continue; ! 173: dr_select[i] = 1; ! 174: ndrives++; ! 175: } ! 176: if (argc > 1) ! 177: iter = atoi(argv[1]); ! 178: signal(SIGCONT, printhdr); ! 179: loop: ! 180: if (--tohdr == 0) ! 181: printhdr(); ! 182: lseek(mf, (long)nl[X_DK_BUSY].n_value, L_SET); ! 183: read(mf, &s.dk_busy, sizeof s.dk_busy); ! 184: lseek(mf, (long)nl[X_DK_TIME].n_value, L_SET); ! 185: read(mf, s.dk_time, dk_ndrive*sizeof (long)); ! 186: lseek(mf, (long)nl[X_DK_XFER].n_value, L_SET); ! 187: read(mf, s.dk_xfer, dk_ndrive*sizeof (long)); ! 188: lseek(mf, (long)nl[X_DK_WDS].n_value, L_SET); ! 189: read(mf, s.dk_wds, dk_ndrive*sizeof (long)); ! 190: lseek(mf, (long)nl[X_DK_SEEK].n_value, L_SET); ! 191: read(mf, s.dk_seek, dk_ndrive*sizeof (long)); ! 192: lseek(mf, (long)nl[X_TK_NIN].n_value, L_SET); ! 193: read(mf, &s.tk_nin, sizeof s.tk_nin); ! 194: lseek(mf, (long)nl[X_TK_NOUT].n_value, L_SET); ! 195: read(mf, &s.tk_nout, sizeof s.tk_nout); ! 196: lseek(mf, (long)nl[X_CP_TIME].n_value, L_SET); ! 197: read(mf, s.cp_time, sizeof s.cp_time); ! 198: for (i = 0; i < dk_ndrive; i++) { ! 199: if (!dr_select[i]) ! 200: continue; ! 201: #define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t ! 202: X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time); ! 203: } ! 204: t = s.tk_nin; s.tk_nin -= s1.tk_nin; s1.tk_nin = t; ! 205: t = s.tk_nout; s.tk_nout -= s1.tk_nout; s1.tk_nout = t; ! 206: etime = 0; ! 207: for(i=0; i<CPUSTATES; i++) { ! 208: X(cp_time); ! 209: etime += s.cp_time[i]; ! 210: } ! 211: if (etime == 0.0) ! 212: etime = 1.0; ! 213: etime /= (float) hz; ! 214: printf("%4.0f%5.0f", s.tk_nin/etime, s.tk_nout/etime); ! 215: for (i=0; i<dk_ndrive; i++) ! 216: if (dr_select[i]) ! 217: stats(i); ! 218: for (i=0; i<CPUSTATES; i++) ! 219: stat1(i); ! 220: printf("\n"); ! 221: fflush(stdout); ! 222: contin: ! 223: if (--iter && argc > 0) { ! 224: sleep(atoi(argv[0])); ! 225: goto loop; ! 226: } ! 227: } ! 228: ! 229: printhdr() ! 230: { ! 231: register int i; ! 232: ! 233: printf(" tty"); ! 234: for (i = 0; i < dk_ndrive; i++) ! 235: if (dr_select[i]) ! 236: printf(" %3.3s ", dr_name[i]); ! 237: printf(" cpu\n"); ! 238: printf(" tin tout"); ! 239: for (i = 0; i < dk_ndrive; i++) ! 240: if (dr_select[i]) ! 241: printf(" bps tps msps "); ! 242: printf(" us ni sy id\n"); ! 243: tohdr = 19; ! 244: } ! 245: ! 246: stats(dn) ! 247: { ! 248: register i; ! 249: double atime, words, xtime, itime; ! 250: ! 251: if (dk_wpms[dn] == 0) { ! 252: printf("%4.0f%4.0f%5.1f ", 0.0, 0.0, 0.0); ! 253: return; ! 254: } ! 255: atime = s.dk_time[dn]; ! 256: atime /= (float) hz; ! 257: words = s.dk_wds[dn]*32.0; /* number of words transferred */ ! 258: xtime = words/dk_wpms[dn]; /* transfer time */ ! 259: itime = atime - xtime; /* time not transferring */ ! 260: if (xtime < 0) ! 261: itime += xtime, xtime = 0; ! 262: if (itime < 0) ! 263: xtime += itime, itime = 0; ! 264: printf("%4.0f", words/512/etime); ! 265: printf("%4.0f", s.dk_xfer[dn]/etime); ! 266: printf("%5.1f ", ! 267: s.dk_seek[dn] ? itime*1000./s.dk_seek[dn] : 0.0); ! 268: } ! 269: ! 270: stat1(o) ! 271: { ! 272: register i; ! 273: double time; ! 274: ! 275: time = 0; ! 276: for(i=0; i<CPUSTATES; i++) ! 277: time += s.cp_time[i]; ! 278: if (time == 0.0) ! 279: time = 1.0; ! 280: printf("%3.0f", 100.*s.cp_time[o]/time); ! 281: } ! 282: ! 283: #define steal(where, var) \ ! 284: lseek(mf, where, L_SET); read(mf, &var, sizeof var); ! 285: ! 286: #ifdef vax ! 287: #include <vaxuba/ubavar.h> ! 288: #include <vaxmba/mbavar.h> ! 289: ! 290: read_names() ! 291: { ! 292: struct mba_device mdev; ! 293: register struct mba_device *mp; ! 294: struct mba_driver mdrv; ! 295: short two_char; ! 296: char *cp = (char *) &two_char; ! 297: struct uba_device udev, *up; ! 298: struct uba_driver udrv; ! 299: ! 300: mp = (struct mba_device *) nl[X_MBDINIT].n_value; ! 301: up = (struct uba_device *) nl[X_UBDINIT].n_value; ! 302: if (up == 0) { ! 303: fprintf(stderr, "iostat: Disk init info not in namelist\n"); ! 304: exit(1); ! 305: } ! 306: if (mp) for (;;) { ! 307: steal(mp++, mdev); ! 308: if (mdev.mi_driver == 0) ! 309: break; ! 310: if (mdev.mi_dk < 0 || mdev.mi_alive == 0) ! 311: continue; ! 312: steal(mdev.mi_driver, mdrv); ! 313: steal(mdrv.md_dname, two_char); ! 314: sprintf(dr_name[mdev.mi_dk], "%c%c%d", ! 315: cp[0], cp[1], mdev.mi_unit); ! 316: } ! 317: if (up) for (;;) { ! 318: steal(up++, udev); ! 319: if (udev.ui_driver == 0) ! 320: break; ! 321: if (udev.ui_dk < 0 || udev.ui_alive == 0) ! 322: continue; ! 323: steal(udev.ui_driver, udrv); ! 324: steal(udrv.ud_dname, two_char); ! 325: sprintf(dr_name[udev.ui_dk], "%c%c%d", ! 326: cp[0], cp[1], udev.ui_unit); ! 327: } ! 328: } ! 329: #endif ! 330: ! 331: #ifdef tahoe ! 332: #include <tahoevba/vbavar.h> ! 333: ! 334: /* ! 335: * Read the drive names out of kmem. ! 336: */ ! 337: read_names() ! 338: { ! 339: struct vba_device udev, *up; ! 340: struct vba_driver udrv; ! 341: short two_char; ! 342: char *cp = (char *)&two_char; ! 343: ! 344: up = (struct vba_device *) nl[X_VBDINIT].n_value; ! 345: if (up == 0) { ! 346: fprintf(stderr, "vmstat: Disk init info not in namelist\n"); ! 347: exit(1); ! 348: } ! 349: for (;;) { ! 350: steal(up++, udev); ! 351: if (udev.ui_driver == 0) ! 352: break; ! 353: if (udev.ui_dk < 0 || udev.ui_alive == 0) ! 354: continue; ! 355: steal(udev.ui_driver, udrv); ! 356: steal(udrv.ud_dname, two_char); ! 357: sprintf(dr_name[udev.ui_dk], "%c%c%d", ! 358: cp[0], cp[1], udev.ui_unit); ! 359: } ! 360: } ! 361: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.