|
|
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.