1 static char *sccsid = "@(#)pstat.c 4.1 (Berkeley) 10/01/80"; 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 23 char *fcore = "/dev/kmem"; 24 char *fnlist = "/vmunix"; 25 int fc; 26 27 struct 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 57 int inof; 58 int txtf; 59 int prcf; 60 int ttyf; 61 int usrf; 62 long ubase; 63 int filf; 64 int swpf; 65 int totflg; 66 char partab[1]; 67 struct cdevsw cdevsw[1]; 68 struct bdevsw bdevsw[1]; 69 int allflg; 70 int kflg; 71 struct pte *Usrptma; 72 struct pte *usrpt; 73 74 main(argc, argv) 75 char **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 168 doinode() 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 211 putf(v, n) 212 { 213 if (v) 214 printf("%c", n); 215 else 216 printf(" "); 217 } 218 219 dotext() 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 } 236 printf(" LOC FLAGS PTDADDR DADDR CADDR RSS SIZE IPTR CNT CCNT\n"); 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'); 249 printf("%8x", xp->x_ptdaddr); 250 printf("%5x", xp->x_daddr[0]); 251 printf("%11x", xp->x_caddr); 252 printf("%5d", xp->x_rssize); 253 printf("%5d", xp->x_size); 254 printf("%10.1x", xp->x_iptr); 255 printf("%5d", xp->x_count&0377); 256 printf("%4d", xp->x_ccount); 257 printf("\n"); 258 } 259 } 260 261 doproc() 262 { 263 struct proc xproc[NPROC]; 264 register struct proc *pp; 265 register loc, np; 266 struct pte apte; 267 268 lseek(fc, (long)nl[SPROC].n_value, 0); 269 read(fc, xproc, sizeof(xproc)); 270 np = 0; 271 for (pp=xproc; pp < &xproc[NPROC]; pp++) 272 if (pp->p_stat) 273 np++; 274 if (totflg) { 275 printf("%3d/%3d processes\n", np, NPROC); 276 return; 277 } 278 printf("%d/%d processes\n", np, NPROC); 279 printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP CLKT\n"); 280 for (loc=nl[SPROC].n_value,pp=xproc; pp<&xproc[NPROC]; pp++,loc+=sizeof(xproc[0])) { 281 if (pp->p_stat==0 && allflg==0) 282 continue; 283 printf("%8x", loc); 284 printf(" %2d", pp->p_stat); 285 printf(" %4x", pp->p_flag & 0xffff); 286 printf(" %4d", pp->p_poip); 287 printf(" %3d", pp->p_pri); 288 printf(" %4x", pp->p_sig); 289 printf(" %4d", pp->p_uid); 290 printf(" %3d", pp->p_slptime); 291 printf(" %3d", pp->p_time); 292 printf(" %4d", pp->p_cpu&0377); 293 printf(" %3d", pp->p_nice); 294 printf(" %6d", pp->p_pgrp); 295 printf(" %6d", pp->p_pid); 296 printf(" %6d", pp->p_ppid); 297 if (kflg) 298 pp->p_addr = (struct pte *)clear((int)pp->p_addr); 299 lseek(fc, (long)(Usrptma+btokmx(pp->p_addr)), 0); 300 read(fc, &apte, sizeof(apte)); 301 printf(" %8x", ctob(apte.pg_pfnum+1) - sizeof(struct pte) * UPAGES); 302 printf(" %4x", pp->p_rssize); 303 printf(" %4x", pp->p_swrss); 304 printf(" %5x", pp->p_dsize+pp->p_ssize); 305 printf(" %7x", clear(pp->p_wchan)); 306 printf(" %7x", clear(pp->p_link)); 307 printf(" %7x", clear(pp->p_textp)); 308 printf(" %u", pp->p_clktim); 309 printf("\n"); 310 } 311 } 312 313 dotty() 314 { 315 struct tty dz_tty[64]; 316 int ndz; 317 register struct tty *tp; 318 register char *mesg; 319 320 printf("1 cons\n"); 321 lseek(fc, (long)nl[SKL].n_value, 0); 322 read(fc, dz_tty, sizeof(dz_tty[0])); 323 mesg = " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n"; 324 printf(mesg); 325 ttyprt(&dz_tty[0], 0); 326 if (nl[SNDZ].n_type == -1) 327 goto dh; 328 lseek(fc, (long)nl[SNDZ].n_value, 0); 329 read(fc, &ndz, sizeof(ndz)); 330 printf("%d dz lines\n", ndz); 331 lseek(fc, (long)nl[SDZ].n_value, 0); 332 read(fc, dz_tty, sizeof(dz_tty)); 333 for (tp = dz_tty; tp < &dz_tty[ndz]; tp++) 334 ttyprt(tp, tp - dz_tty); 335 dh: 336 if (nl[SNDH].n_type == -1) 337 return; 338 lseek(fc, (long)nl[SNDH].n_value, 0); 339 read(fc, &ndz, sizeof(ndz)); 340 printf("%d dh lines\n", ndz); 341 lseek(fc, (long)nl[SDH].n_value, 0); 342 read(fc, dz_tty, sizeof(dz_tty)); 343 for (tp = dz_tty; tp < &dz_tty[ndz]; tp++) 344 ttyprt(tp, tp - dz_tty); 345 } 346 347 ttyprt(atp, line) 348 struct tty *atp; 349 { 350 register struct tty *tp; 351 352 printf("%2d", line); 353 tp = atp; 354 switch (tp->t_line) { 355 356 case NETLDISC: 357 if (tp->t_rec) 358 printf("%4d%4d", 0, tp->t_inbuf); 359 else 360 printf("%4d%4d", tp->t_inbuf, 0); 361 break; 362 363 default: 364 printf("%4d", tp->t_rawq.c_cc); 365 printf("%4d", tp->t_canq.c_cc); 366 } 367 printf("%4d", tp->t_outq.c_cc); 368 printf("%8.1o", tp->t_flags); 369 printf(" %8.1x", tp->t_addr); 370 printf("%3d", tp->t_delct); 371 printf("%4d ", tp->t_col); 372 putf(tp->t_state&TIMEOUT, 'T'); 373 putf(tp->t_state&WOPEN, 'W'); 374 putf(tp->t_state&ISOPEN, 'O'); 375 putf(tp->t_state&CARR_ON, 'C'); 376 putf(tp->t_state&BUSY, 'B'); 377 putf(tp->t_state&ASLEEP, 'A'); 378 putf(tp->t_state&XCLUDE, 'X'); 379 /* 380 putf(tp->t_state&HUPCLS, 'H'); 381 */ 382 printf("%6d", tp->t_pgrp); 383 switch (tp->t_line) { 384 385 case NTTYDISC: 386 printf(" ntty"); 387 break; 388 389 case NETLDISC: 390 printf(" net"); 391 break; 392 } 393 printf("\n"); 394 } 395 396 dousr() 397 { 398 struct user U; 399 register i, j, *ip; 400 401 /* This wins only if PAGSIZ > sizeof (struct user) */ 402 lseek(fc, ubase * NBPG, 0); 403 read(fc, &U, sizeof(U)); 404 printf("pcb"); 405 ip = (int *)&U.u_pcb; 406 while (ip < &U.u_arg[0]) { 407 if ((ip - (int *)&U.u_pcb) % 4 == 0) 408 printf("\t"); 409 printf("%x ", *ip++); 410 if ((ip - (int *)&U.u_pcb) % 4 == 0) 411 printf("\n"); 412 } 413 if ((ip - (int *)&U.u_pcb) % 4 != 0) 414 printf("\n"); 415 printf("arg\t"); 416 for (i=0; i<5; i++) 417 printf(" %.1x", U.u_arg[i]); 418 printf("\n"); 419 for (i=0; i<sizeof(label_t)/sizeof(int); i++) { 420 if (i%5==0) 421 printf("\t"); 422 printf("%9.1x", U.u_ssav[i]); 423 if (i%5==4) 424 printf("\n"); 425 } 426 if (i%5) 427 printf("\n"); 428 printf("segflg\t%d\nerror %d\n", U.u_segflg, U.u_error); 429 printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid); 430 printf("procp\t%.1x\n", U.u_procp); 431 printf("ap\t%.1x\n", U.u_ap); 432 printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2); 433 printf("base, count, offset %.1x %.1x %ld\n", U.u_base, 434 U.u_count, U.u_offset); 435 printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir); 436 printf("dbuf %.14s\n", U.u_dbuf); 437 printf("dirp %.1x\n", U.u_dirp); 438 printf("dent %d %.14s\n", U.u_dent.d_ino, U.u_dent.d_name); 439 printf("pdir %.1o\n", U.u_pdir); 440 printf("file\t"); 441 for (i=0; i<10; i++) 442 printf("%9.1x", U.u_ofile[i]); 443 printf("\n\t"); 444 for (i=10; i<NOFILE; i++) 445 printf("%9.1x", U.u_ofile[i]); 446 printf("\n"); 447 printf("pofile\t"); 448 for (i=0; i<10; i++) 449 printf("%9.1x", U.u_pofile[i]); 450 printf("\n\t"); 451 for (i=10; i<NOFILE; i++) 452 printf("%9.1x", U.u_pofile[i]); 453 printf("\n"); 454 printf("ssav"); 455 for (i=0; i<sizeof(label_t)/sizeof(int); i++) { 456 if (i%5==0) 457 printf("\t"); 458 printf("%9.1x", U.u_ssav[i]); 459 if (i%5==4) 460 printf("\n"); 461 } 462 if (i%5) 463 printf("\n"); 464 printf("sigs\t"); 465 for (i=0; i<NSIG; i++) 466 printf("%.1x ", U.u_signal[i]); 467 printf("\n"); 468 printf("cfcode\t%.1x\n", U.u_cfcode); 469 printf("ar0\t%.1x\n", U.u_ar0); 470 printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size, 471 U.u_prof.pr_off, U.u_prof.pr_scale); 472 printf("\neosys\t%d\n", U.u_eosys); 473 printf("sep\t%d\n", U.u_sep); 474 printf("ttyp\t%.1x\n", U.u_ttyp); 475 printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd)); 476 printf("exdata\t"); 477 ip = (int *)&U.u_exdata; 478 for (i = 0; i < 8; i++) 479 printf("%.1D ", *ip++); 480 printf("\n"); 481 printf("comm %.14s\n", U.u_comm); 482 printf("start\t%D\n", U.u_start); 483 printf("acflag\t%D\n", U.u_acflag); 484 printf("fpflag\t%D\n", U.u_fpflag); 485 printf("cmask\t%D\n", U.u_cmask); 486 printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize); 487 printf("vm\t"); 488 ip = (int *)&U.u_vm; 489 for (i = 0; i < sizeof(U.u_vm)/sizeof(int); i++) 490 printf("%D ", ip[i]); 491 printf("\n"); 492 ip = (int *)&U.u_cvm; 493 printf("cvm\t"); 494 for (i = 0; i < sizeof(U.u_vm)/sizeof(int); i++) 495 printf("%D ", ip[i]); 496 printf("\n"); 497 /* 498 i = U.u_stack - &U; 499 while (U[++i] == 0); 500 i &= ~07; 501 while (i < 512) { 502 printf("%x ", 0140000+2*i); 503 for (j=0; j<8; j++) 504 printf("%9x", U[i++]); 505 printf("\n"); 506 } 507 */ 508 } 509 510 oatoi(s) 511 char *s; 512 { 513 register v; 514 515 v = 0; 516 while (*s) 517 v = (v<<3) + *s++ - '0'; 518 return(v); 519 } 520 521 dofil() 522 { 523 struct file xfile[NFILE]; 524 register struct file *fp; 525 register nf; 526 int loc; 527 528 nf = 0; 529 lseek(fc, (long)nl[SFIL].n_value, 0); 530 read(fc, xfile, sizeof(xfile)); 531 for (fp=xfile; fp < &xfile[NFILE]; fp++) 532 if (fp->f_count) 533 nf++; 534 if (totflg) { 535 printf("%3d/%3d files\n", nf, NFILE); 536 return; 537 } 538 printf("%d/%d open files\n", nf, NFILE); 539 printf(" LOC FLG CNT INO OFFS\n"); 540 for (fp=xfile,loc=nl[SFIL].n_value; fp < &xfile[NFILE]; fp++,loc+=sizeof(xfile[0])) { 541 if (fp->f_count==0) 542 continue; 543 printf("%8x ", loc); 544 putf(fp->f_flag&FREAD, 'R'); 545 putf(fp->f_flag&FWRITE, 'W'); 546 putf(fp->f_flag&FPIPE, 'P'); 547 printf("%4d", mask(fp->f_count)); 548 printf("%9.1x", fp->f_inode); 549 printf(" %ld\n", fp->f_un.f_offset); 550 } 551 } 552 553 doswap() 554 { 555 struct proc proc[NPROC]; 556 struct text xtext[NTEXT]; 557 struct map swapmap[SMAPSIZ]; 558 register struct proc *pp; 559 int nswap, used, tused, free; 560 register struct map *mp; 561 register struct text *xp; 562 563 lseek(fc, (long)nl[SPROC].n_value, 0); 564 read(fc, proc, sizeof(proc)); 565 lseek(fc, (long)nl[SWAPMAP].n_value, 0); 566 read(fc, swapmap, sizeof(swapmap)); 567 lseek(fc, (long)nl[SNSWAP].n_value, 0); 568 read(fc, &nswap, sizeof(nswap)); 569 free = 0; 570 for (mp = swapmap; mp < &swapmap[SMAPSIZ]; mp++) 571 free += mp->m_size; 572 lseek(fc, (long)nl[STEXT].n_value, 0); 573 read(fc, xtext, sizeof(xtext)); 574 tused = 0; 575 for (xp = xtext; xp < &xtext[NTEXT]; xp++) 576 if (xp->x_iptr!=NULL) 577 tused += xdsize(xp); 578 used = tused; 579 for (pp = proc; pp < &proc[NPROC]; pp++) { 580 if (pp->p_stat == 0 || pp->p_stat == SZOMB) 581 continue; 582 if (pp->p_flag & SSYS) 583 continue; 584 used += up(pp->p_dsize) + up(pp->p_ssize); 585 if ((pp->p_flag&SLOAD) == 0) 586 used += vusize(pp); 587 } 588 /* a DMMAX block goes to argmap */ 589 if (totflg) { 590 printf("%3d/%3d 00k swap\n", used/2/100, (used+free)/2/100); 591 return; 592 } 593 printf("%d used (%d text), %d free, %d missing\n", 594 used/2, tused/2, free/2, (nswap - DMMAX - (used + free))/2); 595 } 596 597 up(size) 598 register int size; 599 { 600 register int i, block; 601 602 i = 0; 603 block = DMMIN; 604 while (i < size) { 605 i += block; 606 if (block < DMMAX) 607 block *= 2; 608 } 609 return (i); 610 } 611 612 vusize(p) 613 struct proc *p; 614 { 615 register int tsz = p->p_tsize / NPTEPG; 616 617 return (clrnd(UPAGES + clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz)); 618 } 619 620 xdsize(xp) 621 struct text *xp; 622 { 623 624 if (xp->x_flag & XPAGI) 625 return (clrnd(xp->x_size + ctopt(xp->x_size))); 626 return (xp->x_size); 627 } 628