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