Annotation of researchv10no/cmd/dump/dumptape.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)dumptape.c  1.3 (Berkeley) 3/11/81";
                      2: #include "dump.h"
                      3: 
                      4: char   tblock[NTREC][BSIZE(0)];
                      5: daddr_t        tdaddr[NTREC];
                      6: int    trecno;
                      7: 
                      8: taprec(dp)
                      9: char *dp;
                     10: {
                     11:        register i;
                     12: 
                     13:        for(i=0; i<BSIZE(0); i++)
                     14:                tblock[trecno][i] = *dp++;
                     15:        tdaddr[trecno] = 0;
                     16:        trecno++;
                     17:        spcl.c_tapea++;
                     18:        if(trecno >= NTREC)
                     19:                flusht();
                     20: }
                     21: 
                     22: tapsrec(d)
                     23: daddr_t d;
                     24: {
                     25: 
                     26:        if(d == 0)
                     27:                return;
                     28:        tdaddr[trecno] = d;
                     29:        trecno++;
                     30:        spcl.c_tapea++;
                     31:        if(trecno >= NTREC)
                     32:                flusht();
                     33: }
                     34: 
                     35: int    nogripe = 0;
                     36: 
                     37: flusht()
                     38: {
                     39:        register i, si;
                     40:        daddr_t d;
                     41: 
                     42:        while(trecno < NTREC)
                     43:                tdaddr[trecno++] = 1;
                     44: 
                     45: loop:
                     46:        d = 0;
                     47:        for(i=0; i<NTREC; i++)
                     48:                if(tdaddr[i] != 0)
                     49:                if(d == 0 || tdaddr[i] < d) {
                     50:                        si = i;
                     51:                        d = tdaddr[i];
                     52:                }
                     53:        if(d != 0) {
                     54:                bread(d, tblock[si], BSIZE(0));
                     55:                tdaddr[si] = 0;
                     56:                goto loop;
                     57:        }
                     58:        trecno = 0;
                     59:        if (write(to, tblock[0], sizeof(tblock)) != sizeof(tblock) ){
                     60:                msg("Tape write error on tape %d\n", tapeno);
                     61:                broadcast("TAPE ERROR!\n");
                     62:                if (query("Do you want to restart?")){
                     63:                        msg("This tape will rewind.  After it is rewound,\n");
                     64:                        msg("replace the faulty tape with a new one;\n");
                     65:                        msg("this dump volume will be rewritten.\n");
                     66:                        /*
                     67:                         *      Temporarily change the tapeno identification
                     68:                         */
                     69:                        tapeno--;
                     70:                        nogripe = 1;
                     71:                        close_rewind();
                     72:                        nogripe = 0;
                     73:                        tapeno++;
                     74:                        Exit(X_REWRITE);
                     75:                } else {
                     76:                        dumpabort();
                     77:                        /*NOTREACHED*/
                     78:                }
                     79:        }
                     80: 
                     81:        asize += sizeof(tblock)/density;
                     82:        asize += 7;
                     83:        blockswritten += NTREC;
                     84:        if (asize > tsize) {
                     85:                close_rewind();
                     86:                otape();
                     87:        }
                     88:        timeest();
                     89: }
                     90: 
                     91: rewind()
                     92: {
                     93:        int     secs;
                     94:        int f;
                     95: #ifdef DEBUG
                     96:        msg("Waiting 10 seconds to rewind.\n");
                     97:        sleep(10);
                     98: #else
                     99:        /*
                    100:         *      It takes about 3 minutes, 25secs to rewind 2300' of tape
                    101:         */
                    102:        msg("Tape rewinding\n", secs);
                    103:        close(to);
                    104:        while ((f = open(tape, 0)) < 0)
                    105:                sleep (10);
                    106:        close(f);
                    107: #endif
                    108: }
                    109: 
                    110: close_rewind()
                    111: {
                    112:        close(to);
                    113:        if (!nogripe){
                    114:                rewind();
                    115:                msg("Change Tapes: Mount tape #%d\n", tapeno+1);
                    116:                broadcast("CHANGE TAPES!\7\7\n");
                    117:        }
                    118:        do{
                    119:                if (query ("Is the new tape mounted and ready to go?"))
                    120:                        break;
                    121:                if (query ("Do you want to abort?")){
                    122:                        dumpabort();
                    123:                        /*NOTREACHED*/
                    124:                }
                    125:        } while (1);
                    126: }
                    127: 
                    128: /*
                    129:  *     We implement taking and restoring checkpoints on
                    130:  *     the tape level.
                    131:  *     When each tape is opened, a new process is created by forking; this
                    132:  *     saves all of the necessary context in the parent.  The child
                    133:  *     continues the dump; the parent waits around, saving the context.
                    134:  *     If the child returns X_REWRITE, then it had problems writing that tape;
                    135:  *     this causes the parent to fork again, duplicating the context, and
                    136:  *     everything continues as if nothing had happened.
                    137:  */
                    138: 
                    139: otape()
                    140: {
                    141:        int     parentpid;
                    142:        int     childpid;
                    143:        int     status;
                    144:        int     waitpid;
                    145:        int     sig_ign_parent();
                    146:        int     interrupt();
                    147: 
                    148:        /*
                    149:         *      Force the tape to be closed
                    150:         */
                    151:        close(to);
                    152:        parentpid = getpid();
                    153: 
                    154:     restore_check_point:
                    155:        signal(SIGINT, interrupt);
                    156:        /*
                    157:         *      All signals are inherited...
                    158:         */
                    159:        childpid = fork();
                    160:        if (childpid < 0){
                    161:                msg("Context save fork fails in parent %d\n", parentpid);
                    162:                Exit(X_ABORT);
                    163:        }
                    164:        if (childpid != 0){
                    165:                /*
                    166:                 *      PARENT:
                    167:                 *      save the context by waiting
                    168:                 *      until the child doing all of the work returns.
                    169:                 *      don't catch the interrupt 
                    170:                 */
                    171:                signal(SIGINT, SIG_IGN);
                    172: #ifdef TDEBUG
                    173:                msg("Tape: %d; parent process: %d child process %d\n",
                    174:                        tapeno+1, parentpid, childpid);
                    175: #endif TDEBUG
                    176:                for (;;){
                    177:                        waitpid = wait(&status);
                    178:                        if (waitpid != childpid){
                    179:                                msg("Parent %d waiting for child %d has another child %d return\n",
                    180:                                        parentpid, childpid, waitpid);
                    181:                        } else
                    182:                                break;
                    183:                }
                    184:                if (status & 0xFF){
                    185:                        msg("Child %d returns LOB status %o\n",
                    186:                                childpid, status&0xFF);
                    187:                }
                    188:                status = (status >> 8) & 0xFF;
                    189: #ifdef TDEBUG
                    190:                switch(status){
                    191:                        case X_FINOK:
                    192:                                msg("Child %d finishes X_FINOK\n", childpid);
                    193:                                break;
                    194:                        case X_ABORT:
                    195:                                msg("Child %d finishes X_ABORT\n", childpid);
                    196:                                break;
                    197:                        case X_REWRITE:
                    198:                                msg("Child %d finishes X_REWRITE\n", childpid);
                    199:                                break;
                    200:                        default:
                    201:                                msg("Child %d finishes unknown %d\n", childpid,status);
                    202:                                break;
                    203:                }
                    204: #endif TDEBUG
                    205:                switch(status){
                    206:                        case X_FINOK:
                    207:                                Exit(X_FINOK);
                    208:                        case X_ABORT:
                    209:                                Exit(X_ABORT);
                    210:                        case X_REWRITE:
                    211:                                goto restore_check_point;
                    212:                        default:
                    213:                                msg("Bad return code from dump: %d\n", status);
                    214:                                Exit(X_ABORT);
                    215:                }
                    216:                /*NOTREACHED*/
                    217:        } else {        /* we are the child; just continue */
                    218: #ifdef TDEBUG
                    219:                sleep(4);       /* allow time for parent's message to get out */
                    220:                msg("Child on Tape %d has parent %d, my pid = %d\n",
                    221:                        tapeno+1, parentpid, getpid());
                    222: #endif
                    223:                do{
                    224:                        to = creat(tape, 0666);
                    225:                        if (to < 0) {
                    226:                                if (!query("Cannot open tape. Do you want to retry the open?"))
                    227:                                        dumpabort();
                    228:                        } else break;
                    229:                } while (1);
                    230: 
                    231:                asize = 0;
                    232:                tapeno++;               /* current tape sequence */
                    233:                newtape++;              /* new tape signal */
                    234:                spcl.c_volume++;
                    235:                spcl.c_type = TS_TAPE;
                    236:                spclrec();
                    237:                if (tapeno > 1)
                    238:                        msg("Tape %d begins with blocks from ino %d\n",
                    239:                                tapeno, ino);
                    240:        }
                    241: }
                    242: 
                    243: /*
                    244:  *     The parent still catches interrupts, but does nothing with them
                    245:  */
                    246: sig_ign_parent()
                    247: {
                    248:        msg("Waiting parent receives interrupt\n");
                    249:        signal(SIGINT, sig_ign_parent);
                    250: }
                    251: 
                    252: dumpabort()
                    253: {
                    254:        msg("The ENTIRE dump is aborted.\n");
                    255:        Exit(X_ABORT);
                    256: }
                    257: 
                    258: Exit(status)
                    259: {
                    260: #ifdef TDEBUG
                    261:        msg("pid = %d exits with status %d\n", getpid(), status);
                    262: #endif TDEBUG
                    263:        exit(status);
                    264: }

unix.superglobalmegacorp.com

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