]>
Commit | Line | Data |
---|---|---|
70deb804 SP |
1 | #include <config.h> |
2 | #include <compatlfs.h> | |
3 | #include <ctype.h> | |
4 | #include <compaterr.h> | |
5 | #include <fcntl.h> | |
6 | #include <fstab.h> | |
7 | #include <signal.h> | |
8 | #include <stdio.h> | |
9 | #include <stdlib.h> | |
10 | #include <string.h> | |
11 | #include <unistd.h> | |
12 | #include <errno.h> | |
13 | ||
14 | #include <sys/param.h> | |
15 | #include <sys/time.h> | |
16 | #include <time.h> | |
17 | #ifdef __linux__ | |
18 | #include <linux/types.h> | |
19 | #include <sys/stat.h> | |
20 | #include <sys/mtio.h> | |
21 | #include <bsdcompat.h> | |
22 | #include <linux/fs.h> /* for definition of BLKFLSBUF */ | |
23 | #elif defined sunos | |
24 | #include <sys/vnode.h> | |
25 | ||
26 | #include <ufs/inode.h> | |
27 | #include <ufs/fs.h> | |
28 | #else | |
29 | #include <ufs/ufs/dinode.h> | |
30 | #include <ufs/ffs/fs.h> | |
31 | #endif | |
32 | ||
33 | #include <protocols/dumprestore.h> | |
34 | ||
35 | //#include "dump.h" | |
36 | #include "indexer.h" | |
37 | #include "slave.h" | |
38 | ||
39 | extern dump_ino_t volinfo[]; // TP_NINOS | |
40 | extern int tapeno; | |
41 | ||
42 | static int Afile = -1; /* archive file descriptor */ | |
43 | static int AfileActive = 1;/* Afile flag */ | |
44 | ||
45 | //extern char *Apath; | |
46 | char *Apath; | |
47 | ||
48 | #ifdef USE_QFA | |
49 | static int GetTapePos __P((long long *)); | |
50 | static int MkTapeString __P((struct s_spcl *, long long)); | |
51 | #define FILESQFAPOS 20 | |
52 | ||
53 | int tapepos; | |
54 | int ntrec; /* blocking factor on tape */ | |
55 | int magtapeout; /* is output a magnetic tape? */ | |
56 | //extern int tapepos; | |
57 | //extern int ntrec; /* blocking factor on tape */ | |
58 | //extern int magtapeout; /* is output a magnetic tape? */ | |
59 | ||
60 | static int gtperr = 0; | |
61 | static int gTapeposfd; | |
62 | static char *gTapeposfile; | |
63 | static char gTps[255]; | |
64 | static int32_t gThisDumpDate; | |
65 | #endif /* USE_QFA */ | |
66 | ||
67 | void msg __P((const char *fmt, ...)); | |
68 | void quit __P((const char *fmt, ...)); | |
69 | ||
70 | extern char *host; | |
71 | extern int tapefd; | |
72 | ||
73 | /* | |
74 | * Open the indexer file. | |
75 | */ | |
76 | static int | |
77 | legacy_open(const char *filename, int mode) | |
78 | { | |
79 | if (filename == NULL) { | |
80 | return 0; | |
81 | } | |
82 | ||
83 | if (mode == 0) { | |
84 | if ((Afile = OPEN(filename, O_RDONLY)) < 0) { | |
85 | msg("Cannot open %s for reading: %s\n", | |
86 | filename, strerror(errno)); | |
87 | msg("The ENTIRE dump is aborted.\n"); | |
88 | return -1; | |
89 | } | |
90 | } else if (mode == 1) { | |
91 | if ((Afile = OPEN(filename, O_WRONLY|O_CREAT|O_TRUNC, | |
92 | S_IRUSR | S_IWUSR | S_IRGRP | | |
93 | S_IWGRP | S_IROTH | S_IWOTH)) < 0) { | |
94 | msg("Cannot open %s for writing: %s\n", | |
95 | filename, strerror(errno)); | |
96 | msg("The ENTIRE dump is aborted.\n"); | |
97 | return -1; | |
98 | } | |
99 | } | |
100 | ||
101 | return 0; | |
102 | } | |
103 | ||
104 | /* | |
105 | * Close the indexer file. | |
106 | */ | |
107 | static int | |
108 | legacy_close() | |
109 | { | |
110 | if (Afile >= 0) | |
111 | msg("Archiving dump to %s\n", Apath); | |
112 | return 0; | |
113 | } | |
114 | ||
115 | /* | |
116 | * Write a record to the indexer file. | |
117 | */ | |
118 | static int | |
119 | legacy_writerec(const void *dp, int isspcl) | |
120 | { | |
121 | if (! AfileActive && isspcl && (spcl.c_type == TS_END)) | |
122 | AfileActive = 1; | |
123 | if (AfileActive && Afile >= 0 && !(spcl.c_flags & DR_EXTATTRIBUTES)) { | |
124 | /* When we dump an inode which is not a directory, | |
125 | * it means we ended the archive contents */ | |
126 | if (isspcl && (spcl.c_type == TS_INODE) && | |
127 | ((spcl.c_dinode.di_mode & S_IFMT) != IFDIR)) | |
128 | AfileActive = 0; | |
129 | else { | |
130 | union u_spcl tmp; | |
131 | tmp = *(union u_spcl *)dp; | |
132 | /* Write the record, _uncompressed_ */ | |
133 | if (isspcl) { | |
134 | tmp.s_spcl.c_flags &= ~DR_COMPRESSED; | |
135 | mkchecksum(&tmp); | |
136 | } | |
137 | if (write(Afile, &tmp, TP_BSIZE) != TP_BSIZE) | |
138 | msg("error writing archive file: %s\n", | |
139 | strerror(errno)); | |
140 | } | |
141 | } | |
142 | return 0; | |
143 | } | |
144 | ||
145 | /* | |
146 | * I'm not sure what this is used for... | |
147 | */ | |
148 | static int | |
149 | legacy_foo() | |
150 | { | |
151 | if (Afile >= 0) { | |
152 | volinfo[1] = ROOTINO; | |
153 | memcpy(spcl.c_inos, volinfo, TP_NINOS * sizeof(dump_ino_t)); | |
154 | spcl.c_flags |= DR_INODEINFO; | |
155 | } | |
156 | return 0; | |
157 | } | |
158 | ||
159 | /* | |
160 | * Dump inode | |
161 | */ | |
162 | static int | |
163 | legacy_addInode(struct dinode *dp, dump_ino_t ino, int metaonly) | |
164 | { | |
165 | return 0; | |
166 | } | |
167 | ||
168 | /* | |
169 | * Dump directory (dirent) entry | |
170 | */ | |
171 | static int | |
172 | legacy_addDirEntry(struct direct *dp, dump_ino_t parent_ino) | |
173 | { | |
174 | return 0; | |
175 | } | |
176 | ||
177 | ||
178 | #define LSEEK_GET_TAPEPOS 10 | |
179 | #define LSEEK_GO2_TAPEPOS 11 | |
180 | ||
181 | /* | |
182 | * | |
183 | */ | |
184 | static int | |
185 | legacy_openQfa() | |
186 | { | |
187 | #ifdef USE_QFA | |
188 | gThisDumpDate = spcl.c_date; | |
189 | if (tapepos) { | |
190 | msg("writing QFA positions to %s\n", gTapeposfile); | |
191 | if ((gTapeposfd = open(gTapeposfile, | |
192 | O_WRONLY|O_CREAT|O_TRUNC, | |
193 | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | |
194 | | S_IROTH | S_IWOTH)) < 0) | |
195 | quit("can't open tapeposfile\n"); | |
196 | /* print QFA-file header */ | |
197 | snprintf(gTps, sizeof(gTps), "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date); | |
198 | gTps[sizeof(gTps) - 1] = '\0'; | |
199 | if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) | |
200 | quit("can't write tapeposfile\n"); | |
201 | sprintf(gTps, "ino\ttapeno\ttapepos\n"); | |
202 | if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) | |
203 | quit("can't write tapeposfile\n"); | |
204 | } | |
205 | #endif /* USE_QFA */ | |
206 | return 0; | |
207 | } | |
208 | ||
209 | /* | |
210 | * | |
211 | */ | |
212 | static int | |
213 | legacy_closeQfa() | |
214 | { | |
215 | return 0; | |
216 | } | |
217 | ||
218 | /* | |
219 | * | |
220 | */ | |
221 | static int | |
222 | legacy_openQfaState(QFA_State *s) | |
223 | { | |
224 | s->curtapepos = 0; | |
225 | s->maxntrecs = 50000; /* every 50MB */ | |
226 | s->cntntrecs = s->maxntrecs; | |
227 | return 0; | |
228 | } | |
229 | ||
230 | /* | |
231 | * | |
232 | */ | |
233 | static int | |
234 | legacy_updateQfaState(QFA_State *s) | |
235 | { | |
236 | if (gTapeposfd >= 0) { | |
237 | s->cntntrecs += ntrec; | |
238 | } | |
239 | ||
240 | return 0; | |
241 | } | |
242 | ||
243 | ||
244 | /* | |
245 | * | |
246 | */ | |
247 | static int | |
248 | legacy_updateQfa(QFA_State *s) | |
249 | { | |
250 | #ifdef USE_QFA | |
251 | union u_spcl *uspclptr; | |
252 | struct s_spcl *spclptr; | |
253 | ||
254 | if (gTapeposfd >= 0) { | |
255 | int i; | |
256 | int foundone = 0; | |
257 | ||
258 | for (i = 0; (i < ntrec) && !foundone; ++i) { | |
259 | uspclptr = (union u_spcl *)&slp->tblock[i]; | |
260 | spclptr = &uspclptr->s_spcl; | |
261 | if ((spclptr->c_magic == NFS_MAGIC) && | |
262 | (spclptr->c_type == TS_INODE) && | |
263 | (spclptr->c_date == gThisDumpDate) && | |
264 | !(spclptr->c_dinode.di_mode & S_IFDIR) && | |
265 | !(spclptr->c_flags & DR_EXTATTRIBUTES) | |
266 | ) { | |
267 | foundone = 1; | |
268 | /* if (s->cntntrecs >= s->maxntrecs) { only write every maxntrecs amount of data */ | |
269 | s->cntntrecs = 0; | |
270 | if (gtperr == 0) | |
271 | gtperr = GetTapePos(&s->curtapepos); | |
272 | /* if an error occured previously don't | |
273 | * try again */ | |
274 | if (gtperr == 0) { | |
275 | #ifdef DEBUG_QFA | |
276 | msg("inode %ld at tapepos %ld\n", spclptr->c_inumber, s->curtapepos); | |
277 | #endif | |
278 | gtperr = MkTapeString(spclptr, s->curtapepos); | |
279 | } | |
280 | /* } */ | |
281 | } | |
282 | } | |
283 | } | |
284 | #endif /* USE_QFA */ | |
285 | return 0; | |
286 | } | |
287 | ||
288 | #ifdef USE_QFA | |
289 | /* | |
290 | * read the current tape position | |
291 | */ | |
292 | static int | |
293 | GetTapePos(long long *pos) | |
294 | { | |
295 | int err = 0; | |
296 | ||
297 | #ifdef RDUMP | |
298 | if (host) { | |
299 | *pos = (long long) rmtseek((OFF_T)0, (int)LSEEK_GET_TAPEPOS); | |
300 | err = *pos < 0; | |
301 | } | |
302 | else | |
303 | #endif | |
304 | { | |
305 | if (magtapeout) { | |
306 | long mtpos; | |
307 | *pos = 0; | |
308 | err = (ioctl(tapefd, MTIOCPOS, &mtpos) < 0); | |
309 | *pos = (long long)mtpos; | |
310 | } | |
311 | else { | |
312 | *pos = LSEEK(tapefd, 0, SEEK_CUR); | |
313 | err = (*pos < 0); | |
314 | } | |
315 | } | |
316 | if (err) { | |
317 | err = errno; | |
318 | msg("[%ld] error: %d (getting tapepos: %lld)\n", getpid(), | |
319 | err, *pos); | |
320 | return err; | |
321 | } | |
322 | return err; | |
323 | } | |
324 | ||
325 | static int | |
326 | MkTapeString(struct s_spcl *spclptr, long long curtapepos) | |
327 | { | |
328 | int err = 0; | |
329 | ||
330 | #ifdef DEBUG_QFA | |
331 | msg("inode %ld at tapepos %lld\n", spclptr->c_inumber, curtapepos); | |
332 | #endif | |
333 | ||
334 | snprintf(gTps, sizeof(gTps), "%ld\t%d\t%lld\n", | |
335 | (unsigned long)spclptr->c_inumber, | |
336 | tapeno, | |
337 | curtapepos); | |
338 | gTps[sizeof(gTps) - 1] = '\0'; | |
339 | if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) { | |
340 | err = errno; | |
341 | warn("error writing tapepos file. (error %d)\n", errno); | |
342 | } | |
343 | return err; | |
344 | } | |
345 | #endif /* USE_QFA */ | |
346 | ||
347 | Indexer indexer_legacy = { | |
348 | NULL, | |
349 | &legacy_open, | |
350 | &legacy_close, | |
351 | &legacy_foo, | |
352 | &legacy_writerec, | |
353 | &legacy_addInode, | |
354 | &legacy_addDirEntry, | |
355 | &legacy_openQfa, | |
356 | &legacy_closeQfa, | |
357 | &legacy_updateQfa, | |
358 | &legacy_updateQfaState | |
359 | }; |