Commit | Line | Data |
---|---|---|
8b38f7fc | 1 | #ifndef lint |
d742bf91 | 2 | static char sccsid[] = "@(#)iostat.c 1.3 (Lucasfilm) %G%"; |
8b38f7fc SL |
3 | #endif |
4 | ||
5 | /* | |
6 | * iostat | |
7 | */ | |
8 | #include "systat.h" | |
9 | ||
10 | #include <sys/buf.h> | |
11 | #include <sys/dk.h> | |
12 | #ifdef vax | |
13 | #include <vaxuba/ubavar.h> | |
14 | #include <vaxmba/mbavar.h> | |
15 | #endif | |
16 | #ifdef sun | |
17 | #include <sundev/mbvar.h> | |
18 | #endif | |
19 | ||
20 | WINDOW * | |
21 | openiostat() | |
22 | { | |
23 | static WINDOW *w = NULL; | |
24 | ||
25 | if (w == NULL) | |
959d10ab | 26 | w = newwin(20, 70, 4, 5); |
8b38f7fc SL |
27 | return (w); |
28 | } | |
29 | ||
30 | closeiostat(w) | |
31 | WINDOW *w; | |
32 | { | |
33 | ||
34 | if (w == NULL) | |
35 | return; | |
36 | move(5, 0); | |
37 | clrtobot(); | |
38 | wclear(w); | |
39 | wrefresh(w); | |
40 | } | |
41 | ||
42 | static struct nlist nlst[] = { | |
43 | #define X_DK_BUSY 0 | |
44 | { "_dk_busy" }, | |
45 | #define X_DK_TIME 1 | |
46 | { "_dk_time" }, | |
47 | #define X_DK_XFER 2 | |
48 | { "_dk_xfer" }, | |
49 | #define X_DK_WDS 3 | |
50 | { "_dk_wds" }, | |
51 | #define X_DK_SEEK 4 | |
52 | { "_dk_seek" }, | |
53 | #define X_CP_TIME 5 | |
54 | { "_cp_time" }, | |
55 | #define X_DK_MSPW 6 | |
56 | { "_dk_mspw" }, | |
57 | #define X_HZ 7 | |
58 | { "_hz" }, | |
59 | ||
60 | #ifdef vax | |
61 | #define X_MBDINIT 8 | |
62 | { "_mbdinit" }, | |
63 | #define X_UBDINIT 9 | |
64 | { "_ubdinit" }, | |
65 | #endif | |
66 | #ifdef sun | |
67 | #define X_MBDINIT 8 | |
68 | { "_mbdinit" }, | |
69 | #endif | |
70 | { "" }, | |
71 | }; | |
72 | ||
73 | char dr_name[DK_NDRIVE][10]; | |
74 | ||
75 | struct { | |
76 | int dk_busy; | |
77 | long cp_time[CPUSTATES]; | |
78 | long dk_time[DK_NDRIVE]; | |
79 | long dk_wds[DK_NDRIVE]; | |
80 | long dk_seek[DK_NDRIVE]; | |
81 | long dk_xfer[DK_NDRIVE]; | |
82 | float dk_mspw[DK_NDRIVE]; | |
83 | } s, s1; | |
84 | ||
85 | int kmem; | |
86 | int hz; | |
87 | double etime; | |
88 | ||
89 | initiostat() | |
90 | { | |
91 | register i; | |
92 | ||
93 | if (nlst[X_DK_BUSY].n_type == 0) { | |
94 | nlist("/vmunix", nlst); | |
95 | if (nlst[X_DK_BUSY].n_type == 0) { | |
96 | error("Disk init information isn't in namelist"); | |
97 | return; | |
98 | } | |
99 | } | |
100 | lseek(kmem, (long)nlst[X_DK_MSPW].n_value, L_SET); | |
101 | read(kmem, s.dk_mspw, sizeof s.dk_mspw); | |
102 | for (i = 0; i < DK_NDRIVE; i++) | |
103 | sprintf(dr_name[i], "dk%d", i); | |
104 | lseek(kmem, (long)nlst[X_DK_MSPW].n_value, L_SET); | |
105 | read(kmem, s.dk_mspw, sizeof s.dk_mspw); | |
106 | lseek(kmem, (long)nlst[X_HZ].n_value, L_SET); | |
107 | read(kmem, &hz, sizeof hz); | |
108 | read_names(); | |
109 | } | |
110 | ||
111 | fetchiostat() | |
112 | { | |
113 | ||
114 | if (nlst[X_DK_BUSY].n_type == 0) | |
115 | return; | |
116 | lseek(kmem, (long)nlst[X_DK_BUSY].n_value, L_SET); | |
117 | read(kmem, &s.dk_busy, sizeof s.dk_busy); | |
118 | lseek(kmem, (long)nlst[X_DK_TIME].n_value, L_SET); | |
119 | read(kmem, s.dk_time, sizeof s.dk_time); | |
120 | lseek(kmem, (long)nlst[X_DK_XFER].n_value, L_SET); | |
121 | read(kmem, s.dk_xfer, sizeof s.dk_xfer); | |
122 | lseek(kmem, (long)nlst[X_DK_WDS].n_value, L_SET); | |
123 | read(kmem, s.dk_wds, sizeof s.dk_wds); | |
124 | lseek(kmem, (long)nlst[X_DK_SEEK].n_value, L_SET); | |
125 | read(kmem, s.dk_seek, sizeof s.dk_seek); | |
126 | lseek(kmem, (long)nlst[X_CP_TIME].n_value, L_SET); | |
127 | read(kmem, s.cp_time, sizeof s.cp_time); | |
128 | } | |
129 | ||
130 | labeliostat() | |
131 | { | |
132 | register int i, row; | |
133 | ||
134 | if (nlst[X_DK_BUSY].n_type == 0) { | |
135 | error("No dk_busy defined."); | |
136 | return; | |
137 | } | |
138 | row = 5; | |
959d10ab SL |
139 | move(row, 0); clrtoeol(); |
140 | mvaddstr(row++, 10, | |
141 | "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100"); | |
8b38f7fc SL |
142 | mvaddstr(row++, 0, "cpu user|"); clrtoeol(); |
143 | mvaddstr(row++, 0, " nice|"); clrtoeol(); | |
144 | mvaddstr(row++, 0, " system|"); clrtoeol(); | |
145 | mvaddstr(row++, 0, " idle|"); clrtoeol(); | |
146 | row++; | |
147 | for (i = 0; i < DK_NDRIVE; i++) | |
148 | if (s.dk_mspw[i] != 0.0) { | |
149 | mvprintw(row++, 0, "%3.3s bps|", dr_name[i]); | |
150 | clrtoeol(); | |
151 | mvaddstr(row++, 0, " tps|"); clrtoeol(); | |
152 | mvaddstr(row++, 0, " mps|"); clrtoeol(); | |
153 | } | |
154 | } | |
155 | ||
156 | showiostat() | |
157 | { | |
158 | register int i; | |
159 | register long t; | |
160 | int row; | |
161 | ||
162 | if (nlst[X_DK_BUSY].n_type == 0) | |
163 | return; | |
164 | for (i = 0; i < DK_NDRIVE; i++) { | |
165 | #define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t | |
166 | X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time); | |
167 | } | |
168 | etime = 0; | |
169 | for(i = 0; i < CPUSTATES; i++) { | |
170 | X(cp_time); | |
171 | etime += s.cp_time[i]; | |
172 | } | |
173 | if (etime == 0.0) | |
174 | etime = 1.0; | |
175 | etime /= (float) hz; | |
176 | row = 2; | |
177 | for (i = 0; i < CPUSTATES; i++) | |
178 | stat1(row++, i); | |
179 | row++; | |
180 | for (i = 0; i < DK_NDRIVE; i++) | |
181 | if (s.dk_mspw[i] != 0.0) | |
182 | row = stats(row, i); | |
183 | } | |
184 | ||
185 | stats(row, dn) | |
186 | int row, dn; | |
187 | { | |
188 | register i; | |
189 | double atime, words, xtime, itime; | |
190 | ||
191 | if (s.dk_mspw[dn] == 0.0) { | |
192 | wmove(wnd, row++, 5); wclrtoeol(wnd); | |
193 | wmove(wnd, row++, 5); wclrtoeol(wnd); | |
194 | wmove(wnd, row++, 5); wclrtoeol(wnd); | |
195 | return (row); | |
196 | } | |
197 | atime = s.dk_time[dn]; | |
198 | atime /= (float) hz; | |
199 | words = s.dk_wds[dn]*32.0; /* number of words transferred */ | |
200 | xtime = s.dk_mspw[dn]*words; /* transfer time */ | |
201 | itime = atime - xtime; /* time not transferring */ | |
202 | if (xtime < 0) | |
203 | itime += xtime, xtime = 0; | |
204 | if (itime < 0) | |
205 | xtime += itime, itime = 0; | |
959d10ab SL |
206 | wmove(wnd, row++, 5); histogram(words / 512 / etime, 60, 1.0, 'X'); |
207 | wmove(wnd, row++, 5); histogram(s.dk_xfer[dn] / etime, 60, 1.0, 'X'); | |
8b38f7fc | 208 | wmove(wnd, row++, 5); histogram(s.dk_seek[dn] ? |
959d10ab | 209 | itime * 1000. / s.dk_seek[dn] : 0, 60, 1.0, 'X'); |
8b38f7fc SL |
210 | return (row); |
211 | } | |
212 | ||
213 | stat1(row, o) | |
214 | int row, o; | |
215 | { | |
216 | register i; | |
217 | double time; | |
218 | ||
219 | time = 0; | |
220 | for (i = 0; i < CPUSTATES; i++) | |
221 | time += s.cp_time[i]; | |
222 | if (time == 0.0) | |
223 | time = 1.0; | |
959d10ab | 224 | wmove(wnd, row, 5); histogram(100*s.cp_time[o] / time, 60, 0.5, 'X'); |
8b38f7fc SL |
225 | } |
226 | ||
959d10ab | 227 | histogram(val, colwidth, scale, c) |
8b38f7fc SL |
228 | double val; |
229 | int colwidth; | |
959d10ab | 230 | double scale; |
8b38f7fc SL |
231 | char c; |
232 | { | |
233 | char buf[10]; | |
234 | register int k; | |
959d10ab | 235 | register int v = (int)(val * scale) + 0.5; |
8b38f7fc SL |
236 | |
237 | k = MIN(v, colwidth); | |
238 | if (v > colwidth) { | |
d742bf91 | 239 | sprintf(buf, "%4.1f", val); |
8b38f7fc SL |
240 | k -= strlen(buf); |
241 | while (k--) | |
242 | waddch(wnd, c); | |
243 | waddstr(wnd, buf); | |
244 | return; | |
245 | } | |
246 | while (k--) | |
247 | waddch(wnd, c); | |
248 | wclrtoeol(wnd); | |
249 | } | |
250 | ||
251 | #define steal(where, var) \ | |
252 | lseek(kmem, where, L_SET); read(kmem, &var, sizeof var); | |
253 | ||
254 | #ifdef vax | |
255 | read_names() | |
256 | { | |
257 | struct mba_device mdev; | |
258 | register struct mba_device *mp; | |
259 | struct mba_driver mdrv; | |
260 | short two_char; | |
261 | char *cp = (char *) &two_char; | |
262 | struct uba_device udev, *up; | |
263 | struct uba_driver udrv; | |
264 | ||
265 | mp = (struct mba_device *) nlst[X_MBDINIT].n_value; | |
266 | up = (struct uba_device *) nlst[X_UBDINIT].n_value; | |
267 | if (up == 0) { | |
268 | error("Disk init info not in namelist\n"); | |
269 | return; | |
270 | } | |
271 | if (mp) for (;;) { | |
272 | steal(mp++, mdev); | |
273 | if (mdev.mi_driver == 0) | |
274 | break; | |
275 | if (mdev.mi_dk < 0 || mdev.mi_alive == 0) | |
276 | continue; | |
277 | steal(mdev.mi_driver, mdrv); | |
278 | steal(mdrv.md_dname, two_char); | |
279 | sprintf(dr_name[mdev.mi_dk], "%c%c%d", | |
280 | cp[0], cp[1], mdev.mi_unit); | |
281 | } | |
282 | if (up) for (;;) { | |
283 | steal(up++, udev); | |
284 | if (udev.ui_driver == 0) | |
285 | break; | |
286 | if (udev.ui_dk < 0 || udev.ui_alive == 0) | |
287 | continue; | |
288 | steal(udev.ui_driver, udrv); | |
289 | steal(udrv.ud_dname, two_char); | |
290 | sprintf(dr_name[udev.ui_dk], "%c%c%d", | |
291 | cp[0], cp[1], udev.ui_unit); | |
292 | } | |
293 | } | |
294 | #endif | |
295 | ||
296 | #ifdef sun | |
297 | read_names() | |
298 | { | |
299 | struct mb_device mdev; | |
300 | register struct mb_device *mp; | |
301 | struct mb_driver mdrv; | |
302 | short two_char; | |
303 | char *cp = (char *) &two_char; | |
304 | ||
305 | mp = (struct mb_device *) nlst[X_MBDINIT].n_value; | |
306 | if (mp == 0) { | |
307 | error("Disk init info not in namelist\n"); | |
308 | return; | |
309 | } | |
310 | for (;;) { | |
311 | steal(mp++, mdev); | |
312 | if (mdev.md_driver == 0) | |
313 | break; | |
314 | if (mdev.md_dk < 0 || mdev.md_alive == 0) | |
315 | continue; | |
316 | steal(mdev.md_driver, mdrv); | |
317 | steal(mdrv.mdr_dname, two_char); | |
318 | sprintf(dr_name[mdev.md_dk], "%c%c%d", | |
319 | cp[0], cp[1], mdev.md_unit); | |
320 | } | |
321 | } | |
322 | #endif |