|
|
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.26 (Berkeley) 6/29/90"; ! 15: #endif /* not lint */ ! 16: ! 17: /* ! 18: * Print system stuff ! 19: */ ! 20: #include <sys/param.h> ! 21: #include <sys/user.h> ! 22: #include <sys/proc.h> ! 23: #include <sys/text.h> ! 24: #include <sys/time.h> ! 25: #include <sys/vnode.h> ! 26: #include <sys/map.h> ! 27: #define KERNEL ! 28: #define NFS ! 29: #include <sys/file.h> ! 30: #include <sys/mount.h> ! 31: #include <ufs/quota.h> ! 32: #include <ufs/inode.h> ! 33: #include <sys/stat.h> ! 34: #include <nfs/nfsv2.h> ! 35: #include <nfs/nfs.h> ! 36: #include <nfs/nfsnode.h> ! 37: #include <sys/ioctl.h> ! 38: #include <sys/tty.h> ! 39: #undef KERNEL ! 40: #include <sys/conf.h> ! 41: #include <sys/vm.h> ! 42: #include <machine/pte.h> ! 43: ! 44: #include <kvm.h> ! 45: #include <nlist.h> ! 46: #include <stdio.h> ! 47: #include "pathnames.h" ! 48: ! 49: #define mask(x) (x&0377) ! 50: #define clear(x) ((int)x &~ KERNBASE) ! 51: ! 52: char *fnlist = NULL; ! 53: char *fcore = NULL; ! 54: ! 55: struct nlist nl[] = { ! 56: #define STEXT 0 ! 57: { "_text" }, ! 58: #define SCONS 1 ! 59: { "_cons" }, ! 60: #define SPROC 2 ! 61: { "_proc" }, ! 62: #define SFIL 3 ! 63: { "_file" }, ! 64: #define SWAPMAP 4 ! 65: { "_swapmap" }, ! 66: #define SNPROC 5 ! 67: { "_nproc" }, ! 68: #define SNTEXT 6 ! 69: { "_ntext" }, ! 70: #define SNFILE 7 ! 71: { "_nfile" }, ! 72: #define SNSWAPMAP 8 ! 73: { "_nswapmap" }, ! 74: #define SPTY 9 ! 75: { "_pt_tty" }, ! 76: #define SDMMIN 10 ! 77: { "_dmmin" }, ! 78: #define SDMMAX 11 ! 79: { "_dmmax" }, ! 80: #define SNSWDEV 12 ! 81: { "_nswdev" }, ! 82: #define SSWDEVT 13 ! 83: { "_swdevt" }, ! 84: #define SNPTY 14 ! 85: { "_npty" }, ! 86: #ifdef vax ! 87: #define SDZ (SNPTY+1) ! 88: { "_dz_tty" }, ! 89: #define SNDZ (SNPTY+2) ! 90: { "_dz_cnt" }, ! 91: #define SDMF (SNPTY+3) ! 92: { "_dmf_tty" }, ! 93: #define SNDMF (SNPTY+4) ! 94: { "_ndmf" }, ! 95: #define SDH (SNPTY+5) ! 96: { "_dh11" }, ! 97: #define SNDH (SNPTY+6) ! 98: { "_ndh11" }, ! 99: #define SDHU (SNPTY+7) ! 100: { "_dhu_tty" }, ! 101: #define SNDHU (SNPTY+8) ! 102: { "_ndhu" }, ! 103: #define SDMZ (SNPTY+9) ! 104: { "_dmz_tty" }, ! 105: #define SNDMZ (SNPTY+10) ! 106: { "_ndmz" }, ! 107: #define SQD (SNPTY+11) ! 108: { "_qd_tty" }, ! 109: #define SNQD (SNPTY+12) ! 110: { "_nNQD" }, ! 111: #endif ! 112: #ifdef tahoe ! 113: #define SVX (SNPTY+1) ! 114: { "_vx_tty" }, ! 115: #define SNVX (SNPTY+2) ! 116: { "_nvx" }, ! 117: #define SMP (SNPTY+3) ! 118: { "_mp_tty" }, ! 119: #define SNMP (SNPTY+4) ! 120: { "_nmp" }, ! 121: #endif ! 122: { "" } ! 123: }; ! 124: ! 125: int vnof; ! 126: int txtf; ! 127: int prcf; ! 128: int ttyf; ! 129: int usrf; ! 130: int upid; ! 131: int filf; ! 132: int swpf; ! 133: int totflg; ! 134: char partab[1]; ! 135: struct cdevsw cdevsw[1]; ! 136: struct bdevsw bdevsw[1]; ! 137: int allflg; ! 138: int nflg; ! 139: u_long getword(); ! 140: off_t mkphys(); ! 141: ! 142: char *Program; ! 143: ! 144: main(argc, argv) ! 145: int argc; ! 146: char **argv; ! 147: { ! 148: extern char *optarg; ! 149: extern int optind; ! 150: int ch; ! 151: ! 152: Program = argv[0]; ! 153: while ((ch = getopt(argc, argv, "Tafvikptu:sxn")) != EOF) ! 154: switch((char)ch) { ! 155: case 'T': ! 156: totflg++; ! 157: break; ! 158: case 'a': ! 159: allflg++; ! 160: /*FALLTHROUGH*/ ! 161: case 'p': ! 162: prcf++; ! 163: break; ! 164: case 'f': ! 165: filf++; ! 166: break; ! 167: case 'v': ! 168: case 'i': ! 169: vnof++; ! 170: break; ! 171: case 't': ! 172: ttyf++; ! 173: break; ! 174: case 'u': ! 175: usrf++; ! 176: sscanf(optarg, "%d", &upid); ! 177: break; ! 178: case 's': ! 179: swpf++; ! 180: break; ! 181: case 'x': ! 182: txtf++; ! 183: break; ! 184: case 'n': ! 185: nflg++; ! 186: break; ! 187: case '?': ! 188: default: ! 189: printf("usage: pstat -[Tafiptsx] [-u [pid]] [system] [core]\n"); ! 190: exit(1); ! 191: } ! 192: argc -= optind; ! 193: argv += optind; ! 194: ! 195: if (argc > 1) ! 196: fcore = argv[1]; ! 197: if (argc > 0) ! 198: fnlist = argv[0]; ! 199: if (kvm_openfiles(fnlist, fcore, NULL) == -1) { ! 200: syserror("kvm_openfiles: %s", kvm_geterr()); ! 201: exit(1); ! 202: } ! 203: if (kvm_nlist(nl) != 0) { ! 204: syserror("kvm_nlist: %s", kvm_geterr()); ! 205: exit(1); ! 206: } ! 207: if (!(filf | totflg | vnof | prcf | txtf | ttyf | usrf | swpf)) { ! 208: printf("pstat: one or more of -[aivxptfsu] is required\n"); ! 209: exit(1); ! 210: } ! 211: if (filf||totflg) ! 212: dofile(); ! 213: if (vnof||totflg) ! 214: dovnode(); ! 215: if (prcf||totflg) ! 216: doproc(); ! 217: if (txtf||totflg) ! 218: dotext(); ! 219: if (ttyf) ! 220: dotty(); ! 221: if (usrf) ! 222: dousr(); ! 223: if (swpf||totflg) ! 224: doswap(); ! 225: } ! 226: ! 227: struct e_vnode { ! 228: struct vnode *avnode; ! 229: struct vnode vnode; ! 230: }; ! 231: ! 232: dovnode() ! 233: { ! 234: register struct e_vnode *e_vnodebase, *endvnode, *evp; ! 235: register struct vnode *vp; ! 236: register struct mount *maddr = NULL, *mp; ! 237: register struct inode *ip; ! 238: int numvnodes; ! 239: struct e_vnode *loadvnodes(); ! 240: struct mount *getmnt(); ! 241: ! 242: e_vnodebase = loadvnodes(&numvnodes); ! 243: if (totflg) { ! 244: printf("%7d vnodes\n", numvnodes); ! 245: return; ! 246: } ! 247: endvnode = e_vnodebase + numvnodes; ! 248: printf("%d active vnodes\n", numvnodes); ! 249: ! 250: ! 251: #define ST mp->mnt_stat ! 252: for (evp = e_vnodebase; evp < endvnode; evp++) { ! 253: vp = &evp->vnode; ! 254: if (vp->v_mount != maddr) { ! 255: /* ! 256: * New filesystem ! 257: */ ! 258: if ((mp = getmnt(vp->v_mount)) == NULL) ! 259: continue; ! 260: maddr = vp->v_mount; ! 261: mount_print(mp); ! 262: vnode_header(); ! 263: switch(ST.f_type) { ! 264: case MOUNT_UFS: ! 265: case MOUNT_MFS: ! 266: ufs_header(); ! 267: break; ! 268: case MOUNT_NFS: ! 269: nfs_header(); ! 270: break; ! 271: case MOUNT_NONE: ! 272: case MOUNT_PC: ! 273: default: ! 274: break; ! 275: } ! 276: printf("\n"); ! 277: } ! 278: vnode_print(evp->avnode, vp); ! 279: switch(ST.f_type) { ! 280: case MOUNT_UFS: ! 281: case MOUNT_MFS: ! 282: ufs_print(vp); ! 283: break; ! 284: case MOUNT_NFS: ! 285: nfs_print(vp); ! 286: break; ! 287: case MOUNT_NONE: ! 288: case MOUNT_PC: ! 289: default: ! 290: break; ! 291: } ! 292: printf("\n"); ! 293: } ! 294: free(e_vnodebase); ! 295: } ! 296: ! 297: vnode_header() ! 298: { ! 299: printf("ADDR TYP VFLAG USE REF"); ! 300: } ! 301: ! 302: vnode_print(avnode, vp) ! 303: struct vnode *avnode; ! 304: struct vnode *vp; ! 305: { ! 306: char *type, flags[16]; ! 307: char *fp = flags; ! 308: register flag; ! 309: ! 310: /* ! 311: * set type ! 312: */ ! 313: switch(vp->v_type) { ! 314: case VNON: ! 315: type = "non"; break; ! 316: case VREG: ! 317: type = "reg"; break; ! 318: case VDIR: ! 319: type = "dir"; break; ! 320: case VBLK: ! 321: type = "blk"; break; ! 322: case VCHR: ! 323: type = "chr"; break; ! 324: case VLNK: ! 325: type = "lnk"; break; ! 326: case VSOCK: ! 327: type = "soc"; break; ! 328: case VFIFO: ! 329: type = "fif"; break; ! 330: case VBAD: ! 331: type = "bad"; break; ! 332: default: ! 333: type = "unk"; break; ! 334: } ! 335: /* ! 336: * gather flags ! 337: */ ! 338: flag = vp->v_flag; ! 339: if (flag & VROOT) ! 340: *fp++ = 'R'; ! 341: if (flag & VTEXT) ! 342: *fp++ = 'T'; ! 343: if (flag & VXLOCK) ! 344: *fp++ = 'L'; ! 345: if (flag & VXWANT) ! 346: *fp++ = 'W'; ! 347: if (flag & VEXLOCK) ! 348: *fp++ = 'E'; ! 349: if (flag & VSHLOCK) ! 350: *fp++ = 'S'; ! 351: if (flag & VLWAIT) ! 352: *fp++ = 'T'; ! 353: if (flag & VALIASED) ! 354: *fp++ = 'A'; ! 355: if (flag & VBWAIT) ! 356: *fp++ = 'B'; ! 357: if (flag == 0) ! 358: *fp++ = '-'; ! 359: *fp = '\0'; ! 360: /* ! 361: * print it ! 362: */ ! 363: printf("%8x %s %5s %4d %4d", ! 364: avnode, type, flags, vp->v_usecount, vp->v_holdcnt); ! 365: } ! 366: ! 367: ufs_header() ! 368: { ! 369: printf(" FILEID IFLAG RDEV|SZ"); ! 370: } ! 371: ! 372: ufs_print(vp) ! 373: struct vnode *vp; ! 374: { ! 375: struct inode *ip = VTOI(vp); ! 376: char flagbuf[16], *flags = flagbuf; ! 377: register flag; ! 378: char *name; ! 379: mode_t type; ! 380: extern char *devname(); ! 381: ! 382: flag = ip->i_flag; ! 383: if (flag & ILOCKED) ! 384: *flags++ = 'L'; ! 385: if (flag & IWANT) ! 386: *flags++ = 'W'; ! 387: if (flag & IRENAME) ! 388: *flags++ = 'R'; ! 389: if (flag & IUPD) ! 390: *flags++ = 'U'; ! 391: if (flag & IACC) ! 392: *flags++ = 'A'; ! 393: if (flag & ICHG) ! 394: *flags++ = 'C'; ! 395: if (flag & IMOD) ! 396: *flags++ = 'M'; ! 397: if (flag & ISHLOCK) ! 398: *flags++ = 'S'; ! 399: if (flag & IEXLOCK) ! 400: *flags++ = 'E'; ! 401: if (flag & ILWAIT) ! 402: *flags++ = 'Z'; ! 403: if (flag == 0) ! 404: *flags++ = '-'; ! 405: *flags = '\0'; ! 406: ! 407: printf(" %6d %5s", ip->i_number, flagbuf); ! 408: type = ip->i_mode & S_IFMT; ! 409: if (type == S_IFCHR || type == S_IFBLK) ! 410: if (nflg || ((name = devname(ip->i_rdev, type)) == NULL)) ! 411: printf(" %2d,%-2d", ! 412: major(ip->i_rdev), minor(ip->i_rdev)); ! 413: else ! 414: printf(" %7s", name); ! 415: else ! 416: printf(" %7d", ip->i_size); ! 417: } ! 418: ! 419: nfs_header() ! 420: { ! 421: printf(" FILEID NFLAG RDEV|SZ"); ! 422: } ! 423: ! 424: nfs_print(vp) ! 425: struct vnode *vp; ! 426: { ! 427: struct nfsnode *np = VTONFS(vp); ! 428: char flagbuf[16], *flags = flagbuf; ! 429: register flag; ! 430: char *name; ! 431: mode_t type; ! 432: extern char *devname(); ! 433: ! 434: flag = np->n_flag; ! 435: if (flag & NLOCKED) ! 436: *flags++ = 'L'; ! 437: if (flag & NWANT) ! 438: *flags++ = 'W'; ! 439: if (flag & NMODIFIED) ! 440: *flags++ = 'M'; ! 441: if (flag & NWRITEERR) ! 442: *flags++ = 'E'; ! 443: if (flag == 0) ! 444: *flags++ = '-'; ! 445: *flags = '\0'; ! 446: ! 447: #define VT np->n_vattr ! 448: printf(" %6d %5s", VT.va_fileid, flagbuf); ! 449: type = VT.va_mode & S_IFMT; ! 450: if (type == S_IFCHR || type == S_IFBLK) ! 451: if (nflg || ((name = devname(VT.va_rdev, type)) == NULL)) ! 452: printf(" %2d,%-2d", ! 453: major(VT.va_rdev), minor(VT.va_rdev)); ! 454: else ! 455: printf(" %7s", name); ! 456: else ! 457: printf(" %7d", np->n_size); ! 458: } ! 459: ! 460: /* ! 461: * Given a pointer to a mount structure in kernel space, ! 462: * read it in and return a usable pointer to it. ! 463: */ ! 464: struct mount * ! 465: getmnt(maddr) ! 466: struct mount *maddr; ! 467: { ! 468: static struct mtab { ! 469: struct mtab *next; ! 470: struct mount *maddr; ! 471: struct mount mount; ! 472: } *mhead = NULL; ! 473: register struct mtab *mt; ! 474: ! 475: for (mt = mhead; mt != NULL; mt = mt->next) ! 476: if (maddr == mt->maddr) ! 477: return (&mt->mount); ! 478: if ((mt = (struct mtab *)malloc(sizeof (struct mtab))) == NULL) { ! 479: error("out of memory"); ! 480: exit(1); ! 481: } ! 482: if (kvm_read((off_t)maddr, &mt->mount, sizeof(struct mount)) != ! 483: sizeof(struct mount)) { ! 484: error("can't read mount table at %x", maddr); ! 485: return (NULL); ! 486: } ! 487: mt->maddr = maddr; ! 488: mt->next = mhead; ! 489: mhead = mt; ! 490: return (&mt->mount); ! 491: } ! 492: ! 493: mount_print(mp) ! 494: struct mount *mp; ! 495: { ! 496: char *type = "unknown"; ! 497: register flags; ! 498: ! 499: #define ST mp->mnt_stat ! 500: printf("*** MOUNT "); ! 501: switch (ST.f_type) { ! 502: case MOUNT_NONE: ! 503: type = "none"; ! 504: break; ! 505: case MOUNT_UFS: ! 506: type = "ufs"; ! 507: break; ! 508: case MOUNT_NFS: ! 509: type = "nfs"; ! 510: break; ! 511: case MOUNT_MFS: ! 512: type = "mfs"; ! 513: break; ! 514: case MOUNT_PC: ! 515: type = "pc"; ! 516: break; ! 517: } ! 518: printf("%s %s on %s", type, ST.f_mntfromname, ST.f_mntonname); ! 519: if (flags = mp->mnt_flag) { ! 520: char *comma = "("; ! 521: ! 522: putchar(' '); ! 523: /* user visable flags */ ! 524: if (flags & MNT_RDONLY) { ! 525: printf("%srdonly", comma); ! 526: flags &= ~MNT_RDONLY; ! 527: comma = ","; ! 528: } ! 529: if (flags & MNT_SYNCHRONOUS) { ! 530: printf("%ssynchronous", comma); ! 531: flags &= ~MNT_SYNCHRONOUS; ! 532: comma = ","; ! 533: } ! 534: if (flags & MNT_NOEXEC) { ! 535: printf("%snoexec", comma); ! 536: flags &= ~MNT_NOEXEC; ! 537: comma = ","; ! 538: } ! 539: if (flags & MNT_NOSUID) { ! 540: printf("%snosuid", comma); ! 541: flags &= ~MNT_NOSUID; ! 542: comma = ","; ! 543: } ! 544: if (flags & MNT_NODEV) { ! 545: printf("%snodev", comma); ! 546: flags &= ~MNT_NODEV; ! 547: comma = ","; ! 548: } ! 549: if (flags & MNT_EXPORTED) { ! 550: printf("%sexport", comma); ! 551: flags &= ~MNT_EXPORTED; ! 552: comma = ","; ! 553: } ! 554: if (flags & MNT_EXRDONLY) { ! 555: printf("%sexrdonly", comma); ! 556: flags &= ~MNT_EXRDONLY; ! 557: comma = ","; ! 558: } ! 559: if (flags & MNT_LOCAL) { ! 560: printf("%slocal", comma); ! 561: flags &= ~MNT_LOCAL; ! 562: comma = ","; ! 563: } ! 564: if (flags & MNT_QUOTA) { ! 565: printf("%squota", comma); ! 566: flags &= ~MNT_QUOTA; ! 567: comma = ","; ! 568: } ! 569: /* filesystem control flags */ ! 570: if (flags & MNT_UPDATE) { ! 571: printf("%supdate", comma); ! 572: flags &= ~MNT_UPDATE; ! 573: comma = ","; ! 574: } ! 575: if (flags & MNT_MLOCK) { ! 576: printf("%slock", comma); ! 577: flags &= ~MNT_MLOCK; ! 578: comma = ","; ! 579: } ! 580: if (flags & MNT_MWAIT) { ! 581: printf("%swait", comma); ! 582: flags &= ~MNT_MWAIT; ! 583: comma = ","; ! 584: } ! 585: if (flags & MNT_MPBUSY) { ! 586: printf("%sbusy", comma); ! 587: flags &= ~MNT_MPBUSY; ! 588: comma = ","; ! 589: } ! 590: if (flags & MNT_MPWANT) { ! 591: printf("%swant", comma); ! 592: flags &= ~MNT_MPWANT; ! 593: comma = ","; ! 594: } ! 595: if (flags & MNT_UNMOUNT) { ! 596: printf("%sunmount", comma); ! 597: flags &= ~MNT_UNMOUNT; ! 598: comma = ","; ! 599: } ! 600: if (flags) ! 601: printf("%sunknown_flags:%x", flags); ! 602: printf(")"); ! 603: } ! 604: printf("\n"); ! 605: #undef ST ! 606: } ! 607: ! 608: struct e_vnode * ! 609: loadvnodes(avnodes) ! 610: int *avnodes; ! 611: { ! 612: int ret, copysize, i; ! 613: struct e_vnode *vnodebase; ! 614: ! 615: if (fcore != NULL) { ! 616: error("vnodes on dead kernel, not impl yet\n"); ! 617: exit(1); ! 618: } ! 619: if ((ret = getkerninfo(KINFO_VNODE, NULL, NULL, 0)) == -1) { ! 620: syserror("can't get estimate for kerninfo"); ! 621: exit(1); ! 622: } ! 623: copysize = ret; ! 624: if ((vnodebase = (struct e_vnode *)malloc(copysize)) ! 625: == NULL) { ! 626: error("out of memory"); ! 627: exit(1); ! 628: } ! 629: if ((ret = getkerninfo(KINFO_VNODE, vnodebase, ©size, 0)) ! 630: == -1) { ! 631: syserror("can't get vnode list"); ! 632: exit(1); ! 633: } ! 634: if (copysize % sizeof (struct e_vnode)) { ! 635: error("vnode size mismatch"); ! 636: error(1); ! 637: } ! 638: *avnodes = copysize / sizeof (struct e_vnode); ! 639: ! 640: return (vnodebase); ! 641: } ! 642: ! 643: u_long ! 644: getword(loc) ! 645: off_t loc; ! 646: { ! 647: u_long word; ! 648: ! 649: kvm_read(loc, &word, sizeof (word)); ! 650: return (word); ! 651: } ! 652: ! 653: putf(v, n) ! 654: { ! 655: if (v) ! 656: printf("%c", n); ! 657: else ! 658: printf(" "); ! 659: } ! 660: ! 661: dotext() ! 662: { ! 663: register struct text *xp; ! 664: int ntext; ! 665: struct text *xtext, *atext; ! 666: int ntx, ntxca; ! 667: ! 668: ntx = ntxca = 0; ! 669: ntext = getword(nl[SNTEXT].n_value); ! 670: xtext = (struct text *)calloc(ntext, sizeof (struct text)); ! 671: atext = (struct text *)getword(nl[STEXT].n_value); ! 672: if (ntext < 0 || ntext > 10000) { ! 673: fprintf(stderr, "number of texts is preposterous (%d)\n", ! 674: ntext); ! 675: return; ! 676: } ! 677: if (xtext == NULL) { ! 678: fprintf(stderr, "can't allocate memory for text table\n"); ! 679: return; ! 680: } ! 681: kvm_read(atext, xtext, ntext * sizeof (struct text)); ! 682: for (xp = xtext; xp < &xtext[ntext]; xp++) { ! 683: if (xp->x_vptr != NULL) ! 684: ntxca++; ! 685: if (xp->x_count != 0) ! 686: ntx++; ! 687: } ! 688: if (totflg) { ! 689: printf("%3d/%3d texts active, %3d used\n", ntx, ntext, ntxca); ! 690: return; ! 691: } ! 692: printf("%d/%d active texts, %d used\n", ntx, ntext, ntxca); ! 693: printf("\ ! 694: LOC FLAGS DADDR CADDR RSS SIZE VPTR CNT CCNT FORW BACK\n"); ! 695: for (xp = xtext; xp < &xtext[ntext]; xp++) { ! 696: if (xp->x_vptr == NULL) ! 697: continue; ! 698: printf("%8.1x", atext + (xp - xtext)); ! 699: printf(" "); ! 700: putf(xp->x_flag&XPAGV, 'P'); ! 701: putf(xp->x_flag&XTRC, 'T'); ! 702: putf(xp->x_flag&XWRIT, 'W'); ! 703: putf(xp->x_flag&XLOAD, 'L'); ! 704: putf(xp->x_flag&XLOCK, 'K'); ! 705: putf(xp->x_flag&XWANT, 'w'); ! 706: printf("%5x", xp->x_daddr[0]); ! 707: printf("%10x", xp->x_caddr); ! 708: printf("%5d", xp->x_rssize); ! 709: printf("%5d", xp->x_size); ! 710: printf("%10.1x", xp->x_vptr); ! 711: printf("%5d", xp->x_count&0377); ! 712: printf("%5d", xp->x_ccount); ! 713: printf("%10x", xp->x_forw); ! 714: printf("%9x", xp->x_back); ! 715: printf("\n"); ! 716: } ! 717: free(xtext); ! 718: } ! 719: ! 720: doproc() ! 721: { ! 722: struct proc *xproc, *aproc; ! 723: int nproc; ! 724: register struct proc *pp; ! 725: register loc, np; ! 726: struct pte apte; ! 727: ! 728: nproc = getword(nl[SNPROC].n_value); ! 729: xproc = (struct proc *)calloc(nproc, sizeof (struct proc)); ! 730: aproc = (struct proc *)getword(nl[SPROC].n_value); ! 731: if (nproc < 0 || nproc > 10000) { ! 732: fprintf(stderr, "number of procs is preposterous (%d)\n", ! 733: nproc); ! 734: return; ! 735: } ! 736: if (xproc == NULL) { ! 737: fprintf(stderr, "can't allocate memory for proc table\n"); ! 738: return; ! 739: } ! 740: kvm_read(aproc, xproc, nproc * sizeof (struct proc)); ! 741: np = 0; ! 742: for (pp=xproc; pp < &xproc[nproc]; pp++) ! 743: if (pp->p_stat) ! 744: np++; ! 745: if (totflg) { ! 746: printf("%3d/%3d processes\n", np, nproc); ! 747: return; ! 748: } ! 749: printf("%d/%d processes\n", np, nproc); ! 750: printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP\n"); ! 751: for (pp=xproc; pp<&xproc[nproc]; pp++) { ! 752: if (pp->p_stat==0 && allflg==0) ! 753: continue; ! 754: printf("%8x", aproc + (pp - xproc)); ! 755: printf(" %2d", pp->p_stat); ! 756: printf(" %8x", pp->p_flag); ! 757: printf(" %4d", pp->p_poip); ! 758: printf(" %3d", pp->p_pri); ! 759: printf(" %8x", pp->p_sig); ! 760: printf(" %4d", pp->p_uid); ! 761: printf(" %3d", pp->p_slptime); ! 762: printf(" %3d", pp->p_time); ! 763: printf(" %4d", pp->p_cpu&0377); ! 764: printf(" %3d", pp->p_nice); ! 765: printf(" %6d", pp->p_pid); ! 766: printf(" %6d", pp->p_ppid); ! 767: /* ! 768: if (pp->p_flag & SLOAD) { ! 769: kvm_read(pp->p_addr, &apte, sizeof(apte)); ! 770: printf(" %8x", apte.pg_pfnum); ! 771: } else ! 772: printf(" %8x", pp->p_swaddr); ! 773: */ ! 774: printf(" %4x", pp->p_rssize); ! 775: printf(" %4x", pp->p_swrss); ! 776: printf(" %5x", pp->p_dsize+pp->p_ssize); ! 777: printf(" %7x", clear(pp->p_wchan)); ! 778: printf(" %7x", clear(pp->p_link)); ! 779: printf(" %7x", clear(pp->p_textp)); ! 780: printf("\n"); ! 781: } ! 782: free(xproc); ! 783: } ! 784: ! 785: char mesg[] = "LINE RAW CAN OUT RCC CCC OCC HWT LWT ADDR COL STATE PGID DISC\n"; ! 786: int ttyspace = 128; ! 787: struct tty *tty; ! 788: ! 789: dotty() ! 790: { ! 791: ! 792: if ((tty = (struct tty *)malloc(ttyspace * sizeof(*tty))) == 0) { ! 793: printf("pstat: out of memory\n"); ! 794: return; ! 795: } ! 796: printf("1 cons\n"); ! 797: kvm_read((long)nl[SCONS].n_value, tty, sizeof(*tty)); ! 798: printf(mesg); ! 799: ttyprt(&tty[0], 0); ! 800: #ifdef vax ! 801: if (nl[SNQD].n_type != 0) ! 802: doqdss(); ! 803: if (nl[SNDZ].n_type != 0) ! 804: dottytype("dz", SDZ, SNDZ); ! 805: if (nl[SNDH].n_type != 0) ! 806: dottytype("dh", SDH, SNDH); ! 807: if (nl[SNDMF].n_type != 0) ! 808: dottytype("dmf", SDMF, SNDMF); ! 809: if (nl[SNDHU].n_type != 0) ! 810: dottytype("dhu", SDHU, SNDHU); ! 811: if (nl[SNDMZ].n_type != 0) ! 812: dottytype("dmz", SDMZ, SNDMZ); ! 813: #endif ! 814: #ifdef tahoe ! 815: if (nl[SNVX].n_type != 0) ! 816: dottytype("vx", SVX, SNVX); ! 817: if (nl[SNMP].n_type != 0) ! 818: dottytype("mp", SMP, SNMP); ! 819: #endif ! 820: if (nl[SNPTY].n_type != 0) ! 821: dottytype("pty", SPTY, SNPTY); ! 822: } ! 823: ! 824: /* ! 825: * Special case the qdss: there are 4 ttys per qdss, ! 826: * but only the first of each is used as a tty. ! 827: */ ! 828: #ifdef vax ! 829: doqdss() ! 830: { ! 831: int nqd; ! 832: register struct tty *tp; ! 833: ! 834: kvm_read((long)nl[SNQD].n_value, &nqd, sizeof(nqd)); ! 835: printf("%d qd\n", nqd); ! 836: kvm_read((long)nl[SQD].n_value, tty, nqd * sizeof(struct tty) * 4); ! 837: printf(mesg); ! 838: for (tp = tty; tp < &tty[nqd * 4]; tp += 4) ! 839: ttyprt(tp, tp - tty); ! 840: } ! 841: #endif ! 842: ! 843: dottytype(name, type, number) ! 844: char *name; ! 845: { ! 846: int ntty; ! 847: register struct tty *tp; ! 848: extern char *realloc(); ! 849: ! 850: if (tty == (struct tty *)0) ! 851: return; ! 852: kvm_read((long)nl[number].n_value, &ntty, sizeof(ntty)); ! 853: printf("%d %s lines\n", ntty, name); ! 854: if (ntty > ttyspace) { ! 855: ttyspace = ntty; ! 856: if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) { ! 857: printf("pstat: out of memory\n"); ! 858: return; ! 859: } ! 860: } ! 861: kvm_read((long)nl[type].n_value, tty, ntty * sizeof(struct tty)); ! 862: printf(mesg); ! 863: for (tp = tty; tp < &tty[ntty]; tp++) ! 864: ttyprt(tp, tp - tty); ! 865: } ! 866: ! 867: struct { ! 868: int flag; ! 869: char val; ! 870: } ttystates[] = { ! 871: TS_WOPEN, 'W', ! 872: TS_ISOPEN, 'O', ! 873: TS_CARR_ON, 'C', ! 874: TS_TIMEOUT, 'T', ! 875: TS_FLUSH, 'F', ! 876: TS_BUSY, 'B', ! 877: TS_ASLEEP, 'A', ! 878: TS_XCLUDE, 'X', ! 879: TS_TTSTOP, 'S', ! 880: TS_HUPCLS, 'H', ! 881: TS_TBLOCK, 'K', ! 882: TS_RCOLL, 'R', ! 883: TS_WCOLL, 'I', /* running short on letters ! */ ! 884: TS_ASYNC, 'Y', ! 885: TS_BKSL, 'D', ! 886: TS_ERASE, 'E', ! 887: TS_LNCH, 'L', ! 888: TS_TYPEN, 'P', ! 889: TS_CNTTB, 'N', ! 890: 0, 0 ! 891: }; ! 892: ! 893: ttyprt(atp, line) ! 894: struct tty *atp; ! 895: { ! 896: register struct tty *tp; ! 897: char state[20]; ! 898: register i, j; ! 899: char *name; ! 900: extern char *devname(); ! 901: pid_t pgid; ! 902: ! 903: tp = atp; ! 904: if (nflg || tp->t_dev == 0 || /* XXX */ ! 905: (name = devname(tp->t_dev, S_IFCHR)) == NULL) ! 906: printf("%7d ", line); ! 907: else ! 908: printf("%7s ", name); ! 909: printf("%2d %3d ", tp->t_rawq.c_cc, tp->t_canq.c_cc); ! 910: printf("%3d %6d %6d %6d %4d %3d %8x %3d ", tp->t_outq.c_cc, ! 911: tp->t_rawcc, tp->t_cancc, tp->t_outcc, ! 912: tp->t_hiwat, tp->t_lowat, tp->t_addr, tp->t_col); ! 913: for (i = j = 0; ttystates[i].flag; i++) ! 914: if (tp->t_state&ttystates[i].flag) ! 915: state[j++] = ttystates[i].val; ! 916: state[j] = '\0'; ! 917: printf("%-4s ", state); ! 918: if (tp->t_pgrp == NULL || kvm_read(&tp->t_pgrp->pg_id, &pgid, ! 919: sizeof (pid_t)) != sizeof (pid_t)) ! 920: pgid = 0; ! 921: printf("%6d ", pgid); ! 922: switch (tp->t_line) { ! 923: ! 924: case 0: ! 925: printf("term\n"); ! 926: break; ! 927: ! 928: case TABLDISC: ! 929: printf("tab\n"); ! 930: break; ! 931: ! 932: case SLIPDISC: ! 933: printf("slip\n"); ! 934: break; ! 935: ! 936: default: ! 937: printf("%d\n", tp->t_line); ! 938: } ! 939: } ! 940: ! 941: dousr() ! 942: { ! 943: #ifdef notyet ! 944: register struct user *up; ! 945: register i, j, *ip; ! 946: register struct nameidata *nd = &U.u_nd; ! 947: struct proc *p; ! 948: ! 949: /* This wins only if CLBYTES >= sizeof (struct user) */ ! 950: /* (WHICH IT ISN'T, but u. is going away - so who cares */ ! 951: if (kvm_getprocs(KINFO_PROC_PID, upid) != 0) { ! 952: error("kvm_getproc: %s", kvm_geterr()); ! 953: return (1); ! 954: } ! 955: if ((p = kvm_nextproc()); == NULL) { ! 956: error("kvm_nextproc: %s", kvm_geterr()); ! 957: return (1); ! 958: } ! 959: if (up = kvm_getu(p)) == NULL) { ! 960: error("kvm_getu: %s", kvm_geterr()); ! 961: return (1); ! 962: } ! 963: printf("pcb"); ! 964: ip = (int *)&up->u_pcb; ! 965: while (ip < &up->u_arg[0]) { ! 966: if ((ip - (int *)&up->u_pcb) % 4 == 0) ! 967: printf("\t"); ! 968: printf("%x ", *ip++); ! 969: if ((ip - (int *)&up->u_pcb) % 4 == 0) ! 970: printf("\n"); ! 971: } ! 972: if ((ip - (int *)&up->u_pcb) % 4 != 0) ! 973: printf("\n"); ! 974: printf("arg"); ! 975: for (i=0; i<sizeof(up->u_arg)/sizeof(up->u_arg[0]); i++) { ! 976: if (i%5==0) ! 977: printf("\t"); ! 978: printf(" %.1x", up->u_arg[i]); ! 979: if (i%5==4) ! 980: printf("\n"); ! 981: } ! 982: if (i%5) ! 983: printf("\n"); ! 984: printf("segflg\t%d\nerror %d\n", nd->ni_segflg, up->u_error); ! 985: printf("uids\t%d,%d,%d,%d\n", up->u_uid,up->u_gid,up->u_ruid,up->u_rgid); ! 986: printf("procp\t%.1x\n", up->u_procp); ! 987: printf("ap\t%.1x\n", up->u_ap); ! 988: printf("r_val?\t%.1x %.1x\n", up->u_r.r_val1, up->u_r.r_val2); ! 989: printf("base, count, offset %.1x %.1x %ld\n", nd->ni_base, ! 990: nd->ni_count, nd->ni_offset); ! 991: printf("cdir rdir %.1x %.1x\n", up->u_cdir, up->u_rdir); ! 992: printf("dirp %.1x\n", nd->ni_dirp); ! 993: printf("dent %d %.14s\n", nd->ni_dent.d_ino, nd->ni_dent.d_name); ! 994: printf("dvp vp %.1x %.1x\n", nd->ni_dvp, nd->ni_vp); ! 995: printf("file"); ! 996: for (i=0; i<NOFILE; i++) { ! 997: if (i % 8 == 0) ! 998: printf("\t"); ! 999: printf("%9.1x", up->u_ofile[i]); ! 1000: if (i % 8 == 7) ! 1001: printf("\n"); ! 1002: } ! 1003: if (i % 8) ! 1004: printf("\n"); ! 1005: printf("pofile"); ! 1006: for (i=0; i<NOFILE; i++) { ! 1007: if (i % 8 == 0) ! 1008: printf("\t"); ! 1009: printf("%9.1x", up->u_pofile[i]); ! 1010: if (i % 8 == 7) ! 1011: printf("\n"); ! 1012: } ! 1013: if (i % 8) ! 1014: printf("\n"); ! 1015: printf("ssave"); ! 1016: for (i=0; i<sizeof(label_t)/sizeof(int); i++) { ! 1017: if (i%5==0) ! 1018: printf("\t"); ! 1019: printf("%9.1x", up->u_ssave.val[i]); ! 1020: if (i%5==4) ! 1021: printf("\n"); ! 1022: } ! 1023: if (i%5) ! 1024: printf("\n"); ! 1025: printf("sigs"); ! 1026: for (i=0; i<NSIG; i++) { ! 1027: if (i % 8 == 0) ! 1028: printf("\t"); ! 1029: printf("%.1x ", up->u_signal[i]); ! 1030: if (i % 8 == 7) ! 1031: printf("\n"); ! 1032: } ! 1033: if (i % 8) ! 1034: printf("\n"); ! 1035: printf("code\t%.1x\n", up->u_code); ! 1036: printf("ar0\t%.1x\n", up->u_ar0); ! 1037: printf("prof\t%x %x %x %x\n", up->u_prof.pr_base, up->u_prof.pr_size, ! 1038: up->u_prof.pr_off, up->u_prof.pr_scale); ! 1039: printf("start\t%ld\n", up->u_start.tv_sec); ! 1040: printf("acflag\t%ld\n", up->u_acflag); ! 1041: printf("cmask\t%ld\n", up->u_cmask); ! 1042: printf("sizes\t%.1x %.1x %.1x\n", up->u_tsize, up->u_dsize, up->u_ssize); ! 1043: printf("ru\t"); ! 1044: ip = (int *)&up->u_ru; ! 1045: for (i = 0; i < sizeof(up->u_ru)/sizeof(int); i++) ! 1046: printf("%ld ", ip[i]); ! 1047: printf("\n"); ! 1048: ip = (int *)&up->u_cru; ! 1049: printf("cru\t"); ! 1050: for (i = 0; i < sizeof(up->u_cru)/sizeof(int); i++) ! 1051: printf("%ld ", ip[i]); ! 1052: printf("\n"); ! 1053: #ifdef notdef ! 1054: i = up->u_stack - &U; ! 1055: while (U[++i] == 0); ! 1056: i &= ~07; ! 1057: while (i < 512) { ! 1058: printf("%x ", 0140000+2*i); ! 1059: for (j=0; j<8; j++) ! 1060: printf("%9x", U[i++]); ! 1061: printf("\n"); ! 1062: } ! 1063: #endif ! 1064: #endif ! 1065: } ! 1066: ! 1067: oatoi(s) ! 1068: char *s; ! 1069: { ! 1070: register v; ! 1071: ! 1072: v = 0; ! 1073: while (*s) ! 1074: v = (v<<3) + *s++ - '0'; ! 1075: return(v); ! 1076: } ! 1077: ! 1078: dofile() ! 1079: { ! 1080: int nfile; ! 1081: struct file *xfile, *afile; ! 1082: register struct file *fp; ! 1083: register nf; ! 1084: int loc; ! 1085: static char *dtypes[] = { "???", "inode", "socket" }; ! 1086: ! 1087: nf = 0; ! 1088: nfile = getword(nl[SNFILE].n_value); ! 1089: xfile = (struct file *)calloc(nfile, sizeof (struct file)); ! 1090: afile = (struct file *)getword(nl[SFIL].n_value); ! 1091: if (nfile < 0 || nfile > 10000) { ! 1092: fprintf(stderr, "number of files is preposterous (%d)\n", ! 1093: nfile); ! 1094: return; ! 1095: } ! 1096: if (xfile == NULL) { ! 1097: fprintf(stderr, "can't allocate memory for file table\n"); ! 1098: return; ! 1099: } ! 1100: kvm_read(afile, xfile, nfile * sizeof (struct file)); ! 1101: for (fp=xfile; fp < &xfile[nfile]; fp++) ! 1102: if (fp->f_count) ! 1103: nf++; ! 1104: if (totflg) { ! 1105: printf("%3d/%3d files\n", nf, nfile); ! 1106: return; ! 1107: } ! 1108: printf("%d/%d open files\n", nf, nfile); ! 1109: printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n"); ! 1110: for (fp=xfile,loc=(int)afile; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) { ! 1111: if (fp->f_count==0) ! 1112: continue; ! 1113: printf("%8x ", loc); ! 1114: if (fp->f_type <= DTYPE_SOCKET) ! 1115: printf("%-8.8s", dtypes[fp->f_type]); ! 1116: else ! 1117: printf("%8d", fp->f_type); ! 1118: putf(fp->f_flag&FREAD, 'R'); ! 1119: putf(fp->f_flag&FWRITE, 'W'); ! 1120: putf(fp->f_flag&FAPPEND, 'A'); ! 1121: putf(fp->f_flag&FSHLOCK, 'S'); ! 1122: putf(fp->f_flag&FEXLOCK, 'X'); ! 1123: putf(fp->f_flag&FASYNC, 'I'); ! 1124: printf(" %3d", mask(fp->f_count)); ! 1125: printf(" %3d", mask(fp->f_msgcount)); ! 1126: printf(" %8.1x", fp->f_data); ! 1127: if (fp->f_offset < 0) ! 1128: printf(" %x\n", fp->f_offset); ! 1129: else ! 1130: printf(" %ld\n", fp->f_offset); ! 1131: } ! 1132: free(xfile); ! 1133: } ! 1134: ! 1135: int dmmin, dmmax, nswdev; ! 1136: ! 1137: doswap() ! 1138: { ! 1139: struct proc *proc; ! 1140: int nproc; ! 1141: struct text *xtext; ! 1142: int ntext; ! 1143: struct map *swapmap; ! 1144: int nswapmap; ! 1145: struct swdevt *swdevt, *sw; ! 1146: register struct proc *pp; ! 1147: int nswap, used, tused, free, waste; ! 1148: int db, sb; ! 1149: register struct mapent *me; ! 1150: register struct text *xp; ! 1151: int i, j; ! 1152: long rmalloc(); ! 1153: ! 1154: nproc = getword(nl[SNPROC].n_value); ! 1155: ntext = getword(nl[SNTEXT].n_value); ! 1156: if (nproc < 0 || nproc > 10000 || ntext < 0 || ntext > 10000) { ! 1157: fprintf(stderr, "number of procs/texts is preposterous (%d, %d)\n", ! 1158: nproc, ntext); ! 1159: return; ! 1160: } ! 1161: proc = (struct proc *)calloc(nproc, sizeof (struct proc)); ! 1162: if (proc == NULL) { ! 1163: fprintf(stderr, "can't allocate memory for proc table\n"); ! 1164: exit(1); ! 1165: } ! 1166: xtext = (struct text *)calloc(ntext, sizeof (struct text)); ! 1167: if (xtext == NULL) { ! 1168: fprintf(stderr, "can't allocate memory for text table\n"); ! 1169: exit(1); ! 1170: } ! 1171: nswapmap = getword(nl[SNSWAPMAP].n_value); ! 1172: swapmap = (struct map *)calloc(nswapmap, sizeof (struct map)); ! 1173: if (swapmap == NULL) { ! 1174: fprintf(stderr, "can't allocate memory for swapmap\n"); ! 1175: exit(1); ! 1176: } ! 1177: nswdev = getword(nl[SNSWDEV].n_value); ! 1178: swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt)); ! 1179: if (swdevt == NULL) { ! 1180: fprintf(stderr, "can't allocate memory for swdevt table\n"); ! 1181: exit(1); ! 1182: } ! 1183: kvm_read(nl[SSWDEVT].n_value, swdevt, nswdev * sizeof (struct swdevt)); ! 1184: kvm_read(nl[SPROC].n_value, proc, nproc * sizeof (struct proc)); ! 1185: kvm_read(nl[STEXT].n_value, xtext, ntext * sizeof (struct text)); ! 1186: kvm_read(nl[SWAPMAP].n_value, swapmap, nswapmap * sizeof (struct map)); ! 1187: ! 1188: swapmap->m_name = "swap"; ! 1189: swapmap->m_limit = (struct mapent *)&swapmap[nswapmap]; ! 1190: dmmin = getword(nl[SDMMIN].n_value); ! 1191: dmmax = getword(nl[SDMMAX].n_value); ! 1192: nswap = 0; ! 1193: for (sw = swdevt; sw < &swdevt[nswdev]; sw++) ! 1194: if (sw->sw_freed) ! 1195: nswap += sw->sw_nblks; ! 1196: free = 0; ! 1197: for (me = (struct mapent *)(swapmap+1); ! 1198: me < (struct mapent *)&swapmap[nswapmap]; me++) ! 1199: free += me->m_size; ! 1200: tused = 0; ! 1201: for (xp = xtext; xp < &xtext[ntext]; xp++) ! 1202: if (xp->x_vptr!=NULL) { ! 1203: tused += ctod(clrnd(xp->x_size)); ! 1204: if (xp->x_flag & XPAGV) ! 1205: tused += ctod(clrnd(ctopt(xp->x_size))); ! 1206: } ! 1207: used = tused; ! 1208: waste = 0; ! 1209: for (pp = proc; pp < &proc[nproc]; pp++) { ! 1210: if (pp->p_stat == 0 || pp->p_stat == SZOMB) ! 1211: continue; ! 1212: if (pp->p_flag & SSYS) ! 1213: continue; ! 1214: db = ctod(pp->p_dsize), sb = up(db); ! 1215: used += sb; ! 1216: waste += sb - db; ! 1217: db = ctod(pp->p_ssize), sb = up(db); ! 1218: used += sb; ! 1219: waste += sb - db; ! 1220: if ((pp->p_flag&SLOAD) == 0) ! 1221: used += ctod(vusize(pp)); ! 1222: } ! 1223: if (totflg) { ! 1224: #define btok(x) ((x) / (1024 / DEV_BSIZE)) ! 1225: printf("%3d/%3d 00k swap\n", ! 1226: btok(used/100), btok((used+free)/100)); ! 1227: return; ! 1228: } ! 1229: printf("%dk used (%dk text), %dk free, %dk wasted, %dk missing\n", ! 1230: btok(used), btok(tused), btok(free), btok(waste), ! 1231: /* a dmmax/2 block goes to argmap */ ! 1232: btok(nswap - dmmax/2 - (used + free))); ! 1233: printf("avail: "); ! 1234: for (i = dmmax; i >= dmmin; i /= 2) { ! 1235: j = 0; ! 1236: while (rmalloc(swapmap, i) != 0) ! 1237: j++; ! 1238: if (j) printf("%d*%dk ", j, btok(i)); ! 1239: } ! 1240: free = 0; ! 1241: for (me = (struct mapent *)(swapmap+1); ! 1242: me < (struct mapent *)&swapmap[nswapmap]; me++) ! 1243: free += me->m_size; ! 1244: printf("%d*1k\n", btok(free)); ! 1245: } ! 1246: ! 1247: up(size) ! 1248: register int size; ! 1249: { ! 1250: register int i, block; ! 1251: ! 1252: i = 0; ! 1253: block = dmmin; ! 1254: while (i < size) { ! 1255: i += block; ! 1256: if (block < dmmax) ! 1257: block *= 2; ! 1258: } ! 1259: return (i); ! 1260: } ! 1261: ! 1262: /* ! 1263: * Compute number of pages to be allocated to the u. area ! 1264: * and data and stack area page tables, which are stored on the ! 1265: * disk immediately after the u. area. ! 1266: */ ! 1267: vusize(p) ! 1268: register struct proc *p; ! 1269: { ! 1270: register int tsz = p->p_tsize / NPTEPG; ! 1271: ! 1272: /* ! 1273: * We do not need page table space on the disk for page ! 1274: * table pages wholly containing text. ! 1275: */ ! 1276: return (clrnd(UPAGES + ! 1277: clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz)); ! 1278: } ! 1279: ! 1280: /* ! 1281: * Allocate 'size' units from the given ! 1282: * map. Return the base of the allocated space. ! 1283: * In a map, the addresses are increasing and the ! 1284: * list is terminated by a 0 size. ! 1285: * ! 1286: * Algorithm is first-fit. ! 1287: * ! 1288: * This routine knows about the interleaving of the swapmap ! 1289: * and handles that. ! 1290: */ ! 1291: long ! 1292: rmalloc(mp, size) ! 1293: register struct map *mp; ! 1294: long size; ! 1295: { ! 1296: register struct mapent *ep = (struct mapent *)(mp+1); ! 1297: register int addr; ! 1298: register struct mapent *bp; ! 1299: swblk_t first, rest; ! 1300: ! 1301: if (size <= 0 || size > dmmax) ! 1302: return (0); ! 1303: /* ! 1304: * Search for a piece of the resource map which has enough ! 1305: * free space to accomodate the request. ! 1306: */ ! 1307: for (bp = ep; bp->m_size; bp++) { ! 1308: if (bp->m_size >= size) { ! 1309: /* ! 1310: * If allocating from swapmap, ! 1311: * then have to respect interleaving ! 1312: * boundaries. ! 1313: */ ! 1314: if (nswdev > 1 && ! 1315: (first = dmmax - bp->m_addr%dmmax) < bp->m_size) { ! 1316: if (bp->m_size - first < size) ! 1317: continue; ! 1318: addr = bp->m_addr + first; ! 1319: rest = bp->m_size - first - size; ! 1320: bp->m_size = first; ! 1321: if (rest) ! 1322: rmfree(mp, rest, addr+size); ! 1323: return (addr); ! 1324: } ! 1325: /* ! 1326: * Allocate from the map. ! 1327: * If there is no space left of the piece ! 1328: * we allocated from, move the rest of ! 1329: * the pieces to the left. ! 1330: */ ! 1331: addr = bp->m_addr; ! 1332: bp->m_addr += size; ! 1333: if ((bp->m_size -= size) == 0) { ! 1334: do { ! 1335: bp++; ! 1336: (bp-1)->m_addr = bp->m_addr; ! 1337: } while ((bp-1)->m_size = bp->m_size); ! 1338: } ! 1339: if (addr % CLSIZE) ! 1340: return (0); ! 1341: return (addr); ! 1342: } ! 1343: } ! 1344: return (0); ! 1345: } ! 1346: ! 1347: /* ! 1348: * Free the previously allocated space at addr ! 1349: * of size units into the specified map. ! 1350: * Sort addr into map and combine on ! 1351: * one or both ends if possible. ! 1352: */ ! 1353: rmfree(mp, size, addr) ! 1354: struct map *mp; ! 1355: long size, addr; ! 1356: { ! 1357: struct mapent *firstbp; ! 1358: register struct mapent *bp; ! 1359: register int t; ! 1360: ! 1361: /* ! 1362: * Both address and size must be ! 1363: * positive, or the protocol has broken down. ! 1364: */ ! 1365: if (addr <= 0 || size <= 0) ! 1366: goto badrmfree; ! 1367: /* ! 1368: * Locate the piece of the map which starts after the ! 1369: * returned space (or the end of the map). ! 1370: */ ! 1371: firstbp = bp = (struct mapent *)(mp + 1); ! 1372: for (; bp->m_addr <= addr && bp->m_size != 0; bp++) ! 1373: continue; ! 1374: /* ! 1375: * If the piece on the left abuts us, ! 1376: * then we should combine with it. ! 1377: */ ! 1378: if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) { ! 1379: /* ! 1380: * Check no overlap (internal error). ! 1381: */ ! 1382: if ((bp-1)->m_addr+(bp-1)->m_size > addr) ! 1383: goto badrmfree; ! 1384: /* ! 1385: * Add into piece on the left by increasing its size. ! 1386: */ ! 1387: (bp-1)->m_size += size; ! 1388: /* ! 1389: * If the combined piece abuts the piece on ! 1390: * the right now, compress it in also, ! 1391: * by shifting the remaining pieces of the map over. ! 1392: */ ! 1393: if (bp->m_addr && addr+size >= bp->m_addr) { ! 1394: if (addr+size > bp->m_addr) ! 1395: goto badrmfree; ! 1396: (bp-1)->m_size += bp->m_size; ! 1397: while (bp->m_size) { ! 1398: bp++; ! 1399: (bp-1)->m_addr = bp->m_addr; ! 1400: (bp-1)->m_size = bp->m_size; ! 1401: } ! 1402: } ! 1403: goto done; ! 1404: } ! 1405: /* ! 1406: * Don't abut on the left, check for abutting on ! 1407: * the right. ! 1408: */ ! 1409: if (addr+size >= bp->m_addr && bp->m_size) { ! 1410: if (addr+size > bp->m_addr) ! 1411: goto badrmfree; ! 1412: bp->m_addr -= size; ! 1413: bp->m_size += size; ! 1414: goto done; ! 1415: } ! 1416: /* ! 1417: * Don't abut at all. Make a new entry ! 1418: * and check for map overflow. ! 1419: */ ! 1420: do { ! 1421: t = bp->m_addr; ! 1422: bp->m_addr = addr; ! 1423: addr = t; ! 1424: t = bp->m_size; ! 1425: bp->m_size = size; ! 1426: bp++; ! 1427: } while (size = t); ! 1428: /* ! 1429: * Segment at bp is to be the delimiter; ! 1430: * If there is not room for it ! 1431: * then the table is too full ! 1432: * and we must discard something. ! 1433: */ ! 1434: if (bp+1 > mp->m_limit) { ! 1435: /* ! 1436: * Back bp up to last available segment. ! 1437: * which contains a segment already and must ! 1438: * be made into the delimiter. ! 1439: * Discard second to last entry, ! 1440: * since it is presumably smaller than the last ! 1441: * and move the last entry back one. ! 1442: */ ! 1443: bp--; ! 1444: printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name, ! 1445: (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size); ! 1446: bp[-1] = bp[0]; ! 1447: bp[0].m_size = bp[0].m_addr = 0; ! 1448: } ! 1449: done: ! 1450: return; ! 1451: badrmfree: ! 1452: printf("bad rmfree\n"); ! 1453: } ! 1454: ! 1455: #include <varargs.h> ! 1456: ! 1457: error(va_alist) ! 1458: va_dcl ! 1459: { ! 1460: char *fmt; ! 1461: va_list ap; ! 1462: extern errno; ! 1463: ! 1464: fprintf(stderr, "%s: ", Program); ! 1465: va_start(ap); ! 1466: fmt = va_arg(ap, char *); ! 1467: (void) vfprintf(stderr, fmt, ap); ! 1468: va_end(ap); ! 1469: fprintf(stderr, "\n"); ! 1470: } ! 1471: ! 1472: syserror(va_alist) ! 1473: va_dcl ! 1474: { ! 1475: char *fmt; ! 1476: va_list ap; ! 1477: extern errno; ! 1478: ! 1479: fprintf(stderr, "%s: ", Program); ! 1480: va_start(ap); ! 1481: fmt = va_arg(ap, char *); ! 1482: (void) vfprintf(stderr, fmt, ap); ! 1483: va_end(ap); ! 1484: fprintf(stderr, ": %s\n", strerror(errno)); ! 1485: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.