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