2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <afsconfig.h>
15 #include <afs/param.h>
20 #include <afs/afsutil.h>
22 #include <afs/bubasics.h>
23 #include <afs/afsint.h>
24 #include <afs/volser.h>
30 static char * TapeName(char *);
31 static char * DumpName(afs_int32 adumpID
);
32 static FILE * OpenDump(afs_int32
, char * );
33 FILE * OpenTape(char * , char * );
34 static afs_int32
ScanForChildren(afs_int32
);
35 static afs_int32
DeleteDump(afs_int32
);
36 char * tailCompPtr(char *);
37 afs_int32
ScanDumpHdr(FILE *, char *, char *, afs_int32
*, afs_int32
*,
38 afs_int32
*, afs_int32
*);
39 afs_int32
ScanTapeVolume(FILE *, char *, afs_int32
*, char *, afs_int32
*, afs_int32
*,
40 afs_int32
*, afs_int32
*);
41 afs_int32
ScanVolClone(FILE *, char *, afs_int32
*);
44 /* basic format of a tape file is a file, whose name is "T<tapename>.db", and
45 * which contains the fields
46 * (afs_int32) dumpID, (afs_int32) tape-sequence-within-dump, (afs_int32) damage_flag
47 * all as space-separated integers.
50 /* The format of a dump file is:
51 * a file whose name is "D<dump#>.db"
52 * and whose contents are a header line:
53 * (string) dumpName, (long) parent-id, (long) incTime, (long) dumpEndTime, (long) level
54 * and a bunch of bcdb_volumeEntries with this format:
55 * (string) volume name, (long) volume ID, (string) tape name, (long) position-on-tape,
56 * (long) sequence-in-volume-dump, (long) is-this-the-last-vol-frag, (long) incTime
57 * again, all space-separated.
58 * Note that dumpEndTime is stored and returned in the dump creation time field.
61 /* return the tape file name corresponding to a particular tape */
63 static char * TapeName(char *atapeName
)
67 if (asprintf(&tbuffer
, "%s/T%s.db", AFSDIR_SERVER_BACKUP_DIRPATH
,
73 /* return the dump file name corresponding to a particular dump ID */
75 static char * DumpName(afs_int32 adumpID
)
79 if (asprintf(&tbuffer
, "%s/D%d.db", AFSDIR_SERVER_BACKUP_DIRPATH
,
85 static FILE * OpenDump(afs_int32 adumpID
, char * awrite
)
90 tp
= DumpName(adumpID
);
93 tfile
= fopen(tp
, awrite
);
100 * non-static for recoverDB
103 FILE * OpenTape(char * atapeName
, char * awrite
)
108 tp
= TapeName(atapeName
);
111 tfile
= fopen(tp
, awrite
);
116 /* scan for, and delete, all dumps whose parent dump ID is aparentID */
118 static afs_int32
ScanForChildren(afs_int32 aparentID
)
122 afs_int32 dumpID
, parent
;
125 afs_int32 j2
, j3
, j4
;
129 tdir
= opendir(AFSDIR_SERVER_BACKUP_DIRPATH
);
133 for (tde
= readdir(tdir
); tde
; tde
= readdir(tdir
)) {
134 code
= sscanf(tde
->d_name
, "D%ld.db", (long int *) &dumpID
);
138 tfile
= OpenDump(dumpID
, "r");
140 continue; /* shouldn't happen, but should continue anyway */
142 code
= ScanDumpHdr(tfile
, dname
, dumpName
, &parent
, &j2
, &j3
, &j4
);
145 printf("backup:dsstub: bad dump header for dump %d\n", dumpID
);
149 /* if this guy's parent is the ID we're scanning for, delete it */
150 if (aparentID
== parent
) {
151 code
= DeleteDump(dumpID
);
153 printf("backup:dsstub: failed to delete child dump %d\n",
161 static afs_int32
DeleteDump(afs_int32 adumpID
)
166 tp
= DumpName(adumpID
);
173 code
= ScanForChildren(adumpID
);
178 static afs_int32
DeleteTape(char * atapeName
)
183 tp
= TapeName(atapeName
);
193 * name is a pathname style name, determine trailing name and return
198 tailCompPtr(char *pathNamePtr
)
201 ptr
= strrchr(pathNamePtr
, '/');
203 /* this should never happen */
204 printf("tailCompPtr: could not find / in name(%s)\n", pathNamePtr
);
205 return (pathNamePtr
);
207 ptr
++; /* skip the / */
212 * scan a dump header out of a dump file, leaving the file ptr set after
215 * afile - ptr to file, for reading.
216 * various - ptrs for return values
218 * aname - string of form volume_set.dump_level
219 * dumpName - pathname of dump schedule node
220 * aparent - id of parent
222 * acreateTime - time at which dump was created
223 * alevel - level of dump (0 = full, 1+ are incrementals)
226 ScanDumpHdr(FILE *afile
, char *aname
, char *dumpName
, afs_int32
*aparent
, afs_int32
*aincTime
, afs_int32
*acreateTime
, afs_int32
*alevel
)
230 afs_int32 dbmagic
, dbversion
;
233 tp
= fgets(tbuffer
, sizeof(tbuffer
), afile
);
237 sscanf(tbuffer
, "%d %d %s %s %ld %ld %ld %ld", &dbmagic
, &dbversion
,
238 aname
, dumpName
, (long int *) aparent
, (long int *) aincTime
,
239 (long int *) acreateTime
, (long int *) alevel
);
243 /* now check the magic and version numbers */
244 if ((dbmagic
!= BC_DUMPDB_MAGIC
) || (dbversion
!= BC_DUMPDB_VERSION
))
251 /* scan a tape header out of a tape file, leaving the file ptr positioned just past the header */
252 static afs_int32
ScanTapeHdr(FILE *afile
, afs_int32
*adumpID
, afs_int32
*aseq
, afs_int32
*adamage
)
258 tp
= fgets(tbuffer
, sizeof(tbuffer
), afile
);
261 code
= sscanf(tbuffer
, "%ld %ld %ld", (long int *)adumpID
,
262 (long int *)aseq
, (long int *)adamage
);
270 * scan a tape volume record from a dump file, leaving the file ptr
271 * positioned past the just-scanned record.
278 afs_int32
ScanTapeVolume(FILE *afile
, char *avolName
, afs_int32
*avolID
, char *atapeName
, afs_int32
*apos
, afs_int32
*aseq
, afs_int32
*alastp
, afs_int32
*cloneTime
)
284 tp
= fgets(tbuffer
, sizeof(tbuffer
), afile
);
285 if (!tp
) { /* something went wrong, or eof hit */
287 return -1; /* error occurred */
292 sscanf(tbuffer
, "%s %ld %s %ld %ld %ld %ld", avolName
,
293 (long int *) avolID
, atapeName
, (long int *)apos
,
294 (long int *) aseq
, (long int *) alastp
,
295 (long int *) cloneTime
);
297 return -1; /* bad input line */
302 * Search the dump for the volume with name volName, and return it's
306 * -1 - volume with volName not found
309 afs_int32
ScanVolClone(FILE *tdump
, char *volName
, afs_int32
*cloneTime
)
311 char avolName
[256], atapeName
[256];
312 afs_int32 retval
, avolID
, apos
, aseq
, alastp
;
315 ScanTapeVolume(tdump
, &avolName
[0], &avolID
, &atapeName
[0], &apos
,
316 &aseq
, &alastp
, cloneTime
);
317 while (retval
== 0) {
318 if (strcmp(avolName
, volName
) == 0)
321 ScanTapeVolume(tdump
, &avolName
[0], &avolID
, &atapeName
[0], &apos
,
322 &aseq
, &alastp
, cloneTime
);
328 /* seek a dump file (after a header scan has been done) to position apos */
329 static int SeekDump(FILE *afile
, afs_int32 apos
)
335 /* now skip to appropriate position */
336 for (i
= 0; i
< apos
; i
++) {
337 tp
= fgets(tbuffer
, sizeof(tbuffer
), afile
);