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