|
|
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.