Commit | Line | Data |
---|---|---|
ae1f9014 | 1 | #ifndef lint |
33b2e9da | 2 | static char *sccsid = "@(#)pstat.c 4.22 (Berkeley) %G%"; |
ae1f9014 | 3 | #endif |
ceb84881 BJ |
4 | /* |
5 | * Print system stuff | |
6 | */ | |
7 | ||
8 | #define mask(x) (x&0377) | |
9 | #define clear(x) ((int)x&0x7fffffff) | |
10 | ||
11 | #include <sys/param.h> | |
12 | #include <sys/dir.h> | |
ae1f9014 | 13 | #define KERNEL |
ceb84881 | 14 | #include <sys/file.h> |
ae1f9014 | 15 | #undef KERNEL |
ceb84881 BJ |
16 | #include <sys/user.h> |
17 | #include <sys/proc.h> | |
18 | #include <sys/text.h> | |
19 | #include <sys/inode.h> | |
20 | #include <sys/map.h> | |
88a58f27 | 21 | #include <sys/ioctl.h> |
ceb84881 BJ |
22 | #include <sys/tty.h> |
23 | #include <sys/conf.h> | |
24 | #include <sys/vm.h> | |
25 | #include <nlist.h> | |
0bc29a7d | 26 | #include <machine/pte.h> |
ceb84881 BJ |
27 | |
28 | char *fcore = "/dev/kmem"; | |
29 | char *fnlist = "/vmunix"; | |
30 | int fc; | |
31 | ||
32 | struct nlist nl[] = { | |
33 | #define SINODE 0 | |
34 | { "_inode" }, | |
35 | #define STEXT 1 | |
36 | { "_text" }, | |
37 | #define SPROC 2 | |
38 | { "_proc" }, | |
39 | #define SDZ 3 | |
40 | { "_dz_tty" }, | |
41 | #define SNDZ 4 | |
42 | { "_dz_cnt" }, | |
43 | #define SKL 5 | |
44 | { "_cons" }, | |
45 | #define SFIL 6 | |
46 | { "_file" }, | |
47 | #define USRPTMA 7 | |
48 | { "_Usrptmap" }, | |
49 | #define USRPT 8 | |
50 | { "_usrpt" }, | |
51 | #define SNSWAP 9 | |
52 | { "_nswap" }, | |
53 | #define SWAPMAP 10 | |
54 | { "_swapmap" }, | |
55 | #define SDH 11 | |
56 | { "_dh11" }, | |
57 | #define SNDH 12 | |
58 | { "_ndh11" }, | |
6770b1c5 | 59 | #define SNPROC 13 |
69d3d166 | 60 | { "_nproc" }, |
6770b1c5 | 61 | #define SNTEXT 14 |
69d3d166 | 62 | { "_ntext" }, |
6770b1c5 | 63 | #define SNFILE 15 |
69d3d166 | 64 | { "_nfile" }, |
6770b1c5 | 65 | #define SNINODE 16 |
69d3d166 | 66 | { "_ninode" }, |
6770b1c5 | 67 | #define SNSWAPMAP 17 |
69d3d166 | 68 | { "_nswapmap" }, |
6770b1c5 | 69 | #define SPTY 18 |
676bc34a | 70 | { "_pt_tty" }, |
e79dc02e SL |
71 | #define SDMMIN 19 |
72 | { "_dmmin" }, | |
73 | #define SDMMAX 20 | |
74 | { "_dmmax" }, | |
75 | #define SNSWDEV 21 | |
76 | { "_nswdev" }, | |
ceb84881 BJ |
77 | 0, |
78 | }; | |
79 | ||
80 | int inof; | |
81 | int txtf; | |
82 | int prcf; | |
83 | int ttyf; | |
84 | int usrf; | |
85 | long ubase; | |
86 | int filf; | |
87 | int swpf; | |
88 | int totflg; | |
89 | char partab[1]; | |
90 | struct cdevsw cdevsw[1]; | |
91 | struct bdevsw bdevsw[1]; | |
92 | int allflg; | |
93 | int kflg; | |
94 | struct pte *Usrptma; | |
95 | struct pte *usrpt; | |
96 | ||
97 | main(argc, argv) | |
98 | char **argv; | |
99 | { | |
100 | register char *argp; | |
ae1f9014 | 101 | int allflags; |
ceb84881 BJ |
102 | |
103 | argc--, argv++; | |
104 | while (argc > 0 && **argv == '-') { | |
105 | argp = *argv++; | |
106 | argp++; | |
107 | argc--; | |
108 | while (*argp++) | |
109 | switch (argp[-1]) { | |
110 | ||
111 | case 'T': | |
112 | totflg++; | |
113 | break; | |
114 | ||
115 | case 'a': | |
116 | allflg++; | |
117 | break; | |
118 | ||
119 | case 'i': | |
120 | inof++; | |
121 | break; | |
122 | ||
123 | case 'k': | |
124 | kflg++; | |
125 | fcore = "/vmcore"; | |
126 | break; | |
127 | ||
128 | case 'x': | |
129 | txtf++; | |
130 | break; | |
131 | ||
132 | case 'p': | |
133 | prcf++; | |
134 | break; | |
135 | ||
136 | case 't': | |
137 | ttyf++; | |
138 | break; | |
139 | ||
140 | case 'u': | |
141 | if (argc == 0) | |
142 | break; | |
143 | argc--; | |
144 | usrf++; | |
145 | sscanf( *argv++, "%x", &ubase); | |
146 | break; | |
147 | ||
148 | case 'f': | |
149 | filf++; | |
150 | break; | |
151 | case 's': | |
152 | swpf++; | |
153 | break; | |
ae1f9014 SL |
154 | default: |
155 | usage(); | |
156 | exit(1); | |
ceb84881 BJ |
157 | } |
158 | } | |
ae1f9014 SL |
159 | if (argc>1) |
160 | fcore = argv[1]; | |
ceb84881 BJ |
161 | if ((fc = open(fcore, 0)) < 0) { |
162 | printf("Can't find %s\n", fcore); | |
163 | exit(1); | |
164 | } | |
ae1f9014 SL |
165 | if (argc>0) |
166 | fnlist = argv[0]; | |
ceb84881 | 167 | nlist(fnlist, nl); |
ceb84881 BJ |
168 | usrpt = (struct pte *)nl[USRPT].n_value; |
169 | Usrptma = (struct pte *)nl[USRPTMA].n_value; | |
170 | if (nl[0].n_type == 0) { | |
171 | printf("no namelist\n"); | |
172 | exit(1); | |
173 | } | |
ae1f9014 SL |
174 | allflags = filf | totflg | inof | prcf | txtf | ttyf | usrf | swpf; |
175 | if (allflags == 0) { | |
176 | printf("pstat: one or more of -[aixptfsu] is required\n"); | |
177 | exit(1); | |
178 | } | |
ceb84881 | 179 | if (filf||totflg) |
69d3d166 | 180 | dofile(); |
ceb84881 BJ |
181 | if (inof||totflg) |
182 | doinode(); | |
183 | if (prcf||totflg) | |
184 | doproc(); | |
185 | if (txtf||totflg) | |
186 | dotext(); | |
187 | if (ttyf) | |
188 | dotty(); | |
189 | if (usrf) | |
190 | dousr(); | |
191 | if (swpf||totflg) | |
192 | doswap(); | |
193 | } | |
194 | ||
ae1f9014 SL |
195 | usage() |
196 | { | |
197 | ||
198 | printf("usage: pstat -[aixptfs] [-u [ubase]] [system] [core]\n"); | |
199 | } | |
200 | ||
ceb84881 BJ |
201 | doinode() |
202 | { | |
203 | register struct inode *ip; | |
69d3d166 BJ |
204 | struct inode *xinode, *ainode; |
205 | register int nin; | |
206 | int ninode; | |
ceb84881 BJ |
207 | |
208 | nin = 0; | |
69d3d166 BJ |
209 | ninode = getw(nl[SNINODE].n_value); |
210 | xinode = (struct inode *)calloc(ninode, sizeof (struct inode)); | |
211 | lseek(fc, (int)(ainode = (struct inode *)getw(nl[SINODE].n_value)), 0); | |
212 | read(fc, xinode, ninode * sizeof(struct inode)); | |
213 | for (ip = xinode; ip < &xinode[ninode]; ip++) | |
ceb84881 BJ |
214 | if (ip->i_count) |
215 | nin++; | |
216 | if (totflg) { | |
69d3d166 | 217 | printf("%3d/%3d inodes\n", nin, ninode); |
ceb84881 BJ |
218 | return; |
219 | } | |
69d3d166 | 220 | printf("%d/%d active inodes\n", nin, ninode); |
ae1f9014 | 221 | printf(" LOC FLAGS CNT DEVICE RDC WRC INO MODE NLK UID SIZE/DEV\n"); |
69d3d166 | 222 | for (ip = xinode; ip < &xinode[ninode]; ip++) { |
ceb84881 BJ |
223 | if (ip->i_count == 0) |
224 | continue; | |
69d3d166 | 225 | printf("%8.1x ", ainode + (ip - xinode)); |
88a58f27 | 226 | putf(ip->i_flag&ILOCKED, 'L'); |
ceb84881 BJ |
227 | putf(ip->i_flag&IUPD, 'U'); |
228 | putf(ip->i_flag&IACC, 'A'); | |
229 | putf(ip->i_flag&IMOUNT, 'M'); | |
230 | putf(ip->i_flag&IWANT, 'W'); | |
231 | putf(ip->i_flag&ITEXT, 'T'); | |
ae1f9014 SL |
232 | putf(ip->i_flag&ICHG, 'C'); |
233 | putf(ip->i_flag&ISHLOCK, 'S'); | |
234 | putf(ip->i_flag&IEXLOCK, 'E'); | |
235 | putf(ip->i_flag&ILWAIT, 'Z'); | |
ceb84881 BJ |
236 | printf("%4d", ip->i_count&0377); |
237 | printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev)); | |
88a58f27 SL |
238 | printf("%4d", ip->i_shlockc&0377); |
239 | printf("%4d", ip->i_exlockc&0377); | |
ceb84881 BJ |
240 | printf("%6d", ip->i_number); |
241 | printf("%6x", ip->i_mode & 0xffff); | |
242 | printf("%4d", ip->i_nlink); | |
243 | printf("%4d", ip->i_uid); | |
244 | if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR) | |
a06cf6a1 | 245 | printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev)); |
ceb84881 BJ |
246 | else |
247 | printf("%10ld", ip->i_size); | |
248 | printf("\n"); | |
249 | } | |
69d3d166 BJ |
250 | free(xinode); |
251 | } | |
252 | ||
253 | getw(loc) | |
254 | off_t loc; | |
255 | { | |
256 | int word; | |
257 | ||
cea9ae1e BJ |
258 | if (kflg) |
259 | loc &= 0x7fffffff; | |
69d3d166 BJ |
260 | lseek(fc, loc, 0); |
261 | read(fc, &word, sizeof (word)); | |
adea9260 BJ |
262 | if (kflg) |
263 | word &= 0x7fffffff; | |
69d3d166 | 264 | return (word); |
ceb84881 BJ |
265 | } |
266 | ||
267 | putf(v, n) | |
268 | { | |
269 | if (v) | |
270 | printf("%c", n); | |
271 | else | |
69d3d166 | 272 | printf(" "); |
ceb84881 BJ |
273 | } |
274 | ||
275 | dotext() | |
276 | { | |
277 | register struct text *xp; | |
69d3d166 BJ |
278 | int ntext; |
279 | struct text *xtext, *atext; | |
ceb84881 BJ |
280 | int ntx; |
281 | ||
282 | ntx = 0; | |
69d3d166 BJ |
283 | ntext = getw(nl[SNTEXT].n_value); |
284 | xtext = (struct text *)calloc(ntext, sizeof (struct text)); | |
285 | lseek(fc, (int)(atext = (struct text *)getw(nl[STEXT].n_value)), 0); | |
286 | read(fc, xtext, ntext * sizeof (struct text)); | |
287 | for (xp = xtext; xp < &xtext[ntext]; xp++) | |
ceb84881 BJ |
288 | if (xp->x_iptr!=NULL) |
289 | ntx++; | |
290 | if (totflg) { | |
69d3d166 | 291 | printf("%3d/%3d texts\n", ntx, ntext); |
ceb84881 BJ |
292 | return; |
293 | } | |
69d3d166 | 294 | printf("%d/%d active texts\n", ntx, ntext); |
54298f71 | 295 | printf(" LOC FLAGS DADDR CADDR RSS SIZE IPTR CNT CCNT\n"); |
69d3d166 | 296 | for (xp = xtext; xp < &xtext[ntext]; xp++) { |
ceb84881 BJ |
297 | if (xp->x_iptr == NULL) |
298 | continue; | |
69d3d166 | 299 | printf("%8.1x", atext + (xp - xtext)); |
ceb84881 BJ |
300 | printf(" "); |
301 | putf(xp->x_flag&XPAGI, 'P'); | |
302 | putf(xp->x_flag&XTRC, 'T'); | |
303 | putf(xp->x_flag&XWRIT, 'W'); | |
304 | putf(xp->x_flag&XLOAD, 'L'); | |
305 | putf(xp->x_flag&XLOCK, 'K'); | |
306 | putf(xp->x_flag&XWANT, 'w'); | |
ceb84881 BJ |
307 | printf("%5x", xp->x_daddr[0]); |
308 | printf("%11x", xp->x_caddr); | |
309 | printf("%5d", xp->x_rssize); | |
310 | printf("%5d", xp->x_size); | |
311 | printf("%10.1x", xp->x_iptr); | |
312 | printf("%5d", xp->x_count&0377); | |
54298f71 | 313 | printf("%5d", xp->x_ccount); |
ceb84881 BJ |
314 | printf("\n"); |
315 | } | |
69d3d166 | 316 | free(xtext); |
ceb84881 BJ |
317 | } |
318 | ||
319 | doproc() | |
320 | { | |
69d3d166 BJ |
321 | struct proc *xproc, *aproc; |
322 | int nproc; | |
ceb84881 BJ |
323 | register struct proc *pp; |
324 | register loc, np; | |
325 | struct pte apte; | |
326 | ||
69d3d166 BJ |
327 | nproc = getw(nl[SNPROC].n_value); |
328 | xproc = (struct proc *)calloc(nproc, sizeof (struct proc)); | |
329 | lseek(fc, (int)(aproc = (struct proc *)getw(nl[SPROC].n_value)), 0); | |
330 | read(fc, xproc, nproc * sizeof (struct proc)); | |
ceb84881 | 331 | np = 0; |
69d3d166 | 332 | for (pp=xproc; pp < &xproc[nproc]; pp++) |
ceb84881 BJ |
333 | if (pp->p_stat) |
334 | np++; | |
335 | if (totflg) { | |
69d3d166 | 336 | printf("%3d/%3d processes\n", np, nproc); |
ceb84881 BJ |
337 | return; |
338 | } | |
69d3d166 | 339 | printf("%d/%d processes\n", np, nproc); |
54298f71 | 340 | printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP CLKT\n"); |
69d3d166 | 341 | for (pp=xproc; pp<&xproc[nproc]; pp++) { |
ceb84881 BJ |
342 | if (pp->p_stat==0 && allflg==0) |
343 | continue; | |
69d3d166 | 344 | printf("%8x", aproc + (pp - xproc)); |
ceb84881 BJ |
345 | printf(" %2d", pp->p_stat); |
346 | printf(" %4x", pp->p_flag & 0xffff); | |
347 | printf(" %4d", pp->p_poip); | |
348 | printf(" %3d", pp->p_pri); | |
54298f71 | 349 | printf(" %8x", pp->p_sig); |
ceb84881 BJ |
350 | printf(" %4d", pp->p_uid); |
351 | printf(" %3d", pp->p_slptime); | |
352 | printf(" %3d", pp->p_time); | |
353 | printf(" %4d", pp->p_cpu&0377); | |
354 | printf(" %3d", pp->p_nice); | |
355 | printf(" %6d", pp->p_pgrp); | |
356 | printf(" %6d", pp->p_pid); | |
357 | printf(" %6d", pp->p_ppid); | |
358 | if (kflg) | |
359 | pp->p_addr = (struct pte *)clear((int)pp->p_addr); | |
360 | lseek(fc, (long)(Usrptma+btokmx(pp->p_addr)), 0); | |
361 | read(fc, &apte, sizeof(apte)); | |
362 | printf(" %8x", ctob(apte.pg_pfnum+1) - sizeof(struct pte) * UPAGES); | |
363 | printf(" %4x", pp->p_rssize); | |
364 | printf(" %4x", pp->p_swrss); | |
365 | printf(" %5x", pp->p_dsize+pp->p_ssize); | |
366 | printf(" %7x", clear(pp->p_wchan)); | |
367 | printf(" %7x", clear(pp->p_link)); | |
368 | printf(" %7x", clear(pp->p_textp)); | |
ceb84881 BJ |
369 | printf("\n"); |
370 | } | |
371 | } | |
372 | ||
373 | dotty() | |
374 | { | |
6770b1c5 | 375 | struct tty dz_tty[128]; |
ceb84881 BJ |
376 | int ndz; |
377 | register struct tty *tp; | |
378 | register char *mesg; | |
379 | ||
380 | printf("1 cons\n"); | |
835c8965 BJ |
381 | if (kflg) |
382 | nl[SKL].n_value = clear(nl[SKL].n_value); | |
ceb84881 BJ |
383 | lseek(fc, (long)nl[SKL].n_value, 0); |
384 | read(fc, dz_tty, sizeof(dz_tty[0])); | |
e79dc02e | 385 | mesg = " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n"; |
ceb84881 BJ |
386 | printf(mesg); |
387 | ttyprt(&dz_tty[0], 0); | |
2a63498c | 388 | if (nl[SNDZ].n_type == 0) |
ceb84881 | 389 | goto dh; |
835c8965 BJ |
390 | if (kflg) { |
391 | nl[SNDZ].n_value = clear(nl[SNDZ].n_value); | |
392 | nl[SDZ].n_value = clear(nl[SDZ].n_value); | |
393 | } | |
ceb84881 BJ |
394 | lseek(fc, (long)nl[SNDZ].n_value, 0); |
395 | read(fc, &ndz, sizeof(ndz)); | |
396 | printf("%d dz lines\n", ndz); | |
397 | lseek(fc, (long)nl[SDZ].n_value, 0); | |
6770b1c5 | 398 | read(fc, dz_tty, ndz * sizeof (struct tty)); |
ceb84881 BJ |
399 | for (tp = dz_tty; tp < &dz_tty[ndz]; tp++) |
400 | ttyprt(tp, tp - dz_tty); | |
401 | dh: | |
2a63498c | 402 | if (nl[SNDH].n_type == 0) |
e79dc02e | 403 | goto pty; |
835c8965 BJ |
404 | if (kflg) { |
405 | nl[SNDH].n_value = clear(nl[SNDH].n_value); | |
406 | nl[SDH].n_value = clear(nl[SDH].n_value); | |
407 | } | |
ceb84881 BJ |
408 | lseek(fc, (long)nl[SNDH].n_value, 0); |
409 | read(fc, &ndz, sizeof(ndz)); | |
410 | printf("%d dh lines\n", ndz); | |
411 | lseek(fc, (long)nl[SDH].n_value, 0); | |
6770b1c5 | 412 | read(fc, dz_tty, ndz * sizeof(struct tty)); |
ceb84881 BJ |
413 | for (tp = dz_tty; tp < &dz_tty[ndz]; tp++) |
414 | ttyprt(tp, tp - dz_tty); | |
676bc34a BJ |
415 | pty: |
416 | if (nl[SPTY].n_type == 0) | |
417 | goto pty; | |
418 | if (kflg) { | |
419 | nl[SPTY].n_value = clear(nl[SPTY].n_value); | |
420 | } | |
6770b1c5 | 421 | printf("32 pty lines\n"); |
676bc34a | 422 | lseek(fc, (long)nl[SPTY].n_value, 0); |
6770b1c5 BJ |
423 | read(fc, dz_tty, 32*sizeof(struct tty)); |
424 | for (tp = dz_tty; tp < &dz_tty[32]; tp++) | |
676bc34a | 425 | ttyprt(tp, tp - dz_tty); |
ceb84881 BJ |
426 | } |
427 | ||
428 | ttyprt(atp, line) | |
429 | struct tty *atp; | |
430 | { | |
431 | register struct tty *tp; | |
432 | ||
433 | printf("%2d", line); | |
434 | tp = atp; | |
435 | switch (tp->t_line) { | |
436 | ||
676bc34a | 437 | /* |
ceb84881 BJ |
438 | case NETLDISC: |
439 | if (tp->t_rec) | |
440 | printf("%4d%4d", 0, tp->t_inbuf); | |
441 | else | |
442 | printf("%4d%4d", tp->t_inbuf, 0); | |
443 | break; | |
676bc34a | 444 | */ |
ceb84881 BJ |
445 | |
446 | default: | |
447 | printf("%4d", tp->t_rawq.c_cc); | |
448 | printf("%4d", tp->t_canq.c_cc); | |
449 | } | |
450 | printf("%4d", tp->t_outq.c_cc); | |
e79dc02e | 451 | printf("%8.1x", tp->t_flags); |
ceb84881 | 452 | printf(" %8.1x", tp->t_addr); |
e79dc02e | 453 | printf("%3d", tp->t_delct); |
ceb84881 | 454 | printf("%4d ", tp->t_col); |
676bc34a BJ |
455 | putf(tp->t_state&TS_TIMEOUT, 'T'); |
456 | putf(tp->t_state&TS_WOPEN, 'W'); | |
457 | putf(tp->t_state&TS_ISOPEN, 'O'); | |
458 | putf(tp->t_state&TS_CARR_ON, 'C'); | |
459 | putf(tp->t_state&TS_BUSY, 'B'); | |
460 | putf(tp->t_state&TS_ASLEEP, 'A'); | |
461 | putf(tp->t_state&TS_XCLUDE, 'X'); | |
676bc34a | 462 | putf(tp->t_state&TS_HUPCLS, 'H'); |
ceb84881 BJ |
463 | printf("%6d", tp->t_pgrp); |
464 | switch (tp->t_line) { | |
465 | ||
466 | case NTTYDISC: | |
467 | printf(" ntty"); | |
468 | break; | |
469 | ||
470 | case NETLDISC: | |
471 | printf(" net"); | |
472 | break; | |
473 | } | |
474 | printf("\n"); | |
475 | } | |
476 | ||
477 | dousr() | |
478 | { | |
479 | struct user U; | |
480 | register i, j, *ip; | |
481 | ||
482 | /* This wins only if PAGSIZ > sizeof (struct user) */ | |
483 | lseek(fc, ubase * NBPG, 0); | |
484 | read(fc, &U, sizeof(U)); | |
485 | printf("pcb"); | |
486 | ip = (int *)&U.u_pcb; | |
487 | while (ip < &U.u_arg[0]) { | |
488 | if ((ip - (int *)&U.u_pcb) % 4 == 0) | |
489 | printf("\t"); | |
490 | printf("%x ", *ip++); | |
491 | if ((ip - (int *)&U.u_pcb) % 4 == 0) | |
492 | printf("\n"); | |
493 | } | |
494 | if ((ip - (int *)&U.u_pcb) % 4 != 0) | |
495 | printf("\n"); | |
496 | printf("arg\t"); | |
497 | for (i=0; i<5; i++) | |
498 | printf(" %.1x", U.u_arg[i]); | |
499 | printf("\n"); | |
500 | for (i=0; i<sizeof(label_t)/sizeof(int); i++) { | |
501 | if (i%5==0) | |
502 | printf("\t"); | |
88a58f27 | 503 | printf("%9.1x", U.u_ssave.val[i]); |
ceb84881 BJ |
504 | if (i%5==4) |
505 | printf("\n"); | |
506 | } | |
507 | if (i%5) | |
508 | printf("\n"); | |
509 | printf("segflg\t%d\nerror %d\n", U.u_segflg, U.u_error); | |
510 | printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid); | |
511 | printf("procp\t%.1x\n", U.u_procp); | |
512 | printf("ap\t%.1x\n", U.u_ap); | |
513 | printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2); | |
514 | printf("base, count, offset %.1x %.1x %ld\n", U.u_base, | |
515 | U.u_count, U.u_offset); | |
516 | printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir); | |
ceb84881 BJ |
517 | printf("dirp %.1x\n", U.u_dirp); |
518 | printf("dent %d %.14s\n", U.u_dent.d_ino, U.u_dent.d_name); | |
519 | printf("pdir %.1o\n", U.u_pdir); | |
520 | printf("file\t"); | |
521 | for (i=0; i<10; i++) | |
522 | printf("%9.1x", U.u_ofile[i]); | |
523 | printf("\n\t"); | |
524 | for (i=10; i<NOFILE; i++) | |
525 | printf("%9.1x", U.u_ofile[i]); | |
526 | printf("\n"); | |
527 | printf("pofile\t"); | |
528 | for (i=0; i<10; i++) | |
529 | printf("%9.1x", U.u_pofile[i]); | |
530 | printf("\n\t"); | |
531 | for (i=10; i<NOFILE; i++) | |
532 | printf("%9.1x", U.u_pofile[i]); | |
533 | printf("\n"); | |
88a58f27 | 534 | printf("ssave"); |
ceb84881 BJ |
535 | for (i=0; i<sizeof(label_t)/sizeof(int); i++) { |
536 | if (i%5==0) | |
537 | printf("\t"); | |
88a58f27 | 538 | printf("%9.1x", U.u_ssave.val[i]); |
ceb84881 BJ |
539 | if (i%5==4) |
540 | printf("\n"); | |
541 | } | |
542 | if (i%5) | |
543 | printf("\n"); | |
544 | printf("sigs\t"); | |
545 | for (i=0; i<NSIG; i++) | |
546 | printf("%.1x ", U.u_signal[i]); | |
547 | printf("\n"); | |
df3e00cc | 548 | printf("code\t%.1x\n", U.u_code); |
ceb84881 BJ |
549 | printf("ar0\t%.1x\n", U.u_ar0); |
550 | printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size, | |
551 | U.u_prof.pr_off, U.u_prof.pr_scale); | |
552 | printf("\neosys\t%d\n", U.u_eosys); | |
ceb84881 BJ |
553 | printf("ttyp\t%.1x\n", U.u_ttyp); |
554 | printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd)); | |
555 | printf("exdata\t"); | |
556 | ip = (int *)&U.u_exdata; | |
557 | for (i = 0; i < 8; i++) | |
558 | printf("%.1D ", *ip++); | |
559 | printf("\n"); | |
560 | printf("comm %.14s\n", U.u_comm); | |
561 | printf("start\t%D\n", U.u_start); | |
562 | printf("acflag\t%D\n", U.u_acflag); | |
ceb84881 BJ |
563 | printf("cmask\t%D\n", U.u_cmask); |
564 | printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize); | |
88a58f27 SL |
565 | printf("ru\t"); |
566 | ip = (int *)&U.u_ru; | |
567 | for (i = 0; i < sizeof(U.u_ru)/sizeof(int); i++) | |
ceb84881 BJ |
568 | printf("%D ", ip[i]); |
569 | printf("\n"); | |
88a58f27 SL |
570 | ip = (int *)&U.u_cru; |
571 | printf("cru\t"); | |
572 | for (i = 0; i < sizeof(U.u_cru)/sizeof(int); i++) | |
ceb84881 BJ |
573 | printf("%D ", ip[i]); |
574 | printf("\n"); | |
575 | /* | |
576 | i = U.u_stack - &U; | |
577 | while (U[++i] == 0); | |
578 | i &= ~07; | |
579 | while (i < 512) { | |
580 | printf("%x ", 0140000+2*i); | |
581 | for (j=0; j<8; j++) | |
582 | printf("%9x", U[i++]); | |
583 | printf("\n"); | |
584 | } | |
585 | */ | |
586 | } | |
587 | ||
588 | oatoi(s) | |
589 | char *s; | |
590 | { | |
591 | register v; | |
592 | ||
593 | v = 0; | |
594 | while (*s) | |
595 | v = (v<<3) + *s++ - '0'; | |
596 | return(v); | |
597 | } | |
598 | ||
69d3d166 | 599 | dofile() |
ceb84881 | 600 | { |
69d3d166 BJ |
601 | int nfile; |
602 | struct file *xfile, *afile; | |
ceb84881 BJ |
603 | register struct file *fp; |
604 | register nf; | |
605 | int loc; | |
71c73ab0 | 606 | static char *dtypes[] = { "???", "inode", "socket" }; |
ceb84881 BJ |
607 | |
608 | nf = 0; | |
69d3d166 BJ |
609 | nfile = getw(nl[SNFILE].n_value); |
610 | xfile = (struct file *)calloc(nfile, sizeof (struct file)); | |
611 | lseek(fc, (int)(afile = (struct file *)getw(nl[SFIL].n_value)), 0); | |
612 | read(fc, xfile, nfile * sizeof (struct file)); | |
613 | for (fp=xfile; fp < &xfile[nfile]; fp++) | |
ceb84881 BJ |
614 | if (fp->f_count) |
615 | nf++; | |
616 | if (totflg) { | |
69d3d166 | 617 | printf("%3d/%3d files\n", nf, nfile); |
ceb84881 BJ |
618 | return; |
619 | } | |
69d3d166 | 620 | printf("%d/%d open files\n", nf, nfile); |
192c0cf3 | 621 | printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n"); |
fd2ae9b6 | 622 | for (fp=xfile,loc=(int)afile; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) { |
ceb84881 BJ |
623 | if (fp->f_count==0) |
624 | continue; | |
625 | printf("%8x ", loc); | |
71c73ab0 | 626 | if (fp->f_type <= DTYPE_SOCKET) |
ae1f9014 SL |
627 | printf("%-8.8s", dtypes[fp->f_type]); |
628 | else | |
629 | printf("8d", fp->f_type); | |
ceb84881 BJ |
630 | putf(fp->f_flag&FREAD, 'R'); |
631 | putf(fp->f_flag&FWRITE, 'W'); | |
ae1f9014 | 632 | putf(fp->f_flag&FAPPEND, 'A'); |
192c0cf3 SL |
633 | putf(fp->f_flag&FSHLOCK, 'S'); |
634 | putf(fp->f_flag&FEXLOCK, 'X'); | |
635 | putf(fp->f_flag&FASYNC, 'I'); | |
71c73ab0 SL |
636 | printf(" %3d", mask(fp->f_count)); |
637 | printf(" %3d", mask(fp->f_msgcount)); | |
638 | printf(" %8.1x", fp->f_data); | |
639 | if (fp->f_offset < 0) | |
640 | printf(" %x\n", fp->f_offset); | |
676bc34a BJ |
641 | else |
642 | printf(" %ld\n", fp->f_offset); | |
ceb84881 BJ |
643 | } |
644 | } | |
645 | ||
e79dc02e SL |
646 | int dmmin, dmmax, nswdev; |
647 | ||
ceb84881 BJ |
648 | doswap() |
649 | { | |
69d3d166 BJ |
650 | struct proc *proc; |
651 | int nproc; | |
652 | struct text *xtext; | |
653 | int ntext; | |
654 | struct map *swapmap; | |
655 | int nswapmap; | |
ceb84881 | 656 | register struct proc *pp; |
e79dc02e SL |
657 | int nswap, used, tused, free, waste; |
658 | int db, sb; | |
df3e00cc | 659 | register struct mapent *me; |
ceb84881 | 660 | register struct text *xp; |
e79dc02e | 661 | int i, j; |
ceb84881 | 662 | |
69d3d166 BJ |
663 | nproc = getw(nl[SNPROC].n_value); |
664 | proc = (struct proc *)calloc(nproc, sizeof (struct proc)); | |
665 | lseek(fc, getw(nl[SPROC].n_value), 0); | |
666 | read(fc, proc, nproc * sizeof (struct proc)); | |
667 | nswapmap = getw(nl[SNSWAPMAP].n_value); | |
668 | swapmap = (struct map *)calloc(nswapmap, sizeof (struct map)); | |
669 | lseek(fc, getw(nl[SWAPMAP].n_value), 0); | |
670 | read(fc, swapmap, nswapmap * sizeof (struct map)); | |
33b2e9da | 671 | swapmap->m_name = "swap"; |
69d3d166 | 672 | nswap = getw(nl[SNSWAP].n_value); |
e79dc02e SL |
673 | dmmin = getw(nl[SDMMIN].n_value); |
674 | dmmax = getw(nl[SDMMAX].n_value); | |
675 | nswdev = getw(nl[SNSWDEV].n_value); | |
ceb84881 | 676 | free = 0; |
df3e00cc BJ |
677 | for (me = (struct mapent *)(swapmap+1); |
678 | me < (struct mapent *)&swapmap[nswapmap]; me++) | |
679 | free += me->m_size; | |
69d3d166 BJ |
680 | ntext = getw(nl[SNTEXT].n_value); |
681 | xtext = (struct text *)calloc(ntext, sizeof (struct text)); | |
682 | lseek(fc, getw(nl[STEXT].n_value), 0); | |
683 | read(fc, xtext, ntext * sizeof (struct text)); | |
ceb84881 | 684 | tused = 0; |
69d3d166 | 685 | for (xp = xtext; xp < &xtext[ntext]; xp++) |
ceb84881 BJ |
686 | if (xp->x_iptr!=NULL) |
687 | tused += xdsize(xp); | |
688 | used = tused; | |
e79dc02e | 689 | waste = 0; |
69d3d166 | 690 | for (pp = proc; pp < &proc[nproc]; pp++) { |
ceb84881 BJ |
691 | if (pp->p_stat == 0 || pp->p_stat == SZOMB) |
692 | continue; | |
693 | if (pp->p_flag & SSYS) | |
694 | continue; | |
e79dc02e SL |
695 | db = ctod(pp->p_dsize); |
696 | sb = ctod(pp->p_ssize); | |
697 | waste -= db + sb; | |
698 | db = up(db); | |
699 | sb = up(sb); | |
700 | used += db + sb; | |
701 | waste += db + sb; | |
ceb84881 BJ |
702 | if ((pp->p_flag&SLOAD) == 0) |
703 | used += vusize(pp); | |
704 | } | |
df3e00cc | 705 | /* a DMMAX/2 block goes to argmap */ |
ceb84881 | 706 | if (totflg) { |
e79dc02e | 707 | printf("%3d/%3d 00k swap\n", used/100, (used+free)/100); |
ceb84881 BJ |
708 | return; |
709 | } | |
e79dc02e SL |
710 | printf("%d used (%d text), %d free, %d wasted, %d missing\n", |
711 | used, tused, free, waste, (nswap - dmmax/2 - (used + free))); | |
712 | printf("avail: "); | |
713 | for (i = dmmax; i >= dmmin; i /= 2) { | |
714 | j = 0; | |
715 | while (rmalloc(swapmap, i) != 0) | |
716 | j++; | |
717 | if (j) printf("%d*%d ", j, i); | |
718 | } | |
719 | printf("\n"); | |
ceb84881 BJ |
720 | } |
721 | ||
722 | up(size) | |
723 | register int size; | |
724 | { | |
725 | register int i, block; | |
726 | ||
727 | i = 0; | |
e79dc02e | 728 | block = dmmin; |
ceb84881 BJ |
729 | while (i < size) { |
730 | i += block; | |
e79dc02e | 731 | if (block < dmmax) |
ceb84881 BJ |
732 | block *= 2; |
733 | } | |
734 | return (i); | |
735 | } | |
736 | ||
737 | vusize(p) | |
33b2e9da | 738 | struct proc *p; |
ceb84881 BJ |
739 | { |
740 | register int tsz = p->p_tsize / NPTEPG; | |
741 | ||
e79dc02e SL |
742 | return (ctod(clrnd(UPAGES + |
743 | clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz))); | |
ceb84881 BJ |
744 | } |
745 | ||
746 | xdsize(xp) | |
33b2e9da | 747 | struct text *xp; |
ceb84881 BJ |
748 | { |
749 | ||
750 | if (xp->x_flag & XPAGI) | |
e79dc02e SL |
751 | return (ctod(clrnd(xp->x_size + ctopt(xp->x_size)))); |
752 | return (ctod(xp->x_size)); | |
753 | } | |
754 | ||
755 | /* | |
756 | * Allocate 'size' units from the given | |
757 | * map. Return the base of the allocated space. | |
758 | * In a map, the addresses are increasing and the | |
759 | * list is terminated by a 0 size. | |
760 | * | |
761 | * Algorithm is first-fit. | |
762 | * | |
763 | * This routine knows about the interleaving of the swapmap | |
764 | * and handles that. | |
765 | */ | |
766 | long | |
767 | rmalloc(mp, size) | |
768 | register struct map *mp; | |
769 | long size; | |
770 | { | |
771 | register struct mapent *ep = (struct mapent *)(mp+1); | |
772 | register int addr; | |
773 | register struct mapent *bp; | |
774 | swblk_t first, rest; | |
775 | ||
776 | if (size <= 0 || size > dmmax) | |
777 | return (0); | |
778 | /* | |
779 | * Search for a piece of the resource map which has enough | |
780 | * free space to accomodate the request. | |
781 | */ | |
782 | for (bp = ep; bp->m_size; bp++) { | |
783 | if (bp->m_size >= size) { | |
784 | /* | |
785 | * If allocating from swapmap, | |
786 | * then have to respect interleaving | |
787 | * boundaries. | |
788 | */ | |
789 | if (nswdev > 1 && | |
790 | (first = dmmax - bp->m_addr%dmmax) < bp->m_size) { | |
791 | if (bp->m_size - first < size) | |
792 | continue; | |
793 | addr = bp->m_addr + first; | |
794 | rest = bp->m_size - first - size; | |
795 | bp->m_size = first; | |
796 | if (rest) | |
797 | rmfree(mp, rest, addr+size); | |
798 | return (addr); | |
799 | } | |
800 | /* | |
801 | * Allocate from the map. | |
802 | * If there is no space left of the piece | |
803 | * we allocated from, move the rest of | |
804 | * the pieces to the left. | |
805 | */ | |
806 | addr = bp->m_addr; | |
807 | bp->m_addr += size; | |
808 | if ((bp->m_size -= size) == 0) { | |
809 | do { | |
810 | bp++; | |
811 | (bp-1)->m_addr = bp->m_addr; | |
812 | } while ((bp-1)->m_size = bp->m_size); | |
813 | } | |
814 | if (addr % CLSIZE) | |
815 | return (0); | |
816 | return (addr); | |
817 | } | |
818 | } | |
819 | return (0); | |
820 | } | |
821 | ||
822 | /* | |
823 | * Free the previously allocated space at addr | |
824 | * of size units into the specified map. | |
825 | * Sort addr into map and combine on | |
826 | * one or both ends if possible. | |
827 | */ | |
828 | rmfree(mp, size, addr) | |
829 | struct map *mp; | |
830 | long size, addr; | |
831 | { | |
832 | struct mapent *firstbp; | |
833 | register struct mapent *bp; | |
834 | register int t; | |
835 | ||
836 | /* | |
837 | * Both address and size must be | |
838 | * positive, or the protocol has broken down. | |
839 | */ | |
840 | if (addr <= 0 || size <= 0) | |
841 | goto badrmfree; | |
842 | /* | |
843 | * Locate the piece of the map which starts after the | |
844 | * returned space (or the end of the map). | |
845 | */ | |
846 | firstbp = bp = (struct mapent *)(mp + 1); | |
847 | for (; bp->m_addr <= addr && bp->m_size != 0; bp++) | |
848 | continue; | |
849 | /* | |
850 | * If the piece on the left abuts us, | |
851 | * then we should combine with it. | |
852 | */ | |
853 | if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) { | |
854 | /* | |
855 | * Check no overlap (internal error). | |
856 | */ | |
857 | if ((bp-1)->m_addr+(bp-1)->m_size > addr) | |
858 | goto badrmfree; | |
859 | /* | |
860 | * Add into piece on the left by increasing its size. | |
861 | */ | |
862 | (bp-1)->m_size += size; | |
863 | /* | |
864 | * If the combined piece abuts the piece on | |
865 | * the right now, compress it in also, | |
866 | * by shifting the remaining pieces of the map over. | |
867 | */ | |
868 | if (bp->m_addr && addr+size >= bp->m_addr) { | |
869 | if (addr+size > bp->m_addr) | |
870 | goto badrmfree; | |
871 | (bp-1)->m_size += bp->m_size; | |
872 | while (bp->m_size) { | |
873 | bp++; | |
874 | (bp-1)->m_addr = bp->m_addr; | |
875 | (bp-1)->m_size = bp->m_size; | |
876 | } | |
877 | } | |
878 | goto done; | |
879 | } | |
880 | /* | |
881 | * Don't abut on the left, check for abutting on | |
882 | * the right. | |
883 | */ | |
884 | if (addr+size >= bp->m_addr && bp->m_size) { | |
885 | if (addr+size > bp->m_addr) | |
886 | goto badrmfree; | |
887 | bp->m_addr -= size; | |
888 | bp->m_size += size; | |
889 | goto done; | |
890 | } | |
891 | /* | |
892 | * Don't abut at all. Make a new entry | |
893 | * and check for map overflow. | |
894 | */ | |
895 | do { | |
896 | t = bp->m_addr; | |
897 | bp->m_addr = addr; | |
898 | addr = t; | |
899 | t = bp->m_size; | |
900 | bp->m_size = size; | |
901 | bp++; | |
902 | } while (size = t); | |
903 | /* | |
904 | * Segment at bp is to be the delimiter; | |
905 | * If there is not room for it | |
906 | * then the table is too full | |
907 | * and we must discard something. | |
908 | */ | |
909 | if (bp+1 > mp->m_limit) { | |
910 | /* | |
911 | * Back bp up to last available segment. | |
912 | * which contains a segment already and must | |
913 | * be made into the delimiter. | |
914 | * Discard second to last entry, | |
915 | * since it is presumably smaller than the last | |
916 | * and move the last entry back one. | |
917 | */ | |
918 | bp--; | |
919 | printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name, | |
920 | (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size); | |
921 | bp[-1] = bp[0]; | |
922 | bp[0].m_size = bp[0].m_addr = 0; | |
923 | } | |
924 | done: | |
925 | return; | |
926 | badrmfree: | |
927 | printf("bad rmfree\n"); | |
ceb84881 | 928 | } |