Annotation of 43BSDReno/usr.sbin/pstat/pstat.c, revision 1.1.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.