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

unix.superglobalmegacorp.com

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