Annotation of 42BSD/etc/dump/dumprtape.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)dumprtape.c 1.5 83/08/11";
                      2: 
                      3: #include "dump.h"
                      4: 
                      5: /*
                      6:  * tape buffering routines double buffer for remote dump.
                      7:  * tblock[1-rotor] is written to remote in tape order
                      8:  * as tblock[rotor] is filled in in seek order.
                      9:  */
                     10: 
                     11: struct atblock {
                     12:        char    tblock[TP_BSIZE];
                     13: };
                     14: struct atblock *tblock[2];     /* Pointers to malloc()ed buffers for tape */
                     15: int    writesize;              /* Size of single malloc()ed buffer for tape */
                     16: int    trotor = 0;
                     17: daddr_t *tdaddr;               /* Pointer to array of disk addrs */
                     18: int    toldindex, tcurindex, trecno;
                     19: extern int ntrec;              /* blocking factor on tape */
                     20: 
                     21: /*
                     22:  * Allocate the buffer for tape operations.
                     23:  *
                     24:  * Depends on global variable ntrec, set from 'b' option in command line.
                     25:  * Returns 1 if successful, 0 if failed.
                     26:  *
                     27:  * For later kernel performance improvement, this buffer should be allocated
                     28:  * on a page boundary.
                     29:  */
                     30: alloctape()
                     31: {
                     32: 
                     33:        writesize = ntrec * TP_BSIZE;
                     34:        tblock[0] = (struct atblock *)malloc(2 * writesize);
                     35:        if (tblock[0] == 0)
                     36:                return (0);
                     37:        tblock[1] = tblock[0]+ntrec;    /* Point to second bigbuffer */
                     38:        tdaddr = (daddr_t *)malloc(ntrec * sizeof(daddr_t));
                     39:        return (tdaddr != NULL);
                     40: }
                     41: 
                     42: taprec(dp)
                     43:        char *dp;
                     44: {
                     45:        register i;
                     46:        register struct atblock *bp = tblock[tcurindex];
                     47: 
                     48:        tadvance();
                     49:        tdaddr[tcurindex] = 0;
                     50:        *(&tblock[trotor][tcurindex++]) = *(struct atblock *)dp;
                     51:        spcl.c_tapea++;
                     52:        if (tcurindex >= ntrec)
                     53:                flusht();
                     54: }
                     55: 
                     56: dmpblk(blkno, size)
                     57:        daddr_t blkno;
                     58:        int size;
                     59: {
                     60:        int tpblks, dblkno;
                     61: 
                     62:        if (size % TP_BSIZE != 0)
                     63:                msg("bad size to dmpblk: %d\n", size);
                     64:        dblkno = fsbtodb(sblock, blkno);
                     65:        for (tpblks = size / TP_BSIZE; tpblks > 0; tpblks--) {
                     66:                tapsrec(dblkno);
                     67:                dblkno += TP_BSIZE / DEV_BSIZE;
                     68:        }
                     69: }
                     70: 
                     71: int    nogripe = 0;
                     72: 
                     73: tadvance()
                     74: {
                     75: 
                     76:        if (trecno == 0)
                     77:                return;
                     78:        if (toldindex == 0)
                     79:                rmtwrite0(TP_BSIZE * ntrec);
                     80:        rmtwrite1((char *)(&tblock[1 - trotor][toldindex++]), TP_BSIZE);
                     81:        if (toldindex != ntrec)
                     82:                return;
                     83:        toldindex = 0;
                     84:        if (rmtwrite2() != writesize) {
                     85:                msg("Write error on tape %d\n", tapeno);
                     86:                broadcast("TAPE ERROR!\n");
                     87:                if (query("Restart this tape?") == 0)
                     88:                        dumpabort();
                     89:                msg("After this tape rewinds, replace the reel\n");
                     90:                msg("and the dump volume will be rewritten.\n");
                     91:                close_rewind();
                     92:                exit(X_REWRITE);
                     93:        }
                     94: }
                     95: 
                     96: close_rewind()
                     97: {
                     98: 
                     99:        rewind();
                    100:        tnexttape();
                    101: }
                    102: 
                    103: /* pad out last tape block */
                    104: tfillspec()
                    105: {
                    106: 
                    107:        while (tcurindex)
                    108:                spclrec();
                    109: }
                    110: 
                    111: tapsrec(d)
                    112:        daddr_t d;
                    113: {
                    114: 
                    115:        if (d == 0)
                    116:                return;
                    117:        tdaddr[tcurindex] = d;
                    118:        tcurindex++;
                    119:        spcl.c_tapea++;
                    120:        if (tcurindex >= ntrec)
                    121:                flusht();
                    122: }
                    123: 
                    124: flusht()
                    125: {
                    126:        register i, si;
                    127:        daddr_t d;
                    128: 
                    129:        while (tcurindex < ntrec)
                    130:                tdaddr[tcurindex++] = 1;
                    131: loop:
                    132:        d = 0;
                    133:        for (i=0; i<ntrec; i++)
                    134:                if (tdaddr[i] != 0)
                    135:                        if (d == 0 || tdaddr[i] < d) {
                    136:                                si = i;
                    137:                                d = tdaddr[i];
                    138:                        }
                    139:        if (d != 0) {
                    140:                tadvance();
                    141:                bread(d, (char *)&tblock[trotor][si], TP_BSIZE);
                    142:                tdaddr[si] = 0;
                    143:                goto loop;
                    144:        }
                    145:        tcurindex = 0;
                    146:        trecno++;
                    147:        trotor = 1 - trotor;
                    148:        asize += writesize/density;
                    149:        asize += 7;
                    150:        blockswritten += ntrec;
                    151:        if (asize > tsize) {
                    152:                tflush(0);
                    153:                rewind();
                    154:                msg("Change Tapes: Mount tape #%d\n", tapeno+1);
                    155:                broadcast("CHANGE TAPES!\7\7\n");
                    156:                tnexttape();
                    157:                otape();
                    158:                /* returns in child */
                    159:        }
                    160:        timeest();
                    161: }
                    162: 
                    163: tflush(eof)
                    164:        int eof;
                    165: {
                    166:        int i;
                    167: 
                    168:        if (eof) {
                    169:                do {
                    170:                        spclrec();
                    171:                } while (tcurindex);
                    172:        }
                    173:        for (i = 0; i < ntrec; i++)
                    174:                tadvance();
                    175: }
                    176: 
                    177: tnexttape()
                    178: {
                    179: 
                    180: again:
                    181:        if (query("Next tape ready?") == 1)
                    182:                return;
                    183:        if (query("Want to abort?") == 1)
                    184:                dumpabort();
                    185:        goto again;
                    186: }
                    187: 
                    188: rewind()
                    189: {
                    190: 
                    191:        msg("Tape rewinding\n");
                    192:        rmtclose();
                    193:        while (rmtopen(tape, 0, 0) < 0)
                    194:                sleep(10);
                    195:        rmtclose();
                    196: }
                    197: 
                    198: otape()
                    199: {
                    200:        int ppid, child, status;
                    201:        int w, interrupt();
                    202: 
                    203:        rmtclose();
                    204:        ppid = getpid();
                    205: again:
                    206:        signal(SIGINT, interrupt);
                    207:        child = fork();
                    208:        if (child < 0) {
                    209:                msg("Context save fork fails in parent %d\n", ppid);
                    210:                exit(X_ABORT);
                    211:        }
                    212:        if (child != 0) {
                    213:                signal(SIGINT, SIG_IGN);
                    214:                for (;;) {
                    215:                        w = wait(&status);
                    216:                        if (w == child)
                    217:                                break;
                    218: msg("Parent %d waiting for %d has another child %d return\n", ppid, child, w);
                    219:                }
                    220:                if (status & 0xff)
                    221: msg("Child %d returns LOB status %o\n", child, status & 0xff);
                    222:                switch ((status >> 8) & 0xff) {
                    223: 
                    224:                case X_FINOK:
                    225:                        exit(X_FINOK);
                    226: 
                    227:                case X_ABORT:
                    228:                        exit(X_ABORT);
                    229: 
                    230:                case X_REWRITE:
                    231:                        rmtclose();
                    232: #ifdef notdef
                    233:                        do {
                    234:                                if (!query("Retry conection to remote host?"))
                    235:                                        exit(X_ABORT);
                    236:                                rmtgetconn();
                    237:                        } while (rmtape < 0);
                    238: #endif
                    239:                        goto again;
                    240: 
                    241:                default:
                    242:                        msg("Bad return code from dump: %d\n", status);
                    243:                        exit(X_ABORT);
                    244:                }
                    245:                /*NOTREACHED*/
                    246:        }
                    247:        for (;;) {
                    248:                if (rmtopen(tape, 2) >= 0)
                    249:                        break;
                    250:                if (query("Tape open failed, try again?") == 0)
                    251:                        dumpabort();
                    252:        }
                    253:        asize = 0;
                    254:        tapeno++, newtape++;
                    255:        trecno = 0;
                    256:        spcl.c_volume++;
                    257:        spcl.c_type = TS_TAPE;
                    258:        spclrec();
                    259:        if (tapeno > 1)
                    260:                msg("Tape %d begins with blocks from ino %d\n", tapeno, ino);
                    261: }
                    262: 
                    263: dumpabort()
                    264: {
                    265: 
                    266:        msg("The ENTIRE dump is aborted.\n");
                    267:        exit(X_ABORT);
                    268: }
                    269: 
                    270: Exit(code)
                    271:        int code;
                    272: {
                    273: 
                    274:        exit(code);
                    275: }

unix.superglobalmegacorp.com

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