Annotation of 43BSDReno/usr.sbin/pstat/pstat.c, revision 1.1

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, &copysize, 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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.