|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.