1: static  char *sccsid = "@(#)dumptape.c	1.3 (Berkeley) 3/11/81";
   2: #include "dump.h"
   3: 
   4: char    tblock[NTREC][DEV_BSIZE];
   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<DEV_BSIZE; 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], DEV_BSIZE);
  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 f;
  94: #ifdef DEBUG
  95:     msg("Waiting 10 seconds to rewind.\n");
  96:     sleep(10);
  97: #else
  98:     /*
  99: 	 *	It takes about 3 minutes, 25secs to rewind 2300' of tape
 100: 	 */
 101:     msg("Tape rewinding\n");
 102:     close(to);
 103:     while ((f = open(tape, 0)) < 0)
 104:         sleep (10);
 105:     close(f);
 106: #endif
 107: }
 108: 
 109: close_rewind()
 110: {
 111:     close(to);
 112:     if (!nogripe){
 113:         rewind();
 114:         msg("Change Tapes: Mount tape #%d\n", tapeno+1);
 115:         broadcast("CHANGE TAPES!\7\7\n");
 116:     }
 117:     do{
 118:         if (query ("Is the new tape mounted and ready to go?"))
 119:             break;
 120:         if (query ("Do you want to abort?")){
 121:             dumpabort();
 122:             /*NOTREACHED*/
 123:         }
 124:     } while (1);
 125: }
 126: 
 127: /*
 128:  *	We implement taking and restoring checkpoints on
 129:  *	the tape level.
 130:  *	When each tape is opened, a new process is created by forking; this
 131:  *	saves all of the necessary context in the parent.  The child
 132:  *	continues the dump; the parent waits around, saving the context.
 133:  *	If the child returns X_REWRITE, then it had problems writing that tape;
 134:  *	this causes the parent to fork again, duplicating the context, and
 135:  *	everything continues as if nothing had happened.
 136:  */
 137: 
 138: otape()
 139: {
 140:     int parentpid;
 141:     int childpid;
 142:     int status;
 143:     int waitpid;
 144:     int sig_ign_parent();
 145:     int interrupt();
 146: 
 147:     /*
 148: 	 *	Force the tape to be closed
 149: 	 */
 150:     close(to);
 151:     parentpid = getpid();
 152: 
 153:     restore_check_point:
 154:     signal(SIGINT, interrupt);
 155:     /*
 156: 	 *	All signals are inherited...
 157: 	 */
 158:     childpid = fork();
 159:     if (childpid < 0){
 160:         msg("Context save fork fails in parent %d\n", parentpid);
 161:         Exit(X_ABORT);
 162:     }
 163:     if (childpid != 0){
 164:         /*
 165: 		 *	PARENT:
 166: 		 *	save the context by waiting
 167: 		 *	until the child doing all of the work returns.
 168: 		 *	don't catch the interrupt
 169: 		 */
 170:         signal(SIGINT, SIG_IGN);
 171: #ifdef TDEBUG
 172:         msg("Tape: %d; parent process: %d child process %d\n",
 173:             tapeno+1, parentpid, childpid);
 174: #endif TDEBUG
 175:         for (;;){
 176:             waitpid = wait(&status);
 177:             if (waitpid != childpid){
 178:                 msg("Parent %d waiting for child %d has another child %d return\n",
 179:                     parentpid, childpid, waitpid);
 180:             } else
 181:                 break;
 182:         }
 183:         if (status & 0xFF){
 184:             msg("Child %d returns LOB status %o\n",
 185:                 childpid, status&0xFF);
 186:         }
 187:         status = (status >> 8) & 0xFF;
 188: #ifdef TDEBUG
 189:         switch(status){
 190:             case X_FINOK:
 191:                 msg("Child %d finishes X_FINOK\n", childpid);
 192:                 break;
 193:             case X_ABORT:
 194:                 msg("Child %d finishes X_ABORT\n", childpid);
 195:                 break;
 196:             case X_REWRITE:
 197:                 msg("Child %d finishes X_REWRITE\n", childpid);
 198:                 break;
 199:             default:
 200:                 msg("Child %d finishes unknown %d\n", childpid,status);
 201:                 break;
 202:         }
 203: #endif TDEBUG
 204:         switch(status){
 205:             case X_FINOK:
 206:                 Exit(X_FINOK);
 207:             case X_ABORT:
 208:                 Exit(X_ABORT);
 209:             case X_REWRITE:
 210:                 goto restore_check_point;
 211:             default:
 212:                 msg("Bad return code from dump: %d\n", status);
 213:                 Exit(X_ABORT);
 214:         }
 215:         /*NOTREACHED*/
 216:     } else {    /* we are the child; just continue */
 217: #ifdef TDEBUG
 218:         sleep(4);   /* allow time for parent's message to get out */
 219:         msg("Child on Tape %d has parent %d, my pid = %d\n",
 220:             tapeno+1, parentpid, getpid());
 221: #endif
 222:         do{
 223:             to = creat(tape, 0666);
 224:             if (to < 0) {
 225:                 if (!query("Cannot open tape. Do you want to retry the open?"))
 226:                     dumpabort();
 227:             } else break;
 228:         } while (1);
 229: 
 230:         asize = 0;
 231:         tapeno++;       /* current tape sequence */
 232:         newtape++;      /* new tape signal */
 233:         spcl.c_volume++;
 234:         spcl.c_type = TS_TAPE;
 235:         spclrec();
 236:         if (tapeno > 1)
 237:             msg("Tape %d begins with blocks from ino %d\n",
 238:                 tapeno, ino);
 239:     }
 240: }
 241: 
 242: /*
 243:  *	The parent still catches interrupts, but does nothing with them
 244:  */
 245: sig_ign_parent()
 246: {
 247:     msg("Waiting parent receives interrupt\n");
 248:     signal(SIGINT, sig_ign_parent);
 249: }
 250: 
 251: dumpabort()
 252: {
 253:     msg("The ENTIRE dump is aborted.\n");
 254:     Exit(X_ABORT);
 255: }
 256: 
 257: Exit(status)
 258: {
 259: #ifdef TDEBUG
 260:     msg("pid = %d exits with status %d\n", getpid(), status);
 261: #endif TDEBUG
 262:     exit(status);
 263: }

Defined functions

Exit defined in line 257; used 11 times
close_rewind defined in line 109; used 3 times
flusht defined in line 37; used 2 times
otape defined in line 138; used 2 times
rewind defined in line 91; used 2 times
sig_ign_parent defined in line 245; used 2 times
taprec defined in line 8; used 2 times
tapsrec defined in line 22; used 1 times

Defined variables

nogripe defined in line 35; used 3 times
sccsid defined in line 1; never used
tblock defined in line 4; used 6 times
tdaddr defined in line 5; used 7 times
trecno defined in line 6; used 10 times
Last modified: 1988-12-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3976
Valid CSS Valid XHTML 1.0 Strict