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