|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif /* not lint */ ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)pstat.c 5.18 (Berkeley) 2/27/88"; ! 15: #endif /* not lint */ ! 16: ! 17: /* ! 18: * Print system stuff ! 19: */ ! 20: ! 21: #include <sys/param.h> ! 22: #include <sys/dir.h> ! 23: #define KERNEL ! 24: #include <sys/file.h> ! 25: #undef KERNEL ! 26: #include <sys/user.h> ! 27: #include <sys/proc.h> ! 28: #include <sys/text.h> ! 29: #include <sys/inode.h> ! 30: #include <sys/map.h> ! 31: #include <sys/ioctl.h> ! 32: #include <sys/tty.h> ! 33: #include <sys/conf.h> ! 34: #include <sys/vm.h> ! 35: #include <nlist.h> ! 36: #include <machine/pte.h> ! 37: #include <stdio.h> ! 38: ! 39: #define mask(x) (x&0377) ! 40: #define clear(x) ((int)x &~ KERNBASE) ! 41: ! 42: char *fcore = "/dev/kmem"; ! 43: char *fmem = "/dev/mem"; ! 44: char *fnlist = "/vmunix"; ! 45: int fc, fm; ! 46: ! 47: struct nlist nl[] = { ! 48: #define SINODE 0 ! 49: { "_inode" }, ! 50: #define STEXT 1 ! 51: { "_text" }, ! 52: #define SPROC 2 ! 53: { "_proc" }, ! 54: #define SCONS 3 ! 55: { "_cons" }, ! 56: #define SFIL 4 ! 57: { "_file" }, ! 58: #define USRPTMA 5 ! 59: { "_Usrptmap" }, ! 60: #define USRPT 6 ! 61: { "_usrpt" }, ! 62: #define SWAPMAP 7 ! 63: { "_swapmap" }, ! 64: #define SNPROC 8 ! 65: { "_nproc" }, ! 66: #define SNTEXT 9 ! 67: { "_ntext" }, ! 68: #define SNFILE 10 ! 69: { "_nfile" }, ! 70: #define SNINODE 11 ! 71: { "_ninode" }, ! 72: #define SNSWAPMAP 12 ! 73: { "_nswapmap" }, ! 74: #define SPTY 13 ! 75: { "_pt_tty" }, ! 76: #define SDMMIN 14 ! 77: { "_dmmin" }, ! 78: #define SDMMAX 15 ! 79: { "_dmmax" }, ! 80: #define SNSWDEV 16 ! 81: { "_nswdev" }, ! 82: #define SSWDEVT 17 ! 83: { "_swdevt" }, ! 84: #define SYSMAP 18 ! 85: { "_Sysmap" }, ! 86: #define SNPTY 19 ! 87: { "_npty" }, ! 88: #ifdef vax ! 89: #define SDZ (SNPTY+1) ! 90: { "_dz_tty" }, ! 91: #define SNDZ (SNPTY+2) ! 92: { "_dz_cnt" }, ! 93: #define SDMF (SNPTY+3) ! 94: { "_dmf_tty" }, ! 95: #define SNDMF (SNPTY+4) ! 96: { "_ndmf" }, ! 97: #define SDH (SNPTY+5) ! 98: { "_dh11" }, ! 99: #define SNDH (SNPTY+6) ! 100: { "_ndh11" }, ! 101: #define SDHU (SNPTY+7) ! 102: { "_dhu_tty" }, ! 103: #define SNDHU (SNPTY+8) ! 104: { "_ndhu" }, ! 105: #define SDMZ (SNPTY+9) ! 106: { "_dmz_tty" }, ! 107: #define SNDMZ (SNPTY+10) ! 108: { "_ndmz" }, ! 109: #define SQD (SNPTY+11) ! 110: { "_qd_tty" }, ! 111: #define SNQD (SNPTY+12) ! 112: { "_nNQD" }, ! 113: #endif ! 114: #ifdef tahoe ! 115: #define SVX (SNPTY+1) ! 116: { "_vx_tty" }, ! 117: #define SNVX (SNPTY+2) ! 118: { "_nvx" }, ! 119: #define SMP (SNPTY+3) ! 120: { "_mp_tty" }, ! 121: #define SNMP (SNPTY+4) ! 122: { "_nmp" }, ! 123: #endif ! 124: { "" } ! 125: }; ! 126: ! 127: int inof; ! 128: int txtf; ! 129: int prcf; ! 130: int ttyf; ! 131: int usrf; ! 132: long ubase; ! 133: int filf; ! 134: int swpf; ! 135: int totflg; ! 136: char partab[1]; ! 137: struct cdevsw cdevsw[1]; ! 138: struct bdevsw bdevsw[1]; ! 139: int allflg; ! 140: int kflg; ! 141: struct pte *Usrptma; ! 142: struct pte *usrpt; ! 143: u_long getword(); ! 144: off_t mkphys(); ! 145: ! 146: main(argc, argv) ! 147: int argc; ! 148: char **argv; ! 149: { ! 150: extern char *optarg; ! 151: extern int optind; ! 152: int ch; ! 153: ! 154: while ((ch = getopt(argc, argv, "Tafikptu:sx")) != EOF) ! 155: switch((char)ch) { ! 156: case 'T': ! 157: totflg++; ! 158: break; ! 159: case 'a': ! 160: allflg++; ! 161: /*FALLTHROUGH*/ ! 162: case 'p': ! 163: prcf++; ! 164: break; ! 165: case 'f': ! 166: filf++; ! 167: break; ! 168: case 'i': ! 169: inof++; ! 170: break; ! 171: case 'k': /* undocumented */ ! 172: kflg++; ! 173: fcore = fmem = "/vmcore"; ! 174: break; ! 175: case 't': ! 176: ttyf++; ! 177: break; ! 178: case 'u': ! 179: usrf++; ! 180: sscanf(optarg, "%x", &ubase); ! 181: break; ! 182: case 's': ! 183: swpf++; ! 184: break; ! 185: case 'x': ! 186: txtf++; ! 187: break; ! 188: case '?': ! 189: default: ! 190: printf("usage: pstat -[Tafiptsx] [-u [ubase]] [system] [core]\n"); ! 191: exit(1); ! 192: } ! 193: argc -= optind; ! 194: argv += optind; ! 195: ! 196: if (argc>1) { ! 197: fcore = fmem = argv[1]; ! 198: kflg++; ! 199: } ! 200: if ((fc = open(fcore, O_RDONLY, 0)) < 0) { ! 201: perror(fcore); ! 202: exit(1); ! 203: } ! 204: if ((fm = open(fmem, O_RDONLY, 0)) < 0) { ! 205: perror(fmem); ! 206: exit(1); ! 207: } ! 208: if (argc>0) ! 209: fnlist = argv[0]; ! 210: nlist(fnlist, nl); ! 211: if (nl[0].n_type == 0) { ! 212: printf("pstat: no namelist.\n"); ! 213: exit(1); ! 214: } ! 215: usrpt = (struct pte *)nl[USRPT].n_value; ! 216: Usrptma = (struct pte *)nl[USRPTMA].n_value; ! 217: if (!(filf | totflg | inof | prcf | txtf | ttyf | usrf | swpf)) { ! 218: printf("pstat: one or more of -[aixptfsu] is required\n"); ! 219: exit(1); ! 220: } ! 221: if (filf||totflg) ! 222: dofile(); ! 223: if (inof||totflg) ! 224: doinode(); ! 225: if (prcf||totflg) ! 226: doproc(); ! 227: if (txtf||totflg) ! 228: dotext(); ! 229: if (ttyf) ! 230: dotty(); ! 231: if (usrf) ! 232: dousr(); ! 233: if (swpf||totflg) ! 234: doswap(); ! 235: } ! 236: ! 237: doinode() ! 238: { ! 239: register struct inode *ip; ! 240: struct inode *xinode, *ainode; ! 241: register int nin; ! 242: int ninode; ! 243: ! 244: nin = 0; ! 245: ninode = getword(nl[SNINODE].n_value); ! 246: xinode = (struct inode *)calloc(ninode, sizeof (struct inode)); ! 247: ainode = (struct inode *)getword(nl[SINODE].n_value); ! 248: if (ninode < 0 || ninode > 10000) { ! 249: fprintf(stderr, "number of inodes is preposterous (%d)\n", ! 250: ninode); ! 251: return; ! 252: } ! 253: if (xinode == NULL) { ! 254: fprintf(stderr, "can't allocate memory for inode table\n"); ! 255: return; ! 256: } ! 257: lseek(fc, mkphys((off_t)ainode), 0); ! 258: read(fc, xinode, ninode * sizeof(struct inode)); ! 259: for (ip = xinode; ip < &xinode[ninode]; ip++) ! 260: if (ip->i_count) ! 261: nin++; ! 262: if (totflg) { ! 263: printf("%3d/%3d inodes\n", nin, ninode); ! 264: return; ! 265: } ! 266: printf("%d/%d active inodes\n", nin, ninode); ! 267: printf(" LOC FLAGS CNT DEVICE RDC WRC INO MODE NLK UID SIZE/DEV\n"); ! 268: for (ip = xinode; ip < &xinode[ninode]; ip++) { ! 269: if (ip->i_count == 0) ! 270: continue; ! 271: printf("%8.1x ", ainode + (ip - xinode)); ! 272: putf(ip->i_flag&ILOCKED, 'L'); ! 273: putf(ip->i_flag&IUPD, 'U'); ! 274: putf(ip->i_flag&IACC, 'A'); ! 275: putf(ip->i_flag&IMOUNT, 'M'); ! 276: putf(ip->i_flag&IWANT, 'W'); ! 277: putf(ip->i_flag&ITEXT, 'T'); ! 278: putf(ip->i_flag&ICHG, 'C'); ! 279: putf(ip->i_flag&ISHLOCK, 'S'); ! 280: putf(ip->i_flag&IEXLOCK, 'E'); ! 281: putf(ip->i_flag&ILWAIT, 'Z'); ! 282: printf("%4d", ip->i_count&0377); ! 283: printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev)); ! 284: printf("%4d", ip->i_shlockc&0377); ! 285: printf("%4d", ip->i_exlockc&0377); ! 286: printf("%6d", ip->i_number); ! 287: printf("%6x", ip->i_mode & 0xffff); ! 288: printf("%4d", ip->i_nlink); ! 289: printf("%4d", ip->i_uid); ! 290: if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR) ! 291: printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev)); ! 292: else ! 293: printf("%10ld", ip->i_size); ! 294: printf("\n"); ! 295: } ! 296: free(xinode); ! 297: } ! 298: ! 299: u_long ! 300: getword(loc) ! 301: off_t loc; ! 302: { ! 303: u_long word; ! 304: ! 305: if (kflg) ! 306: loc = clear(loc); ! 307: lseek(fc, loc, 0); ! 308: read(fc, &word, sizeof (word)); ! 309: return (word); ! 310: } ! 311: ! 312: putf(v, n) ! 313: { ! 314: if (v) ! 315: printf("%c", n); ! 316: else ! 317: printf(" "); ! 318: } ! 319: ! 320: dotext() ! 321: { ! 322: register struct text *xp; ! 323: int ntext; ! 324: struct text *xtext, *atext; ! 325: int ntx, ntxca; ! 326: ! 327: ntx = ntxca = 0; ! 328: ntext = getword(nl[SNTEXT].n_value); ! 329: xtext = (struct text *)calloc(ntext, sizeof (struct text)); ! 330: atext = (struct text *)getword(nl[STEXT].n_value); ! 331: if (ntext < 0 || ntext > 10000) { ! 332: fprintf(stderr, "number of texts is preposterous (%d)\n", ! 333: ntext); ! 334: return; ! 335: } ! 336: if (xtext == NULL) { ! 337: fprintf(stderr, "can't allocate memory for text table\n"); ! 338: return; ! 339: } ! 340: lseek(fc, mkphys((off_t)atext), 0); ! 341: read(fc, xtext, ntext * sizeof (struct text)); ! 342: for (xp = xtext; xp < &xtext[ntext]; xp++) { ! 343: if (xp->x_iptr != NULL) ! 344: ntxca++; ! 345: if (xp->x_count != 0) ! 346: ntx++; ! 347: } ! 348: if (totflg) { ! 349: printf("%3d/%3d texts active, %3d used\n", ntx, ntext, ntxca); ! 350: return; ! 351: } ! 352: printf("%d/%d active texts, %d used\n", ntx, ntext, ntxca); ! 353: printf("\ ! 354: LOC FLAGS DADDR CADDR RSS SIZE IPTR CNT CCNT FORW BACK\n"); ! 355: for (xp = xtext; xp < &xtext[ntext]; xp++) { ! 356: if (xp->x_iptr == NULL) ! 357: continue; ! 358: printf("%8.1x", atext + (xp - xtext)); ! 359: printf(" "); ! 360: putf(xp->x_flag&XPAGI, 'P'); ! 361: putf(xp->x_flag&XTRC, 'T'); ! 362: putf(xp->x_flag&XWRIT, 'W'); ! 363: putf(xp->x_flag&XLOAD, 'L'); ! 364: putf(xp->x_flag&XLOCK, 'K'); ! 365: putf(xp->x_flag&XWANT, 'w'); ! 366: printf("%5x", xp->x_daddr[0]); ! 367: printf("%10x", xp->x_caddr); ! 368: printf("%5d", xp->x_rssize); ! 369: printf("%5d", xp->x_size); ! 370: printf("%10.1x", xp->x_iptr); ! 371: printf("%5d", xp->x_count&0377); ! 372: printf("%5d", xp->x_ccount); ! 373: printf("%10x", xp->x_forw); ! 374: printf("%9x", xp->x_back); ! 375: printf("\n"); ! 376: } ! 377: free(xtext); ! 378: } ! 379: ! 380: doproc() ! 381: { ! 382: struct proc *xproc, *aproc; ! 383: int nproc; ! 384: register struct proc *pp; ! 385: register loc, np; ! 386: struct pte apte; ! 387: ! 388: nproc = getword(nl[SNPROC].n_value); ! 389: xproc = (struct proc *)calloc(nproc, sizeof (struct proc)); ! 390: aproc = (struct proc *)getword(nl[SPROC].n_value); ! 391: if (nproc < 0 || nproc > 10000) { ! 392: fprintf(stderr, "number of procs is preposterous (%d)\n", ! 393: nproc); ! 394: return; ! 395: } ! 396: if (xproc == NULL) { ! 397: fprintf(stderr, "can't allocate memory for proc table\n"); ! 398: return; ! 399: } ! 400: lseek(fc, mkphys((off_t)aproc), 0); ! 401: read(fc, xproc, nproc * sizeof (struct proc)); ! 402: np = 0; ! 403: for (pp=xproc; pp < &xproc[nproc]; pp++) ! 404: if (pp->p_stat) ! 405: np++; ! 406: if (totflg) { ! 407: printf("%3d/%3d processes\n", np, nproc); ! 408: return; ! 409: } ! 410: printf("%d/%d processes\n", np, nproc); ! 411: printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP\n"); ! 412: for (pp=xproc; pp<&xproc[nproc]; pp++) { ! 413: if (pp->p_stat==0 && allflg==0) ! 414: continue; ! 415: printf("%8x", aproc + (pp - xproc)); ! 416: printf(" %2d", pp->p_stat); ! 417: printf(" %4x", pp->p_flag & 0xffff); ! 418: printf(" %4d", pp->p_poip); ! 419: printf(" %3d", pp->p_pri); ! 420: printf(" %8x", pp->p_sig); ! 421: printf(" %4d", pp->p_uid); ! 422: printf(" %3d", pp->p_slptime); ! 423: printf(" %3d", pp->p_time); ! 424: printf(" %4d", pp->p_cpu&0377); ! 425: printf(" %3d", pp->p_nice); ! 426: printf(" %6d", pp->p_pgrp); ! 427: printf(" %6d", pp->p_pid); ! 428: printf(" %6d", pp->p_ppid); ! 429: if (kflg) ! 430: pp->p_addr = (struct pte *)clear((int)pp->p_addr); ! 431: if (pp->p_flag & SLOAD) { ! 432: lseek(fc, (long)pp->p_addr, 0); ! 433: read(fc, &apte, sizeof(apte)); ! 434: printf(" %8x", apte.pg_pfnum); ! 435: } else ! 436: printf(" %8x", pp->p_swaddr); ! 437: printf(" %4x", pp->p_rssize); ! 438: printf(" %4x", pp->p_swrss); ! 439: printf(" %5x", pp->p_dsize+pp->p_ssize); ! 440: printf(" %7x", clear(pp->p_wchan)); ! 441: printf(" %7x", clear(pp->p_link)); ! 442: printf(" %7x", clear(pp->p_textp)); ! 443: printf("\n"); ! 444: } ! 445: free(xproc); ! 446: } ! 447: ! 448: static char mesg[] = ! 449: " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n"; ! 450: static int ttyspace = 128; ! 451: static struct tty *tty; ! 452: ! 453: dotty() ! 454: { ! 455: extern char *malloc(); ! 456: ! 457: if ((tty = (struct tty *)malloc(ttyspace * sizeof(*tty))) == 0) { ! 458: printf("pstat: out of memory\n"); ! 459: return; ! 460: } ! 461: printf("1 cons\n"); ! 462: if (kflg) ! 463: nl[SCONS].n_value = clear(nl[SCONS].n_value); ! 464: lseek(fc, (long)nl[SCONS].n_value, 0); ! 465: read(fc, tty, sizeof(*tty)); ! 466: printf(mesg); ! 467: ttyprt(&tty[0], 0); ! 468: #ifdef vax ! 469: if (nl[SNQD].n_type != 0) ! 470: doqdss(); ! 471: if (nl[SNDZ].n_type != 0) ! 472: dottytype("dz", SDZ, SNDZ); ! 473: if (nl[SNDH].n_type != 0) ! 474: dottytype("dh", SDH, SNDH); ! 475: if (nl[SNDMF].n_type != 0) ! 476: dottytype("dmf", SDMF, SNDMF); ! 477: if (nl[SNDHU].n_type != 0) ! 478: dottytype("dhu", SDHU, SNDHU); ! 479: if (nl[SNDMZ].n_type != 0) ! 480: dottytype("dmz", SDMZ, SNDMZ); ! 481: #endif ! 482: #ifdef tahoe ! 483: if (nl[SNVX].n_type != 0) ! 484: dottytype("vx", SVX, SNVX); ! 485: if (nl[SNMP].n_type != 0) ! 486: dottytype("mp", SMP, SNMP); ! 487: #endif ! 488: if (nl[SNPTY].n_type != 0) ! 489: dottytype("pty", SPTY, SNPTY); ! 490: } ! 491: ! 492: /* ! 493: * Special case the qdss because there are 4 tty structs per qdss ! 494: * and only the first of each is used as a tty. ! 495: */ ! 496: #ifdef vax ! 497: doqdss() ! 498: { ! 499: int nqd; ! 500: register struct tty *tp; ! 501: ! 502: if (kflg) { ! 503: nl[SNQD].n_value = clear(nl[SNQD].n_value); ! 504: nl[SQD].n_value = clear(nl[SQD].n_value); ! 505: } ! 506: lseek(fc, (long)nl[SNQD].n_value, 0); ! 507: read(fc, &nqd, sizeof(nqd)); ! 508: printf("%d qd\n", nqd); ! 509: lseek(fc, (long)nl[SQD].n_value, 0); ! 510: read(fc, tty, nqd * sizeof(struct tty) * 4); ! 511: printf(mesg); ! 512: for (tp = tty; tp < &tty[nqd * 4]; tp += 4) ! 513: ttyprt(tp, tp - tty); ! 514: } ! 515: #endif ! 516: ! 517: dottytype(name, type, number) ! 518: char *name; ! 519: { ! 520: int ntty; ! 521: register struct tty *tp; ! 522: extern char *realloc(); ! 523: ! 524: if (tty == (struct tty *)0) ! 525: return; ! 526: if (kflg) { ! 527: nl[number].n_value = clear(nl[number].n_value); ! 528: nl[type].n_value = clear(nl[type].n_value); ! 529: } ! 530: lseek(fc, (long)nl[number].n_value, 0); ! 531: read(fc, &ntty, sizeof(ntty)); ! 532: printf("%d %s lines\n", ntty, name); ! 533: if (ntty > ttyspace) { ! 534: ttyspace = ntty; ! 535: if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) { ! 536: printf("pstat: out of memory\n"); ! 537: return; ! 538: } ! 539: } ! 540: lseek(fc, (long)nl[type].n_value, 0); ! 541: read(fc, tty, ntty * sizeof(struct tty)); ! 542: printf(mesg); ! 543: for (tp = tty; tp < &tty[ntty]; tp++) ! 544: ttyprt(tp, tp - tty); ! 545: } ! 546: ! 547: ttyprt(atp, line) ! 548: struct tty *atp; ! 549: { ! 550: register struct tty *tp; ! 551: ! 552: printf("%2d", line); ! 553: tp = atp; ! 554: switch (tp->t_line) { ! 555: ! 556: #ifdef notdef ! 557: case NETLDISC: ! 558: if (tp->t_rec) ! 559: printf("%4d%4d", 0, tp->t_inbuf); ! 560: else ! 561: printf("%4d%4d", tp->t_inbuf, 0); ! 562: break; ! 563: #endif ! 564: ! 565: default: ! 566: printf("%4d%4d", tp->t_rawq.c_cc, tp->t_canq.c_cc); ! 567: } ! 568: printf("%4d %8x %8x%4d%4d", tp->t_outq.c_cc, tp->t_flags, ! 569: tp->t_addr, tp->t_delct, tp->t_col); ! 570: putf(tp->t_state&TS_TIMEOUT, 'T'); ! 571: putf(tp->t_state&TS_WOPEN, 'W'); ! 572: putf(tp->t_state&TS_ISOPEN, 'O'); ! 573: putf(tp->t_state&TS_FLUSH, 'F'); ! 574: putf(tp->t_state&TS_CARR_ON, 'C'); ! 575: putf(tp->t_state&TS_BUSY, 'B'); ! 576: putf(tp->t_state&TS_ASLEEP, 'A'); ! 577: putf(tp->t_state&TS_XCLUDE, 'X'); ! 578: putf(tp->t_state&TS_TTSTOP, 'S'); ! 579: putf(tp->t_state&TS_HUPCLS, 'H'); ! 580: printf("%6d", tp->t_pgrp); ! 581: switch (tp->t_line) { ! 582: ! 583: case OTTYDISC: ! 584: printf("\n"); ! 585: break; ! 586: ! 587: case NTTYDISC: ! 588: printf(" ntty\n"); ! 589: break; ! 590: ! 591: case NETLDISC: ! 592: printf(" berknet\n"); ! 593: break; ! 594: ! 595: case TABLDISC: ! 596: printf(" tab\n"); ! 597: break; ! 598: ! 599: case SLIPDISC: ! 600: printf(" slip\n"); ! 601: break; ! 602: ! 603: default: ! 604: printf(" %d\n", tp->t_line); ! 605: } ! 606: } ! 607: ! 608: dousr() ! 609: { ! 610: struct user U; ! 611: register i, j, *ip; ! 612: register struct nameidata *nd = &U.u_nd; ! 613: ! 614: /* This wins only if CLBYTES >= sizeof (struct user) */ ! 615: lseek(fm, ubase * NBPG, 0); ! 616: read(fm, &U, sizeof(U)); ! 617: printf("pcb"); ! 618: ip = (int *)&U.u_pcb; ! 619: while (ip < &U.u_arg[0]) { ! 620: if ((ip - (int *)&U.u_pcb) % 4 == 0) ! 621: printf("\t"); ! 622: printf("%x ", *ip++); ! 623: if ((ip - (int *)&U.u_pcb) % 4 == 0) ! 624: printf("\n"); ! 625: } ! 626: if ((ip - (int *)&U.u_pcb) % 4 != 0) ! 627: printf("\n"); ! 628: printf("arg"); ! 629: for (i=0; i<sizeof(U.u_arg)/sizeof(U.u_arg[0]); i++) { ! 630: if (i%5==0) ! 631: printf("\t"); ! 632: printf(" %.1x", U.u_arg[i]); ! 633: if (i%5==4) ! 634: printf("\n"); ! 635: } ! 636: if (i%5) ! 637: printf("\n"); ! 638: printf("segflg\t%d\nerror %d\n", nd->ni_segflg, U.u_error); ! 639: printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid); ! 640: printf("procp\t%.1x\n", U.u_procp); ! 641: printf("ap\t%.1x\n", U.u_ap); ! 642: printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2); ! 643: printf("base, count, offset %.1x %.1x %ld\n", nd->ni_base, ! 644: nd->ni_count, nd->ni_offset); ! 645: printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir); ! 646: printf("dirp %.1x\n", nd->ni_dirp); ! 647: printf("dent %d %.14s\n", nd->ni_dent.d_ino, nd->ni_dent.d_name); ! 648: printf("pdir %.1o\n", nd->ni_pdir); ! 649: printf("file"); ! 650: for (i=0; i<NOFILE; i++) { ! 651: if (i % 8 == 0) ! 652: printf("\t"); ! 653: printf("%9.1x", U.u_ofile[i]); ! 654: if (i % 8 == 7) ! 655: printf("\n"); ! 656: } ! 657: if (i % 8) ! 658: printf("\n"); ! 659: printf("pofile"); ! 660: for (i=0; i<NOFILE; i++) { ! 661: if (i % 8 == 0) ! 662: printf("\t"); ! 663: printf("%9.1x", U.u_pofile[i]); ! 664: if (i % 8 == 7) ! 665: printf("\n"); ! 666: } ! 667: if (i % 8) ! 668: printf("\n"); ! 669: printf("ssave"); ! 670: for (i=0; i<sizeof(label_t)/sizeof(int); i++) { ! 671: if (i%5==0) ! 672: printf("\t"); ! 673: printf("%9.1x", U.u_ssave.val[i]); ! 674: if (i%5==4) ! 675: printf("\n"); ! 676: } ! 677: if (i%5) ! 678: printf("\n"); ! 679: printf("sigs"); ! 680: for (i=0; i<NSIG; i++) { ! 681: if (i % 8 == 0) ! 682: printf("\t"); ! 683: printf("%.1x ", U.u_signal[i]); ! 684: if (i % 8 == 7) ! 685: printf("\n"); ! 686: } ! 687: if (i % 8) ! 688: printf("\n"); ! 689: printf("code\t%.1x\n", U.u_code); ! 690: printf("ar0\t%.1x\n", U.u_ar0); ! 691: printf("prof\t%x %x %x %x\n", U.u_prof.pr_base, U.u_prof.pr_size, ! 692: U.u_prof.pr_off, U.u_prof.pr_scale); ! 693: printf("\neosys\t%d\n", U.u_eosys); ! 694: printf("ttyp\t%.1x\n", U.u_ttyp); ! 695: printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd)); ! 696: printf("comm %.14s\n", U.u_comm); ! 697: printf("start\t%ld\n", U.u_start.tv_sec); ! 698: printf("acflag\t%ld\n", U.u_acflag); ! 699: printf("cmask\t%ld\n", U.u_cmask); ! 700: printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize); ! 701: printf("ru\t"); ! 702: ip = (int *)&U.u_ru; ! 703: for (i = 0; i < sizeof(U.u_ru)/sizeof(int); i++) ! 704: printf("%ld ", ip[i]); ! 705: printf("\n"); ! 706: ip = (int *)&U.u_cru; ! 707: printf("cru\t"); ! 708: for (i = 0; i < sizeof(U.u_cru)/sizeof(int); i++) ! 709: printf("%ld ", ip[i]); ! 710: printf("\n"); ! 711: #ifdef notdef ! 712: i = U.u_stack - &U; ! 713: while (U[++i] == 0); ! 714: i &= ~07; ! 715: while (i < 512) { ! 716: printf("%x ", 0140000+2*i); ! 717: for (j=0; j<8; j++) ! 718: printf("%9x", U[i++]); ! 719: printf("\n"); ! 720: } ! 721: #endif ! 722: } ! 723: ! 724: oatoi(s) ! 725: char *s; ! 726: { ! 727: register v; ! 728: ! 729: v = 0; ! 730: while (*s) ! 731: v = (v<<3) + *s++ - '0'; ! 732: return(v); ! 733: } ! 734: ! 735: dofile() ! 736: { ! 737: int nfile; ! 738: struct file *xfile, *afile; ! 739: register struct file *fp; ! 740: register nf; ! 741: int loc; ! 742: static char *dtypes[] = { "???", "inode", "socket" }; ! 743: ! 744: nf = 0; ! 745: nfile = getword(nl[SNFILE].n_value); ! 746: xfile = (struct file *)calloc(nfile, sizeof (struct file)); ! 747: afile = (struct file *)getword(nl[SFIL].n_value); ! 748: if (nfile < 0 || nfile > 10000) { ! 749: fprintf(stderr, "number of files is preposterous (%d)\n", ! 750: nfile); ! 751: return; ! 752: } ! 753: if (xfile == NULL) { ! 754: fprintf(stderr, "can't allocate memory for file table\n"); ! 755: return; ! 756: } ! 757: lseek(fc, mkphys((off_t)afile), 0); ! 758: read(fc, xfile, nfile * sizeof (struct file)); ! 759: for (fp=xfile; fp < &xfile[nfile]; fp++) ! 760: if (fp->f_count) ! 761: nf++; ! 762: if (totflg) { ! 763: printf("%3d/%3d files\n", nf, nfile); ! 764: return; ! 765: } ! 766: printf("%d/%d open files\n", nf, nfile); ! 767: printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n"); ! 768: for (fp=xfile,loc=(int)afile; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) { ! 769: if (fp->f_count==0) ! 770: continue; ! 771: printf("%8x ", loc); ! 772: if (fp->f_type <= DTYPE_SOCKET) ! 773: printf("%-8.8s", dtypes[fp->f_type]); ! 774: else ! 775: printf("%8d", fp->f_type); ! 776: putf(fp->f_flag&FREAD, 'R'); ! 777: putf(fp->f_flag&FWRITE, 'W'); ! 778: putf(fp->f_flag&FAPPEND, 'A'); ! 779: putf(fp->f_flag&FSHLOCK, 'S'); ! 780: putf(fp->f_flag&FEXLOCK, 'X'); ! 781: putf(fp->f_flag&FASYNC, 'I'); ! 782: printf(" %3d", mask(fp->f_count)); ! 783: printf(" %3d", mask(fp->f_msgcount)); ! 784: printf(" %8.1x", fp->f_data); ! 785: if (fp->f_offset < 0) ! 786: printf(" %x\n", fp->f_offset); ! 787: else ! 788: printf(" %ld\n", fp->f_offset); ! 789: } ! 790: free(xfile); ! 791: } ! 792: ! 793: int dmmin, dmmax, nswdev; ! 794: ! 795: doswap() ! 796: { ! 797: struct proc *proc; ! 798: int nproc; ! 799: struct text *xtext; ! 800: int ntext; ! 801: struct map *swapmap; ! 802: int nswapmap; ! 803: struct swdevt *swdevt, *sw; ! 804: register struct proc *pp; ! 805: int nswap, used, tused, free, waste; ! 806: int db, sb; ! 807: register struct mapent *me; ! 808: register struct text *xp; ! 809: int i, j; ! 810: long rmalloc(); ! 811: ! 812: nproc = getword(nl[SNPROC].n_value); ! 813: ntext = getword(nl[SNTEXT].n_value); ! 814: if (nproc < 0 || nproc > 10000 || ntext < 0 || ntext > 10000) { ! 815: fprintf(stderr, "number of procs/texts is preposterous (%d, %d)\n", ! 816: nproc, ntext); ! 817: return; ! 818: } ! 819: proc = (struct proc *)calloc(nproc, sizeof (struct proc)); ! 820: if (proc == NULL) { ! 821: fprintf(stderr, "can't allocate memory for proc table\n"); ! 822: exit(1); ! 823: } ! 824: xtext = (struct text *)calloc(ntext, sizeof (struct text)); ! 825: if (xtext == NULL) { ! 826: fprintf(stderr, "can't allocate memory for text table\n"); ! 827: exit(1); ! 828: } ! 829: nswapmap = getword(nl[SNSWAPMAP].n_value); ! 830: swapmap = (struct map *)calloc(nswapmap, sizeof (struct map)); ! 831: if (swapmap == NULL) { ! 832: fprintf(stderr, "can't allocate memory for swapmap\n"); ! 833: exit(1); ! 834: } ! 835: nswdev = getword(nl[SNSWDEV].n_value); ! 836: swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt)); ! 837: if (swdevt == NULL) { ! 838: fprintf(stderr, "can't allocate memory for swdevt table\n"); ! 839: exit(1); ! 840: } ! 841: lseek(fc, mkphys((off_t)nl[SSWDEVT].n_value), L_SET); ! 842: read(fc, swdevt, nswdev * sizeof (struct swdevt)); ! 843: lseek(fc, mkphys((off_t)getword(nl[SPROC].n_value)), 0); ! 844: read(fc, proc, nproc * sizeof (struct proc)); ! 845: lseek(fc, mkphys((off_t)getword(nl[STEXT].n_value)), 0); ! 846: read(fc, xtext, ntext * sizeof (struct text)); ! 847: lseek(fc, mkphys((off_t)getword(nl[SWAPMAP].n_value)), 0); ! 848: read(fc, swapmap, nswapmap * sizeof (struct map)); ! 849: swapmap->m_name = "swap"; ! 850: swapmap->m_limit = (struct mapent *)&swapmap[nswapmap]; ! 851: dmmin = getword(nl[SDMMIN].n_value); ! 852: dmmax = getword(nl[SDMMAX].n_value); ! 853: nswap = 0; ! 854: for (sw = swdevt; sw < &swdevt[nswdev]; sw++) ! 855: if (sw->sw_freed) ! 856: nswap += sw->sw_nblks; ! 857: free = 0; ! 858: for (me = (struct mapent *)(swapmap+1); ! 859: me < (struct mapent *)&swapmap[nswapmap]; me++) ! 860: free += me->m_size; ! 861: tused = 0; ! 862: for (xp = xtext; xp < &xtext[ntext]; xp++) ! 863: if (xp->x_iptr!=NULL) { ! 864: tused += ctod(clrnd(xp->x_size)); ! 865: if (xp->x_flag & XPAGI) ! 866: tused += ctod(clrnd(ctopt(xp->x_size))); ! 867: } ! 868: used = tused; ! 869: waste = 0; ! 870: for (pp = proc; pp < &proc[nproc]; pp++) { ! 871: if (pp->p_stat == 0 || pp->p_stat == SZOMB) ! 872: continue; ! 873: if (pp->p_flag & SSYS) ! 874: continue; ! 875: db = ctod(pp->p_dsize), sb = up(db); ! 876: used += sb; ! 877: waste += sb - db; ! 878: db = ctod(pp->p_ssize), sb = up(db); ! 879: used += sb; ! 880: waste += sb - db; ! 881: if ((pp->p_flag&SLOAD) == 0) ! 882: used += ctod(vusize(pp)); ! 883: } ! 884: if (totflg) { ! 885: #define btok(x) ((x) / (1024 / DEV_BSIZE)) ! 886: printf("%3d/%3d 00k swap\n", ! 887: btok(used/100), btok((used+free)/100)); ! 888: return; ! 889: } ! 890: printf("%dk used (%dk text), %dk free, %dk wasted, %dk missing\n", ! 891: btok(used), btok(tused), btok(free), btok(waste), ! 892: /* a dmmax/2 block goes to argmap */ ! 893: btok(nswap - dmmax/2 - (used + free))); ! 894: printf("avail: "); ! 895: for (i = dmmax; i >= dmmin; i /= 2) { ! 896: j = 0; ! 897: while (rmalloc(swapmap, i) != 0) ! 898: j++; ! 899: if (j) printf("%d*%dk ", j, btok(i)); ! 900: } ! 901: free = 0; ! 902: for (me = (struct mapent *)(swapmap+1); ! 903: me < (struct mapent *)&swapmap[nswapmap]; me++) ! 904: free += me->m_size; ! 905: printf("%d*1k\n", btok(free)); ! 906: } ! 907: ! 908: up(size) ! 909: register int size; ! 910: { ! 911: register int i, block; ! 912: ! 913: i = 0; ! 914: block = dmmin; ! 915: while (i < size) { ! 916: i += block; ! 917: if (block < dmmax) ! 918: block *= 2; ! 919: } ! 920: return (i); ! 921: } ! 922: ! 923: /* ! 924: * Compute number of pages to be allocated to the u. area ! 925: * and data and stack area page tables, which are stored on the ! 926: * disk immediately after the u. area. ! 927: */ ! 928: vusize(p) ! 929: register struct proc *p; ! 930: { ! 931: register int tsz = p->p_tsize / NPTEPG; ! 932: ! 933: /* ! 934: * We do not need page table space on the disk for page ! 935: * table pages wholly containing text. ! 936: */ ! 937: return (clrnd(UPAGES + ! 938: clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz)); ! 939: } ! 940: ! 941: /* ! 942: * Allocate 'size' units from the given ! 943: * map. Return the base of the allocated space. ! 944: * In a map, the addresses are increasing and the ! 945: * list is terminated by a 0 size. ! 946: * ! 947: * Algorithm is first-fit. ! 948: * ! 949: * This routine knows about the interleaving of the swapmap ! 950: * and handles that. ! 951: */ ! 952: long ! 953: rmalloc(mp, size) ! 954: register struct map *mp; ! 955: long size; ! 956: { ! 957: register struct mapent *ep = (struct mapent *)(mp+1); ! 958: register int addr; ! 959: register struct mapent *bp; ! 960: swblk_t first, rest; ! 961: ! 962: if (size <= 0 || size > dmmax) ! 963: return (0); ! 964: /* ! 965: * Search for a piece of the resource map which has enough ! 966: * free space to accomodate the request. ! 967: */ ! 968: for (bp = ep; bp->m_size; bp++) { ! 969: if (bp->m_size >= size) { ! 970: /* ! 971: * If allocating from swapmap, ! 972: * then have to respect interleaving ! 973: * boundaries. ! 974: */ ! 975: if (nswdev > 1 && ! 976: (first = dmmax - bp->m_addr%dmmax) < bp->m_size) { ! 977: if (bp->m_size - first < size) ! 978: continue; ! 979: addr = bp->m_addr + first; ! 980: rest = bp->m_size - first - size; ! 981: bp->m_size = first; ! 982: if (rest) ! 983: rmfree(mp, rest, addr+size); ! 984: return (addr); ! 985: } ! 986: /* ! 987: * Allocate from the map. ! 988: * If there is no space left of the piece ! 989: * we allocated from, move the rest of ! 990: * the pieces to the left. ! 991: */ ! 992: addr = bp->m_addr; ! 993: bp->m_addr += size; ! 994: if ((bp->m_size -= size) == 0) { ! 995: do { ! 996: bp++; ! 997: (bp-1)->m_addr = bp->m_addr; ! 998: } while ((bp-1)->m_size = bp->m_size); ! 999: } ! 1000: if (addr % CLSIZE) ! 1001: return (0); ! 1002: return (addr); ! 1003: } ! 1004: } ! 1005: return (0); ! 1006: } ! 1007: ! 1008: /* ! 1009: * Free the previously allocated space at addr ! 1010: * of size units into the specified map. ! 1011: * Sort addr into map and combine on ! 1012: * one or both ends if possible. ! 1013: */ ! 1014: rmfree(mp, size, addr) ! 1015: struct map *mp; ! 1016: long size, addr; ! 1017: { ! 1018: struct mapent *firstbp; ! 1019: register struct mapent *bp; ! 1020: register int t; ! 1021: ! 1022: /* ! 1023: * Both address and size must be ! 1024: * positive, or the protocol has broken down. ! 1025: */ ! 1026: if (addr <= 0 || size <= 0) ! 1027: goto badrmfree; ! 1028: /* ! 1029: * Locate the piece of the map which starts after the ! 1030: * returned space (or the end of the map). ! 1031: */ ! 1032: firstbp = bp = (struct mapent *)(mp + 1); ! 1033: for (; bp->m_addr <= addr && bp->m_size != 0; bp++) ! 1034: continue; ! 1035: /* ! 1036: * If the piece on the left abuts us, ! 1037: * then we should combine with it. ! 1038: */ ! 1039: if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) { ! 1040: /* ! 1041: * Check no overlap (internal error). ! 1042: */ ! 1043: if ((bp-1)->m_addr+(bp-1)->m_size > addr) ! 1044: goto badrmfree; ! 1045: /* ! 1046: * Add into piece on the left by increasing its size. ! 1047: */ ! 1048: (bp-1)->m_size += size; ! 1049: /* ! 1050: * If the combined piece abuts the piece on ! 1051: * the right now, compress it in also, ! 1052: * by shifting the remaining pieces of the map over. ! 1053: */ ! 1054: if (bp->m_addr && addr+size >= bp->m_addr) { ! 1055: if (addr+size > bp->m_addr) ! 1056: goto badrmfree; ! 1057: (bp-1)->m_size += bp->m_size; ! 1058: while (bp->m_size) { ! 1059: bp++; ! 1060: (bp-1)->m_addr = bp->m_addr; ! 1061: (bp-1)->m_size = bp->m_size; ! 1062: } ! 1063: } ! 1064: goto done; ! 1065: } ! 1066: /* ! 1067: * Don't abut on the left, check for abutting on ! 1068: * the right. ! 1069: */ ! 1070: if (addr+size >= bp->m_addr && bp->m_size) { ! 1071: if (addr+size > bp->m_addr) ! 1072: goto badrmfree; ! 1073: bp->m_addr -= size; ! 1074: bp->m_size += size; ! 1075: goto done; ! 1076: } ! 1077: /* ! 1078: * Don't abut at all. Make a new entry ! 1079: * and check for map overflow. ! 1080: */ ! 1081: do { ! 1082: t = bp->m_addr; ! 1083: bp->m_addr = addr; ! 1084: addr = t; ! 1085: t = bp->m_size; ! 1086: bp->m_size = size; ! 1087: bp++; ! 1088: } while (size = t); ! 1089: /* ! 1090: * Segment at bp is to be the delimiter; ! 1091: * If there is not room for it ! 1092: * then the table is too full ! 1093: * and we must discard something. ! 1094: */ ! 1095: if (bp+1 > mp->m_limit) { ! 1096: /* ! 1097: * Back bp up to last available segment. ! 1098: * which contains a segment already and must ! 1099: * be made into the delimiter. ! 1100: * Discard second to last entry, ! 1101: * since it is presumably smaller than the last ! 1102: * and move the last entry back one. ! 1103: */ ! 1104: bp--; ! 1105: printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name, ! 1106: (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size); ! 1107: bp[-1] = bp[0]; ! 1108: bp[0].m_size = bp[0].m_addr = 0; ! 1109: } ! 1110: done: ! 1111: return; ! 1112: badrmfree: ! 1113: printf("bad rmfree\n"); ! 1114: } ! 1115: /* ! 1116: * "addr" is a kern virt addr and does not correspond ! 1117: * To a phys addr after zipping out the high bit.. ! 1118: * since it was valloc'd in the kernel. ! 1119: * ! 1120: * We return the phys addr by simulating kernel vm (/dev/kmem) ! 1121: * when we are reading a crash dump. ! 1122: */ ! 1123: off_t ! 1124: mkphys(addr) ! 1125: off_t addr; ! 1126: { ! 1127: register off_t o; ! 1128: ! 1129: if (!kflg) ! 1130: return(addr); ! 1131: addr = clear(addr); ! 1132: o = addr & PGOFSET; ! 1133: addr >>= PGSHIFT; ! 1134: addr &= PG_PFNUM; ! 1135: addr *= NBPW; ! 1136: addr = getword(nl[SYSMAP].n_value + addr); ! 1137: addr = ((addr & PG_PFNUM) << PGSHIFT) | o; ! 1138: return(addr); ! 1139: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.