un-barfup pstat
[unix-history] / usr / src / usr.sbin / pstat / pstat.c
CommitLineData
54298f71 1static char *sccsid = "@(#)pstat.c 4.2 (Berkeley) %G%";
ceb84881
BJ
2/*
3 * Print system stuff
4 */
5
6#define mask(x) (x&0377)
7#define clear(x) ((int)x&0x7fffffff)
8
9#include <sys/param.h>
10#include <sys/dir.h>
11#include <sys/file.h>
12#include <sys/user.h>
13#include <sys/proc.h>
14#include <sys/text.h>
15#include <sys/inode.h>
16#include <sys/map.h>
17#include <sys/tty.h>
18#include <sys/conf.h>
19#include <sys/vm.h>
20#include <nlist.h>
21#include <sys/pte.h>
22
23char *fcore = "/dev/kmem";
24char *fnlist = "/vmunix";
25int fc;
26
27struct nlist nl[] = {
28#define SINODE 0
29 { "_inode" },
30#define STEXT 1
31 { "_text" },
32#define SPROC 2
33 { "_proc" },
34#define SDZ 3
35 { "_dz_tty" },
36#define SNDZ 4
37 { "_dz_cnt" },
38#define SKL 5
39 { "_cons" },
40#define SFIL 6
41 { "_file" },
42#define USRPTMA 7
43 { "_Usrptmap" },
44#define USRPT 8
45 { "_usrpt" },
46#define SNSWAP 9
47 { "_nswap" },
48#define SWAPMAP 10
49 { "_swapmap" },
50#define SDH 11
51 { "_dh11" },
52#define SNDH 12
53 { "_ndh11" },
54 0,
55};
56
57int inof;
58int txtf;
59int prcf;
60int ttyf;
61int usrf;
62long ubase;
63int filf;
64int swpf;
65int totflg;
66char partab[1];
67struct cdevsw cdevsw[1];
68struct bdevsw bdevsw[1];
69int allflg;
70int kflg;
71struct pte *Usrptma;
72struct pte *usrpt;
73
74main(argc, argv)
75char **argv;
76{
77 register char *argp;
78
79 argc--, argv++;
80 while (argc > 0 && **argv == '-') {
81 argp = *argv++;
82 argp++;
83 argc--;
84 while (*argp++)
85 switch (argp[-1]) {
86
87 case 'T':
88 totflg++;
89 break;
90
91 case 'a':
92 allflg++;
93 break;
94
95 case 'i':
96 inof++;
97 break;
98
99 case 'k':
100 kflg++;
101 fcore = "/vmcore";
102 break;
103
104 case 'x':
105 txtf++;
106 break;
107
108 case 'p':
109 prcf++;
110 break;
111
112 case 't':
113 ttyf++;
114 break;
115
116 case 'u':
117 if (argc == 0)
118 break;
119 argc--;
120 usrf++;
121 sscanf( *argv++, "%x", &ubase);
122 break;
123
124 case 'f':
125 filf++;
126 break;
127 case 's':
128 swpf++;
129 break;
130 }
131 }
132 if (argc>0)
133 fcore = argv[0];
134 if ((fc = open(fcore, 0)) < 0) {
135 printf("Can't find %s\n", fcore);
136 exit(1);
137 }
138 if (argc>1)
139 fnlist = argv[1];
140 nlist(fnlist, nl);
141 if (kflg) {
142 register struct nlist *nlp;
143 for (nlp=nl; nlp < &nl[sizeof (nl)/sizeof(nl[0])]; nlp++)
144 nlp->n_value = clear(nlp->n_value);
145 }
146 usrpt = (struct pte *)nl[USRPT].n_value;
147 Usrptma = (struct pte *)nl[USRPTMA].n_value;
148 if (nl[0].n_type == 0) {
149 printf("no namelist\n");
150 exit(1);
151 }
152 if (filf||totflg)
153 dofil();
154 if (inof||totflg)
155 doinode();
156 if (prcf||totflg)
157 doproc();
158 if (txtf||totflg)
159 dotext();
160 if (ttyf)
161 dotty();
162 if (usrf)
163 dousr();
164 if (swpf||totflg)
165 doswap();
166}
167
168doinode()
169{
170 register struct inode *ip;
171 struct inode xinode[NINODE];
172 register int nin, loc;
173
174 nin = 0;
175 lseek(fc, (long)nl[SINODE].n_value, 0);
176 read(fc, xinode, sizeof(xinode));
177 for (ip = xinode; ip < &xinode[NINODE]; ip++)
178 if (ip->i_count)
179 nin++;
180 if (totflg) {
181 printf("%3d/%3d inodes\n", nin, NINODE);
182 return;
183 }
184 printf("%d/%d active xinodes\n", nin, NINODE);
185 printf(" LOC FLAGS CNT DEVICE INO MODE NLK UID SIZE/DEV\n");
186 loc = nl[SINODE].n_value;
187 for (ip = xinode; ip < &xinode[NINODE]; ip++, loc += sizeof(xinode[0])) {
188 if (ip->i_count == 0)
189 continue;
190 printf("%8.1x ", loc);
191 putf(ip->i_flag&ILOCK, 'L');
192 putf(ip->i_flag&IUPD, 'U');
193 putf(ip->i_flag&IACC, 'A');
194 putf(ip->i_flag&IMOUNT, 'M');
195 putf(ip->i_flag&IWANT, 'W');
196 putf(ip->i_flag&ITEXT, 'T');
197 printf("%4d", ip->i_count&0377);
198 printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev));
199 printf("%6d", ip->i_number);
200 printf("%6x", ip->i_mode & 0xffff);
201 printf("%4d", ip->i_nlink);
202 printf("%4d", ip->i_uid);
203 if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR)
204 printf("%6d,%3d", major(ip->i_un.i_rdev), minor(ip->i_un.i_rdev));
205 else
206 printf("%10ld", ip->i_size);
207 printf("\n");
208 }
209}
210
211putf(v, n)
212{
213 if (v)
214 printf("%c", n);
215 else
216 printf(" ");
217}
218
219dotext()
220{
221 register struct text *xp;
222 struct text xtext[NTEXT];
223 register loc;
224 int ntx;
225
226 ntx = 0;
227 lseek(fc, (long)nl[STEXT].n_value, 0);
228 read(fc, xtext, sizeof(xtext));
229 for (xp = xtext; xp < &xtext[NTEXT]; xp++)
230 if (xp->x_iptr!=NULL)
231 ntx++;
232 if (totflg) {
233 printf("%3d/%3d texts\n", ntx, NTEXT);
234 return;
235 }
54298f71 236 printf(" LOC FLAGS DADDR CADDR RSS SIZE IPTR CNT CCNT\n");
ceb84881
BJ
237 loc = nl[STEXT].n_value;
238 for (xp = xtext; xp < &xtext[NTEXT]; xp++, loc+=sizeof(xtext[0])) {
239 if (xp->x_iptr == NULL)
240 continue;
241 printf("%8.1x", loc);
242 printf(" ");
243 putf(xp->x_flag&XPAGI, 'P');
244 putf(xp->x_flag&XTRC, 'T');
245 putf(xp->x_flag&XWRIT, 'W');
246 putf(xp->x_flag&XLOAD, 'L');
247 putf(xp->x_flag&XLOCK, 'K');
248 putf(xp->x_flag&XWANT, 'w');
ceb84881
BJ
249 printf("%5x", xp->x_daddr[0]);
250 printf("%11x", xp->x_caddr);
251 printf("%5d", xp->x_rssize);
252 printf("%5d", xp->x_size);
253 printf("%10.1x", xp->x_iptr);
254 printf("%5d", xp->x_count&0377);
54298f71 255 printf("%5d", xp->x_ccount);
ceb84881
BJ
256 printf("\n");
257 }
258}
259
260doproc()
261{
262 struct proc xproc[NPROC];
263 register struct proc *pp;
264 register loc, np;
265 struct pte apte;
266
267 lseek(fc, (long)nl[SPROC].n_value, 0);
268 read(fc, xproc, sizeof(xproc));
269 np = 0;
270 for (pp=xproc; pp < &xproc[NPROC]; pp++)
271 if (pp->p_stat)
272 np++;
273 if (totflg) {
274 printf("%3d/%3d processes\n", np, NPROC);
275 return;
276 }
277 printf("%d/%d processes\n", np, NPROC);
54298f71 278 printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP CLKT\n");
ceb84881
BJ
279 for (loc=nl[SPROC].n_value,pp=xproc; pp<&xproc[NPROC]; pp++,loc+=sizeof(xproc[0])) {
280 if (pp->p_stat==0 && allflg==0)
281 continue;
282 printf("%8x", loc);
283 printf(" %2d", pp->p_stat);
284 printf(" %4x", pp->p_flag & 0xffff);
285 printf(" %4d", pp->p_poip);
286 printf(" %3d", pp->p_pri);
54298f71 287 printf(" %8x", pp->p_sig);
ceb84881
BJ
288 printf(" %4d", pp->p_uid);
289 printf(" %3d", pp->p_slptime);
290 printf(" %3d", pp->p_time);
291 printf(" %4d", pp->p_cpu&0377);
292 printf(" %3d", pp->p_nice);
293 printf(" %6d", pp->p_pgrp);
294 printf(" %6d", pp->p_pid);
295 printf(" %6d", pp->p_ppid);
296 if (kflg)
297 pp->p_addr = (struct pte *)clear((int)pp->p_addr);
298 lseek(fc, (long)(Usrptma+btokmx(pp->p_addr)), 0);
299 read(fc, &apte, sizeof(apte));
300 printf(" %8x", ctob(apte.pg_pfnum+1) - sizeof(struct pte) * UPAGES);
301 printf(" %4x", pp->p_rssize);
302 printf(" %4x", pp->p_swrss);
303 printf(" %5x", pp->p_dsize+pp->p_ssize);
304 printf(" %7x", clear(pp->p_wchan));
305 printf(" %7x", clear(pp->p_link));
306 printf(" %7x", clear(pp->p_textp));
307 printf(" %u", pp->p_clktim);
308 printf("\n");
309 }
310}
311
312dotty()
313{
314 struct tty dz_tty[64];
315 int ndz;
316 register struct tty *tp;
317 register char *mesg;
318
319 printf("1 cons\n");
320 lseek(fc, (long)nl[SKL].n_value, 0);
321 read(fc, dz_tty, sizeof(dz_tty[0]));
322 mesg = " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n";
323 printf(mesg);
324 ttyprt(&dz_tty[0], 0);
325 if (nl[SNDZ].n_type == -1)
326 goto dh;
327 lseek(fc, (long)nl[SNDZ].n_value, 0);
328 read(fc, &ndz, sizeof(ndz));
329 printf("%d dz lines\n", ndz);
330 lseek(fc, (long)nl[SDZ].n_value, 0);
331 read(fc, dz_tty, sizeof(dz_tty));
332 for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
333 ttyprt(tp, tp - dz_tty);
334dh:
335 if (nl[SNDH].n_type == -1)
336 return;
337 lseek(fc, (long)nl[SNDH].n_value, 0);
338 read(fc, &ndz, sizeof(ndz));
339 printf("%d dh lines\n", ndz);
340 lseek(fc, (long)nl[SDH].n_value, 0);
341 read(fc, dz_tty, sizeof(dz_tty));
342 for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
343 ttyprt(tp, tp - dz_tty);
344}
345
346ttyprt(atp, line)
347struct tty *atp;
348{
349 register struct tty *tp;
350
351 printf("%2d", line);
352 tp = atp;
353 switch (tp->t_line) {
354
355 case NETLDISC:
356 if (tp->t_rec)
357 printf("%4d%4d", 0, tp->t_inbuf);
358 else
359 printf("%4d%4d", tp->t_inbuf, 0);
360 break;
361
362 default:
363 printf("%4d", tp->t_rawq.c_cc);
364 printf("%4d", tp->t_canq.c_cc);
365 }
366 printf("%4d", tp->t_outq.c_cc);
367 printf("%8.1o", tp->t_flags);
368 printf(" %8.1x", tp->t_addr);
369 printf("%3d", tp->t_delct);
370 printf("%4d ", tp->t_col);
371 putf(tp->t_state&TIMEOUT, 'T');
372 putf(tp->t_state&WOPEN, 'W');
373 putf(tp->t_state&ISOPEN, 'O');
374 putf(tp->t_state&CARR_ON, 'C');
375 putf(tp->t_state&BUSY, 'B');
376 putf(tp->t_state&ASLEEP, 'A');
377 putf(tp->t_state&XCLUDE, 'X');
378/*
379 putf(tp->t_state&HUPCLS, 'H');
380 */
381 printf("%6d", tp->t_pgrp);
382 switch (tp->t_line) {
383
384 case NTTYDISC:
385 printf(" ntty");
386 break;
387
388 case NETLDISC:
389 printf(" net");
390 break;
391 }
392 printf("\n");
393}
394
395dousr()
396{
397 struct user U;
398 register i, j, *ip;
399
400 /* This wins only if PAGSIZ > sizeof (struct user) */
401 lseek(fc, ubase * NBPG, 0);
402 read(fc, &U, sizeof(U));
403 printf("pcb");
404 ip = (int *)&U.u_pcb;
405 while (ip < &U.u_arg[0]) {
406 if ((ip - (int *)&U.u_pcb) % 4 == 0)
407 printf("\t");
408 printf("%x ", *ip++);
409 if ((ip - (int *)&U.u_pcb) % 4 == 0)
410 printf("\n");
411 }
412 if ((ip - (int *)&U.u_pcb) % 4 != 0)
413 printf("\n");
414 printf("arg\t");
415 for (i=0; i<5; i++)
416 printf(" %.1x", U.u_arg[i]);
417 printf("\n");
418 for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
419 if (i%5==0)
420 printf("\t");
421 printf("%9.1x", U.u_ssav[i]);
422 if (i%5==4)
423 printf("\n");
424 }
425 if (i%5)
426 printf("\n");
427 printf("segflg\t%d\nerror %d\n", U.u_segflg, U.u_error);
428 printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid);
429 printf("procp\t%.1x\n", U.u_procp);
430 printf("ap\t%.1x\n", U.u_ap);
431 printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2);
432 printf("base, count, offset %.1x %.1x %ld\n", U.u_base,
433 U.u_count, U.u_offset);
434 printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir);
435 printf("dbuf %.14s\n", U.u_dbuf);
436 printf("dirp %.1x\n", U.u_dirp);
437 printf("dent %d %.14s\n", U.u_dent.d_ino, U.u_dent.d_name);
438 printf("pdir %.1o\n", U.u_pdir);
439 printf("file\t");
440 for (i=0; i<10; i++)
441 printf("%9.1x", U.u_ofile[i]);
442 printf("\n\t");
443 for (i=10; i<NOFILE; i++)
444 printf("%9.1x", U.u_ofile[i]);
445 printf("\n");
446 printf("pofile\t");
447 for (i=0; i<10; i++)
448 printf("%9.1x", U.u_pofile[i]);
449 printf("\n\t");
450 for (i=10; i<NOFILE; i++)
451 printf("%9.1x", U.u_pofile[i]);
452 printf("\n");
453 printf("ssav");
454 for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
455 if (i%5==0)
456 printf("\t");
457 printf("%9.1x", U.u_ssav[i]);
458 if (i%5==4)
459 printf("\n");
460 }
461 if (i%5)
462 printf("\n");
463 printf("sigs\t");
464 for (i=0; i<NSIG; i++)
465 printf("%.1x ", U.u_signal[i]);
466 printf("\n");
467 printf("cfcode\t%.1x\n", U.u_cfcode);
468 printf("ar0\t%.1x\n", U.u_ar0);
469 printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size,
470 U.u_prof.pr_off, U.u_prof.pr_scale);
471 printf("\neosys\t%d\n", U.u_eosys);
472 printf("sep\t%d\n", U.u_sep);
473 printf("ttyp\t%.1x\n", U.u_ttyp);
474 printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd));
475 printf("exdata\t");
476 ip = (int *)&U.u_exdata;
477 for (i = 0; i < 8; i++)
478 printf("%.1D ", *ip++);
479 printf("\n");
480 printf("comm %.14s\n", U.u_comm);
481 printf("start\t%D\n", U.u_start);
482 printf("acflag\t%D\n", U.u_acflag);
483 printf("fpflag\t%D\n", U.u_fpflag);
484 printf("cmask\t%D\n", U.u_cmask);
485 printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize);
486 printf("vm\t");
487 ip = (int *)&U.u_vm;
488 for (i = 0; i < sizeof(U.u_vm)/sizeof(int); i++)
489 printf("%D ", ip[i]);
490 printf("\n");
491 ip = (int *)&U.u_cvm;
492 printf("cvm\t");
493 for (i = 0; i < sizeof(U.u_vm)/sizeof(int); i++)
494 printf("%D ", ip[i]);
495 printf("\n");
496/*
497 i = U.u_stack - &U;
498 while (U[++i] == 0);
499 i &= ~07;
500 while (i < 512) {
501 printf("%x ", 0140000+2*i);
502 for (j=0; j<8; j++)
503 printf("%9x", U[i++]);
504 printf("\n");
505 }
506*/
507}
508
509oatoi(s)
510char *s;
511{
512 register v;
513
514 v = 0;
515 while (*s)
516 v = (v<<3) + *s++ - '0';
517 return(v);
518}
519
520dofil()
521{
522 struct file xfile[NFILE];
523 register struct file *fp;
524 register nf;
525 int loc;
526
527 nf = 0;
528 lseek(fc, (long)nl[SFIL].n_value, 0);
529 read(fc, xfile, sizeof(xfile));
530 for (fp=xfile; fp < &xfile[NFILE]; fp++)
531 if (fp->f_count)
532 nf++;
533 if (totflg) {
534 printf("%3d/%3d files\n", nf, NFILE);
535 return;
536 }
537 printf("%d/%d open files\n", nf, NFILE);
538 printf(" LOC FLG CNT INO OFFS\n");
539 for (fp=xfile,loc=nl[SFIL].n_value; fp < &xfile[NFILE]; fp++,loc+=sizeof(xfile[0])) {
540 if (fp->f_count==0)
541 continue;
542 printf("%8x ", loc);
543 putf(fp->f_flag&FREAD, 'R');
544 putf(fp->f_flag&FWRITE, 'W');
545 putf(fp->f_flag&FPIPE, 'P');
546 printf("%4d", mask(fp->f_count));
547 printf("%9.1x", fp->f_inode);
548 printf(" %ld\n", fp->f_un.f_offset);
549 }
550}
551
552doswap()
553{
554 struct proc proc[NPROC];
555 struct text xtext[NTEXT];
556 struct map swapmap[SMAPSIZ];
557 register struct proc *pp;
558 int nswap, used, tused, free;
559 register struct map *mp;
560 register struct text *xp;
561
562 lseek(fc, (long)nl[SPROC].n_value, 0);
563 read(fc, proc, sizeof(proc));
564 lseek(fc, (long)nl[SWAPMAP].n_value, 0);
565 read(fc, swapmap, sizeof(swapmap));
566 lseek(fc, (long)nl[SNSWAP].n_value, 0);
567 read(fc, &nswap, sizeof(nswap));
568 free = 0;
569 for (mp = swapmap; mp < &swapmap[SMAPSIZ]; mp++)
570 free += mp->m_size;
571 lseek(fc, (long)nl[STEXT].n_value, 0);
572 read(fc, xtext, sizeof(xtext));
573 tused = 0;
574 for (xp = xtext; xp < &xtext[NTEXT]; xp++)
575 if (xp->x_iptr!=NULL)
576 tused += xdsize(xp);
577 used = tused;
578 for (pp = proc; pp < &proc[NPROC]; pp++) {
579 if (pp->p_stat == 0 || pp->p_stat == SZOMB)
580 continue;
581 if (pp->p_flag & SSYS)
582 continue;
583 used += up(pp->p_dsize) + up(pp->p_ssize);
584 if ((pp->p_flag&SLOAD) == 0)
585 used += vusize(pp);
586 }
587 /* a DMMAX block goes to argmap */
588 if (totflg) {
589 printf("%3d/%3d 00k swap\n", used/2/100, (used+free)/2/100);
590 return;
591 }
592 printf("%d used (%d text), %d free, %d missing\n",
593 used/2, tused/2, free/2, (nswap - DMMAX - (used + free))/2);
594}
595
596up(size)
597 register int size;
598{
599 register int i, block;
600
601 i = 0;
602 block = DMMIN;
603 while (i < size) {
604 i += block;
605 if (block < DMMAX)
606 block *= 2;
607 }
608 return (i);
609}
610
611vusize(p)
612struct proc *p;
613{
614 register int tsz = p->p_tsize / NPTEPG;
615
616 return (clrnd(UPAGES + clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz));
617}
618
619xdsize(xp)
620struct text *xp;
621{
622
623 if (xp->x_flag & XPAGI)
624 return (clrnd(xp->x_size + ctopt(xp->x_size)));
625 return (xp->x_size);
626}