oops
[unix-history] / usr / src / usr.sbin / iostat / iostat.c
CommitLineData
d66f1fc6 1static char *sccsid = "@(#)iostat.c 4.10 (Berkeley) 83/10/19";
be974f30
BJ
2/*
3 * iostat
4 */
700789be 5#include <stdio.h>
be974f30 6#include <nlist.h>
700789be
MT
7#include <sys/types.h>
8#include <sys/buf.h>
41b4a915
BS
9#include <sys/dk.h>
10#ifdef vax
4e7e20a4
KM
11#include <vaxuba/ubavar.h>
12#include <vaxmba/mbavar.h>
41b4a915
BS
13#endif
14#ifdef sun
15#include <sundev/mbvar.h>
16#endif
be974f30
BJ
17
18struct 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
22f209a2
SL
37 { "_hz" },
38#define X_HZ 9
d66f1fc6
SL
39 { "_phz" },
40#define X_PHZ 10
41b4a915 41#ifdef vax
700789be 42 { "_mbdinit" },
d66f1fc6 43#define X_MBDINIT 11
700789be 44 { "_ubdinit" },
d66f1fc6 45#define X_UBDINIT 12
41b4a915 46#endif
41b4a915
BS
47#ifdef sun
48 { "_mbdinit" },
d66f1fc6 49#define X_MBDINIT 11
41b4a915 50#endif
be974f30
BJ
51 { 0 },
52};
700789be
MT
53
54char dr_name[DK_NDRIVE][10];
55
be974f30
BJ
56struct
57{
58 int dk_busy;
59 long cp_time[CPUSTATES];
60 long dk_time[DK_NDRIVE];
61 long dk_wds[DK_NDRIVE];
62 long dk_seek[DK_NDRIVE];
63 long dk_xfer[DK_NDRIVE];
64 float dk_mspw[DK_NDRIVE];
65 long tk_nin;
66 long tk_nout;
67} s, s1;
68
69int mf;
22f209a2 70int hz;
d66f1fc6 71int phz;
be974f30
BJ
72double etime;
73
74main(argc, argv)
75char *argv[];
76{
77 extern char *ctime();
78 register i;
79 int iter;
80 double f1, f2;
81 long t;
8b6704d4 82 int tohdr = 1;
be974f30
BJ
83
84 nlist("/vmunix", nl);
85 if(nl[X_DK_BUSY].n_type == 0) {
86 printf("dk_busy not found in /vmunix namelist\n");
87 exit(1);
88 }
89 mf = open("/dev/kmem", 0);
90 if(mf < 0) {
91 printf("cannot open /dev/kmem\n");
92 exit(1);
93 }
94 iter = 0;
95 while (argc>1&&argv[1][0]=='-') {
96 argc--;
97 argv++;
98 }
99 lseek(mf, (long)nl[X_DK_MSPW].n_value, 0);
100 read(mf, s.dk_mspw, sizeof s.dk_mspw);
700789be
MT
101 for (i = 0; i < DK_NDRIVE; i++)
102 sprintf(dr_name[i], "dk%d", i);
103 read_names();
be974f30
BJ
104 if(argc > 2)
105 iter = atoi(argv[2]);
be974f30 106loop:
8b6704d4 107 if (--tohdr == 0) {
700789be 108 printf(" tty");
8b6704d4
BJ
109 for (i = 0; i < DK_NDRIVE; i++)
110 if (s.dk_mspw[i] != 0.0)
700789be
MT
111 printf(" %3.3s ", dr_name[i]);
112 printf(" cpu\n");
8b6704d4
BJ
113 printf(" tin tout");
114 for (i = 0; i < DK_NDRIVE; i++)
115 if (s.dk_mspw[i] != 0.0)
4e7e20a4 116 printf(" bps tps msps ");
8b6704d4
BJ
117 printf(" us ni sy id\n");
118 tohdr = 19;
119 }
be974f30
BJ
120 lseek(mf, (long)nl[X_DK_BUSY].n_value, 0);
121 read(mf, &s.dk_busy, sizeof s.dk_busy);
122 lseek(mf, (long)nl[X_DK_TIME].n_value, 0);
123 read(mf, s.dk_time, sizeof s.dk_time);
124 lseek(mf, (long)nl[X_DK_XFER].n_value, 0);
125 read(mf, s.dk_xfer, sizeof s.dk_xfer);
126 lseek(mf, (long)nl[X_DK_WDS].n_value, 0);
127 read(mf, s.dk_wds, sizeof s.dk_wds);
128 lseek(mf, (long)nl[X_TK_NIN].n_value, 0);
129 read(mf, &s.tk_nin, sizeof s.tk_nin);
130 lseek(mf, (long)nl[X_TK_NOUT].n_value, 0);
131 read(mf, &s.tk_nout, sizeof s.tk_nout);
132 lseek(mf, (long)nl[X_DK_SEEK].n_value, 0);
133 read(mf, s.dk_seek, sizeof s.dk_seek);
134 lseek(mf, (long)nl[X_CP_TIME].n_value, 0);
135 read(mf, s.cp_time, sizeof s.cp_time);
136 lseek(mf, (long)nl[X_DK_MSPW].n_value, 0);
137 read(mf, s.dk_mspw, sizeof s.dk_mspw);
22f209a2
SL
138 lseek(mf, (long)nl[X_HZ].n_value, 0);
139 read(mf, &hz, sizeof hz);
d66f1fc6
SL
140 lseek(mf, (long)nl[X_PHZ].n_value, 0);
141 read(mf, &phz, sizeof phz);
142 if (phz)
143 hz = phz;
be974f30
BJ
144 for (i = 0; i < DK_NDRIVE; i++) {
145#define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
146 X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
147 }
148 t = s.tk_nin; s.tk_nin -= s1.tk_nin; s1.tk_nin = t;
149 t = s.tk_nout; s.tk_nout -= s1.tk_nout; s1.tk_nout = t;
150 etime = 0;
151 for(i=0; i<CPUSTATES; i++) {
152 X(cp_time);
153 etime += s.cp_time[i];
154 }
155 if (etime == 0.0)
156 etime = 1.0;
22f209a2 157 etime /= (float) hz;
be974f30
BJ
158 printf("%4.0f%5.0f", s.tk_nin/etime, s.tk_nout/etime);
159 for (i=0; i<DK_NDRIVE; i++)
160 if (s.dk_mspw[i] != 0.0)
161 stats(i);
162 for (i=0; i<CPUSTATES; i++)
163 stat1(i);
164 printf("\n");
165contin:
166 --iter;
167 if(iter)
168 if(argc > 1) {
169 sleep(atoi(argv[1]));
170 goto loop;
171 }
172}
173
174stats(dn)
175{
176 register i;
177 double atime, words, xtime, itime;
178
179 if (s.dk_mspw[dn] == 0.0) {
180 printf("%4.0f%4.0f%5.1f ", 0.0, 0.0, 0.0);
181 return;
182 }
183 atime = s.dk_time[dn];
22f209a2 184 atime /= (float) hz;
be974f30
BJ
185 words = s.dk_wds[dn]*32.0; /* number of words transferred */
186 xtime = s.dk_mspw[dn]*words; /* transfer time */
187 itime = atime - xtime; /* time not transferring */
188/*
189 printf("\ndn %d, words %8.2f, atime %6.2f, xtime %6.2f, itime %6.2f\n",
190 dn, words, atime, xtime, itime);
191*/
192 if (xtime < 0)
193 itime += xtime, xtime = 0;
194 if (itime < 0)
195 xtime += itime, itime = 0;
4e7e20a4 196 printf("%4.0f", words/512/etime);
be974f30
BJ
197 printf("%4.0f", s.dk_xfer[dn]/etime);
198 printf("%5.1f ",
199 s.dk_seek[dn] ? itime*1000./s.dk_seek[dn] : 0.0);
200/*
201 printf("%4.1f",
202 s.dk_xfer[dn] ? xtime*1000./s.dk_xfer[dn] : 0.0);
203*/
204}
205
206stat1(o)
207{
208 register i;
209 double time;
210
211 time = 0;
212 for(i=0; i<CPUSTATES; i++)
213 time += s.cp_time[i];
214 if (time == 0.0)
215 time = 1.0;
216 printf("%3.0f", 100*s.cp_time[o]/time);
217}
700789be 218
700789be 219#define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var);
41b4a915
BS
220
221#ifdef vax
700789be
MT
222read_names()
223{
224 struct mba_device mdev;
225 register struct mba_device *mp;
226 struct mba_driver mdrv;
227 short two_char;
228 char *cp = (char *) &two_char;
229 struct uba_device udev, *up;
230 struct uba_driver udrv;
231
232 mp = (struct mba_device *) nl[X_MBDINIT].n_value;
233 up = (struct uba_device *) nl[X_UBDINIT].n_value;
0e22e6c5 234 if (up == 0)
700789be
MT
235 {
236 fprintf(stderr, "iostat: Disk init info not in namelist\n");
237 exit(1);
238 }
41b4a915 239 if (mp) for (;;) {
700789be
MT
240 steal(mp++, mdev);
241 if (mdev.mi_driver == 0)
242 break;
243 if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
244 continue;
245 steal(mdev.mi_driver, mdrv);
246 steal(mdrv.md_dname, two_char);
247 sprintf(dr_name[mdev.mi_dk], "%c%c%d", cp[0], cp[1], mdev.mi_unit);
248 }
41b4a915 249 if (up) for (;;) {
700789be
MT
250 steal(up++, udev);
251 if (udev.ui_driver == 0)
252 break;
253 if (udev.ui_dk < 0 || udev.ui_alive == 0)
254 continue;
255 steal(udev.ui_driver, udrv);
256 steal(udrv.ud_dname, two_char);
257 sprintf(dr_name[udev.ui_dk], "%c%c%d", cp[0], cp[1], udev.ui_unit);
258 }
259}
41b4a915
BS
260#endif
261
262#ifdef sun
263read_names()
264{
265 struct mb_device mdev;
266 register struct mb_device *mp;
267 struct mb_driver mdrv;
268 short two_char;
269 char *cp = (char *) &two_char;
270
271 mp = (struct mb_device *) nl[X_MBDINIT].n_value;
272 if (mp == 0) {
273 fprintf(stderr, "iostat: Disk init info not in namelist\n");
274 exit(1);
275 }
276 for (;;) {
277 steal(mp++, mdev);
278 if (mdev.md_driver == 0)
279 break;
280 if (mdev.md_dk < 0 || mdev.md_alive == 0)
281 continue;
282 steal(mdev.md_driver, mdrv);
283 steal(mdrv.mdr_dname, two_char);
284 sprintf(dr_name[mdev.md_dk], "%c%c%d", cp[0], cp[1], mdev.md_unit);
285 }
286}
287#endif