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