|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)pstat.c 4.24 (Berkeley) 10/15/83"; ! 3: #endif ! 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> ! 13: #define KERNEL ! 14: #include <sys/file.h> ! 15: #undef KERNEL ! 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> ! 21: #include <sys/ioctl.h> ! 22: #include <sys/tty.h> ! 23: #include <sys/conf.h> ! 24: #include <sys/vm.h> ! 25: #include <nlist.h> ! 26: #include <machine/pte.h> ! 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 SWAPMAP 9 ! 52: { "_swapmap" }, ! 53: #define SDH 10 ! 54: { "_dh11" }, ! 55: #define SNDH 11 ! 56: { "_ndh11" }, ! 57: #define SNPROC 12 ! 58: { "_nproc" }, ! 59: #define SNTEXT 13 ! 60: { "_ntext" }, ! 61: #define SNFILE 14 ! 62: { "_nfile" }, ! 63: #define SNINODE 15 ! 64: { "_ninode" }, ! 65: #define SNSWAPMAP 16 ! 66: { "_nswapmap" }, ! 67: #define SPTY 17 ! 68: { "_pt_tty" }, ! 69: #define SDMMIN 18 ! 70: { "_dmmin" }, ! 71: #define SDMMAX 19 ! 72: { "_dmmax" }, ! 73: #define SNSWDEV 20 ! 74: { "_nswdev" }, ! 75: #define SSWDEVT 21 ! 76: { "_swdevt" }, ! 77: { "" } ! 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; ! 101: int allflags; ! 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; ! 154: default: ! 155: usage(); ! 156: exit(1); ! 157: } ! 158: } ! 159: if (argc>1) ! 160: fcore = argv[1]; ! 161: if ((fc = open(fcore, 0)) < 0) { ! 162: printf("Can't find %s\n", fcore); ! 163: exit(1); ! 164: } ! 165: if (argc>0) ! 166: fnlist = argv[0]; ! 167: nlist(fnlist, nl); ! 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: } ! 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: } ! 179: if (filf||totflg) ! 180: dofile(); ! 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: ! 195: usage() ! 196: { ! 197: ! 198: printf("usage: pstat -[aixptfs] [-u [ubase]] [system] [core]\n"); ! 199: } ! 200: ! 201: doinode() ! 202: { ! 203: register struct inode *ip; ! 204: struct inode *xinode, *ainode; ! 205: register int nin; ! 206: int ninode; ! 207: ! 208: nin = 0; ! 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++) ! 214: if (ip->i_count) ! 215: nin++; ! 216: if (totflg) { ! 217: printf("%3d/%3d inodes\n", nin, ninode); ! 218: return; ! 219: } ! 220: printf("%d/%d active inodes\n", nin, ninode); ! 221: printf(" LOC FLAGS CNT DEVICE RDC WRC INO MODE NLK UID SIZE/DEV\n"); ! 222: for (ip = xinode; ip < &xinode[ninode]; ip++) { ! 223: if (ip->i_count == 0) ! 224: continue; ! 225: printf("%8.1x ", ainode + (ip - xinode)); ! 226: putf(ip->i_flag&ILOCKED, 'L'); ! 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'); ! 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'); ! 236: printf("%4d", ip->i_count&0377); ! 237: printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev)); ! 238: printf("%4d", ip->i_shlockc&0377); ! 239: printf("%4d", ip->i_exlockc&0377); ! 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) ! 245: printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev)); ! 246: else ! 247: printf("%10ld", ip->i_size); ! 248: printf("\n"); ! 249: } ! 250: free(xinode); ! 251: } ! 252: ! 253: getw(loc) ! 254: off_t loc; ! 255: { ! 256: int word; ! 257: ! 258: if (kflg) ! 259: loc &= 0x7fffffff; ! 260: lseek(fc, loc, 0); ! 261: read(fc, &word, sizeof (word)); ! 262: if (kflg) ! 263: word &= 0x7fffffff; ! 264: return (word); ! 265: } ! 266: ! 267: putf(v, n) ! 268: { ! 269: if (v) ! 270: printf("%c", n); ! 271: else ! 272: printf(" "); ! 273: } ! 274: ! 275: dotext() ! 276: { ! 277: register struct text *xp; ! 278: int ntext; ! 279: struct text *xtext, *atext; ! 280: int ntx; ! 281: ! 282: ntx = 0; ! 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++) ! 288: if (xp->x_iptr!=NULL) ! 289: ntx++; ! 290: if (totflg) { ! 291: printf("%3d/%3d texts\n", ntx, ntext); ! 292: return; ! 293: } ! 294: printf("%d/%d active texts\n", ntx, ntext); ! 295: printf(" LOC FLAGS DADDR CADDR RSS SIZE IPTR CNT CCNT\n"); ! 296: for (xp = xtext; xp < &xtext[ntext]; xp++) { ! 297: if (xp->x_iptr == NULL) ! 298: continue; ! 299: printf("%8.1x", atext + (xp - xtext)); ! 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'); ! 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); ! 313: printf("%5d", xp->x_ccount); ! 314: printf("\n"); ! 315: } ! 316: free(xtext); ! 317: } ! 318: ! 319: doproc() ! 320: { ! 321: struct proc *xproc, *aproc; ! 322: int nproc; ! 323: register struct proc *pp; ! 324: register loc, np; ! 325: struct pte apte; ! 326: ! 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)); ! 331: np = 0; ! 332: for (pp=xproc; pp < &xproc[nproc]; pp++) ! 333: if (pp->p_stat) ! 334: np++; ! 335: if (totflg) { ! 336: printf("%3d/%3d processes\n", np, nproc); ! 337: return; ! 338: } ! 339: printf("%d/%d processes\n", np, nproc); ! 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"); ! 341: for (pp=xproc; pp<&xproc[nproc]; pp++) { ! 342: if (pp->p_stat==0 && allflg==0) ! 343: continue; ! 344: printf("%8x", aproc + (pp - xproc)); ! 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); ! 349: printf(" %8x", pp->p_sig); ! 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)); ! 369: printf("\n"); ! 370: } ! 371: } ! 372: ! 373: dotty() ! 374: { ! 375: struct tty dz_tty[128]; ! 376: int ndz; ! 377: register struct tty *tp; ! 378: register char *mesg; ! 379: ! 380: printf("1 cons\n"); ! 381: if (kflg) ! 382: nl[SKL].n_value = clear(nl[SKL].n_value); ! 383: lseek(fc, (long)nl[SKL].n_value, 0); ! 384: read(fc, dz_tty, sizeof(dz_tty[0])); ! 385: mesg = " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n"; ! 386: printf(mesg); ! 387: ttyprt(&dz_tty[0], 0); ! 388: if (nl[SNDZ].n_type == 0) ! 389: goto dh; ! 390: if (kflg) { ! 391: nl[SNDZ].n_value = clear(nl[SNDZ].n_value); ! 392: nl[SDZ].n_value = clear(nl[SDZ].n_value); ! 393: } ! 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); ! 398: read(fc, dz_tty, ndz * sizeof (struct tty)); ! 399: for (tp = dz_tty; tp < &dz_tty[ndz]; tp++) ! 400: ttyprt(tp, tp - dz_tty); ! 401: dh: ! 402: if (nl[SNDH].n_type == 0) ! 403: goto pty; ! 404: if (kflg) { ! 405: nl[SNDH].n_value = clear(nl[SNDH].n_value); ! 406: nl[SDH].n_value = clear(nl[SDH].n_value); ! 407: } ! 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); ! 412: read(fc, dz_tty, ndz * sizeof(struct tty)); ! 413: for (tp = dz_tty; tp < &dz_tty[ndz]; tp++) ! 414: ttyprt(tp, tp - dz_tty); ! 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: } ! 421: printf("32 pty lines\n"); ! 422: lseek(fc, (long)nl[SPTY].n_value, 0); ! 423: read(fc, dz_tty, 32*sizeof(struct tty)); ! 424: for (tp = dz_tty; tp < &dz_tty[32]; tp++) ! 425: ttyprt(tp, tp - dz_tty); ! 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: ! 437: /* ! 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; ! 444: */ ! 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); ! 451: printf("%8.1x", tp->t_flags); ! 452: printf(" %8.1x", tp->t_addr); ! 453: printf("%3d", tp->t_delct); ! 454: printf("%4d ", tp->t_col); ! 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'); ! 462: putf(tp->t_state&TS_HUPCLS, 'H'); ! 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"); ! 503: printf("%9.1x", U.u_ssave.val[i]); ! 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); ! 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"); ! 534: printf("ssave"); ! 535: for (i=0; i<sizeof(label_t)/sizeof(int); i++) { ! 536: if (i%5==0) ! 537: printf("\t"); ! 538: printf("%9.1x", U.u_ssave.val[i]); ! 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"); ! 548: printf("code\t%.1x\n", U.u_code); ! 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); ! 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); ! 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); ! 565: printf("ru\t"); ! 566: ip = (int *)&U.u_ru; ! 567: for (i = 0; i < sizeof(U.u_ru)/sizeof(int); i++) ! 568: printf("%D ", ip[i]); ! 569: printf("\n"); ! 570: ip = (int *)&U.u_cru; ! 571: printf("cru\t"); ! 572: for (i = 0; i < sizeof(U.u_cru)/sizeof(int); i++) ! 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: ! 599: dofile() ! 600: { ! 601: int nfile; ! 602: struct file *xfile, *afile; ! 603: register struct file *fp; ! 604: register nf; ! 605: int loc; ! 606: static char *dtypes[] = { "???", "inode", "socket" }; ! 607: ! 608: nf = 0; ! 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++) ! 614: if (fp->f_count) ! 615: nf++; ! 616: if (totflg) { ! 617: printf("%3d/%3d files\n", nf, nfile); ! 618: return; ! 619: } ! 620: printf("%d/%d open files\n", nf, nfile); ! 621: printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n"); ! 622: for (fp=xfile,loc=(int)afile; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) { ! 623: if (fp->f_count==0) ! 624: continue; ! 625: printf("%8x ", loc); ! 626: if (fp->f_type <= DTYPE_SOCKET) ! 627: printf("%-8.8s", dtypes[fp->f_type]); ! 628: else ! 629: printf("8d", fp->f_type); ! 630: putf(fp->f_flag&FREAD, 'R'); ! 631: putf(fp->f_flag&FWRITE, 'W'); ! 632: putf(fp->f_flag&FAPPEND, 'A'); ! 633: putf(fp->f_flag&FSHLOCK, 'S'); ! 634: putf(fp->f_flag&FEXLOCK, 'X'); ! 635: putf(fp->f_flag&FASYNC, 'I'); ! 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); ! 641: else ! 642: printf(" %ld\n", fp->f_offset); ! 643: } ! 644: } ! 645: ! 646: int dmmin, dmmax, nswdev; ! 647: ! 648: doswap() ! 649: { ! 650: struct proc *proc; ! 651: int nproc; ! 652: struct text *xtext; ! 653: int ntext; ! 654: struct map *swapmap; ! 655: int nswapmap; ! 656: struct swdevt *swdevt, *sw; ! 657: register struct proc *pp; ! 658: int nswap, used, tused, free, waste; ! 659: int db, sb; ! 660: register struct mapent *me; ! 661: register struct text *xp; ! 662: int i, j; ! 663: ! 664: nproc = getw(nl[SNPROC].n_value); ! 665: proc = (struct proc *)calloc(nproc, sizeof (struct proc)); ! 666: ntext = getw(nl[SNTEXT].n_value); ! 667: xtext = (struct text *)calloc(ntext, sizeof (struct text)); ! 668: nswapmap = getw(nl[SNSWAPMAP].n_value); ! 669: swapmap = (struct map *)calloc(nswapmap, sizeof (struct map)); ! 670: nswdev = getw(nl[SNSWDEV].n_value); ! 671: swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt)); ! 672: lseek(fc, nl[SSWDEVT].n_value, L_SET); ! 673: read(fc, swdevt, nswdev * sizeof (struct swdevt)); ! 674: lseek(fc, getw(nl[SPROC].n_value), 0); ! 675: read(fc, proc, nproc * sizeof (struct proc)); ! 676: lseek(fc, getw(nl[STEXT].n_value), 0); ! 677: read(fc, xtext, ntext * sizeof (struct text)); ! 678: lseek(fc, getw(nl[SWAPMAP].n_value), 0); ! 679: read(fc, swapmap, nswapmap * sizeof (struct map)); ! 680: swapmap->m_name = "swap"; ! 681: swapmap->m_limit = (struct mapent *)&swapmap[nswapmap]; ! 682: dmmin = getw(nl[SDMMIN].n_value); ! 683: dmmax = getw(nl[SDMMAX].n_value); ! 684: nswap = 0; ! 685: for (sw = swdevt; sw < &swdevt[nswdev]; sw++) ! 686: nswap += sw->sw_nblks, ! 687: free = 0; ! 688: for (me = (struct mapent *)(swapmap+1); ! 689: me < (struct mapent *)&swapmap[nswapmap]; me++) ! 690: free += me->m_size; ! 691: tused = 0; ! 692: for (xp = xtext; xp < &xtext[ntext]; xp++) ! 693: if (xp->x_iptr!=NULL) { ! 694: tused += ctod(xp->x_size); ! 695: if (xp->x_flag & XPAGI) ! 696: tused += ctod(ctopt(xp->x_size)); ! 697: } ! 698: used = tused; ! 699: waste = 0; ! 700: for (pp = proc; pp < &proc[nproc]; pp++) { ! 701: if (pp->p_stat == 0 || pp->p_stat == SZOMB) ! 702: continue; ! 703: if (pp->p_flag & SSYS) ! 704: continue; ! 705: db = ctod(pp->p_dsize), sb = up(db); ! 706: used += sb; ! 707: waste += sb - db; ! 708: db = ctod(pp->p_ssize), sb = up(db); ! 709: used += sb; ! 710: waste += sb - db; ! 711: if ((pp->p_flag&SLOAD) == 0) ! 712: used += vusize(pp); ! 713: } ! 714: if (totflg) { ! 715: #define btok(x) ((x) / (1024 / DEV_BSIZE)) ! 716: printf("%3d/%3d 00k swap\n", ! 717: btok(used/100), btok((used+free)/100)); ! 718: return; ! 719: } ! 720: printf("%dk used (%dk text), %dk free, %dk wasted, %dk missing\n", ! 721: btok(used), btok(tused), btok(free), btok(waste), ! 722: /* a dmmax/2 block goes to argmap */ ! 723: btok(nswap - dmmax/2 - (used + free))); ! 724: printf("avail: "); ! 725: for (i = dmmax; i >= dmmin; i /= 2) { ! 726: j = 0; ! 727: while (rmalloc(swapmap, i) != 0) ! 728: j++; ! 729: if (j) printf("%d*%dk ", j, btok(i)); ! 730: } ! 731: free = 0; ! 732: for (me = (struct mapent *)(swapmap+1); ! 733: me < (struct mapent *)&swapmap[nswapmap]; me++) ! 734: free += me->m_size; ! 735: printf("%d*1k\n", btok(free)); ! 736: } ! 737: ! 738: up(size) ! 739: register int size; ! 740: { ! 741: register int i, block; ! 742: ! 743: i = 0; ! 744: block = dmmin; ! 745: while (i < size) { ! 746: i += block; ! 747: if (block < dmmax) ! 748: block *= 2; ! 749: } ! 750: return (i); ! 751: } ! 752: ! 753: /* ! 754: * Compute number of pages to be allocated to the u. area ! 755: * and data and stack area page tables, which are stored on the ! 756: * disk immediately after the u. area. ! 757: */ ! 758: vusize(p) ! 759: register struct proc *p; ! 760: { ! 761: register int tsz = p->p_tsize / NPTEPG; ! 762: ! 763: /* ! 764: * We do not need page table space on the disk for page ! 765: * table pages wholly containing text. ! 766: */ ! 767: return (clrnd(UPAGES + ! 768: clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz)); ! 769: } ! 770: ! 771: /* ! 772: * Allocate 'size' units from the given ! 773: * map. Return the base of the allocated space. ! 774: * In a map, the addresses are increasing and the ! 775: * list is terminated by a 0 size. ! 776: * ! 777: * Algorithm is first-fit. ! 778: * ! 779: * This routine knows about the interleaving of the swapmap ! 780: * and handles that. ! 781: */ ! 782: long ! 783: rmalloc(mp, size) ! 784: register struct map *mp; ! 785: long size; ! 786: { ! 787: register struct mapent *ep = (struct mapent *)(mp+1); ! 788: register int addr; ! 789: register struct mapent *bp; ! 790: swblk_t first, rest; ! 791: ! 792: if (size <= 0 || size > dmmax) ! 793: return (0); ! 794: /* ! 795: * Search for a piece of the resource map which has enough ! 796: * free space to accomodate the request. ! 797: */ ! 798: for (bp = ep; bp->m_size; bp++) { ! 799: if (bp->m_size >= size) { ! 800: /* ! 801: * If allocating from swapmap, ! 802: * then have to respect interleaving ! 803: * boundaries. ! 804: */ ! 805: if (nswdev > 1 && ! 806: (first = dmmax - bp->m_addr%dmmax) < bp->m_size) { ! 807: if (bp->m_size - first < size) ! 808: continue; ! 809: addr = bp->m_addr + first; ! 810: rest = bp->m_size - first - size; ! 811: bp->m_size = first; ! 812: if (rest) ! 813: rmfree(mp, rest, addr+size); ! 814: return (addr); ! 815: } ! 816: /* ! 817: * Allocate from the map. ! 818: * If there is no space left of the piece ! 819: * we allocated from, move the rest of ! 820: * the pieces to the left. ! 821: */ ! 822: addr = bp->m_addr; ! 823: bp->m_addr += size; ! 824: if ((bp->m_size -= size) == 0) { ! 825: do { ! 826: bp++; ! 827: (bp-1)->m_addr = bp->m_addr; ! 828: } while ((bp-1)->m_size = bp->m_size); ! 829: } ! 830: if (addr % CLSIZE) ! 831: return (0); ! 832: return (addr); ! 833: } ! 834: } ! 835: return (0); ! 836: } ! 837: ! 838: /* ! 839: * Free the previously allocated space at addr ! 840: * of size units into the specified map. ! 841: * Sort addr into map and combine on ! 842: * one or both ends if possible. ! 843: */ ! 844: rmfree(mp, size, addr) ! 845: struct map *mp; ! 846: long size, addr; ! 847: { ! 848: struct mapent *firstbp; ! 849: register struct mapent *bp; ! 850: register int t; ! 851: ! 852: /* ! 853: * Both address and size must be ! 854: * positive, or the protocol has broken down. ! 855: */ ! 856: if (addr <= 0 || size <= 0) ! 857: goto badrmfree; ! 858: /* ! 859: * Locate the piece of the map which starts after the ! 860: * returned space (or the end of the map). ! 861: */ ! 862: firstbp = bp = (struct mapent *)(mp + 1); ! 863: for (; bp->m_addr <= addr && bp->m_size != 0; bp++) ! 864: continue; ! 865: /* ! 866: * If the piece on the left abuts us, ! 867: * then we should combine with it. ! 868: */ ! 869: if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) { ! 870: /* ! 871: * Check no overlap (internal error). ! 872: */ ! 873: if ((bp-1)->m_addr+(bp-1)->m_size > addr) ! 874: goto badrmfree; ! 875: /* ! 876: * Add into piece on the left by increasing its size. ! 877: */ ! 878: (bp-1)->m_size += size; ! 879: /* ! 880: * If the combined piece abuts the piece on ! 881: * the right now, compress it in also, ! 882: * by shifting the remaining pieces of the map over. ! 883: */ ! 884: if (bp->m_addr && addr+size >= bp->m_addr) { ! 885: if (addr+size > bp->m_addr) ! 886: goto badrmfree; ! 887: (bp-1)->m_size += bp->m_size; ! 888: while (bp->m_size) { ! 889: bp++; ! 890: (bp-1)->m_addr = bp->m_addr; ! 891: (bp-1)->m_size = bp->m_size; ! 892: } ! 893: } ! 894: goto done; ! 895: } ! 896: /* ! 897: * Don't abut on the left, check for abutting on ! 898: * the right. ! 899: */ ! 900: if (addr+size >= bp->m_addr && bp->m_size) { ! 901: if (addr+size > bp->m_addr) ! 902: goto badrmfree; ! 903: bp->m_addr -= size; ! 904: bp->m_size += size; ! 905: goto done; ! 906: } ! 907: /* ! 908: * Don't abut at all. Make a new entry ! 909: * and check for map overflow. ! 910: */ ! 911: do { ! 912: t = bp->m_addr; ! 913: bp->m_addr = addr; ! 914: addr = t; ! 915: t = bp->m_size; ! 916: bp->m_size = size; ! 917: bp++; ! 918: } while (size = t); ! 919: /* ! 920: * Segment at bp is to be the delimiter; ! 921: * If there is not room for it ! 922: * then the table is too full ! 923: * and we must discard something. ! 924: */ ! 925: if (bp+1 > mp->m_limit) { ! 926: /* ! 927: * Back bp up to last available segment. ! 928: * which contains a segment already and must ! 929: * be made into the delimiter. ! 930: * Discard second to last entry, ! 931: * since it is presumably smaller than the last ! 932: * and move the last entry back one. ! 933: */ ! 934: bp--; ! 935: printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name, ! 936: (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size); ! 937: bp[-1] = bp[0]; ! 938: bp[0].m_size = bp[0].m_addr = 0; ! 939: } ! 940: done: ! 941: return; ! 942: badrmfree: ! 943: printf("bad rmfree\n"); ! 944: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.