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 <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
32 #include <afs/afsutil.h>
34 #include <afs/bubasics.h>
35 #include <afs/volser.h>
37 #define dprintf /* debug */
39 /* basic format of a tape file is a file, whose name is "T<tapename>.db", and
40 * which contains the fields
41 * (afs_int32) dumpID, (afs_int32) tape-sequence-within-dump, (afs_int32) damage_flag
42 * all as space-separated integers.
45 /* The format of a dump file is:
46 * a file whose name is "D<dump#>.db"
47 * and whose contents are a header line:
48 * (string) dumpName, (long) parent-id, (long) incTime, (long) dumpEndTime, (long) level
49 * and a bunch of bcdb_volumeEntries with this format:
50 * (string) volume name, (long) volume ID, (string) tape name, (long) position-on-tape,
51 * (long) sequence-in-volume-dump, (long) is-this-the-last-vol-frag, (long) incTime
52 * again, all space-separated.
53 * Note that dumpEndTime is stored and returned in the dump creation time field.
56 afs_int32 DeleteDump();
57 afs_int32 ScanDumpHdr();
59 /* return the tape file name corresponding to a particular tape */
62 register char *atapeName;
64 static char tbuffer[AFSDIR_PATH_MAX];
66 /* construct the backup dir path */
67 strcpy(tbuffer, AFSDIR_SERVER_BACKUP_DIRPATH);
68 strcat(tbuffer, "/T");
69 strcat(tbuffer + 1, atapeName);
70 strcat(tbuffer, ".db");
74 /* return the dump file name corresponding to a particular dump ID */
77 register afs_int32 adumpID;
79 static char tbuffer[AFSDIR_PATH_MAX];
80 char buf[AFSDIR_PATH_MAX];
82 /* construct the backup dir path */
83 strcpy(buf, AFSDIR_SERVER_BACKUP_DIRPATH);
84 strcat(buf, "/D%d.db");
85 sprintf(tbuffer, buf, adumpID);
90 OpenDump(adumpID, awrite)
97 tp = DumpName(adumpID);
98 tfile = fopen(tp, awrite);
104 * non-static for recoverDB
108 OpenTape(atapeName, awrite)
113 register FILE *tfile;
114 tp = TapeName(atapeName);
115 tfile = fopen(tp, awrite);
119 /* scan for, and delete, all dumps whose parent dump ID is aparentID */
121 ScanForChildren(aparentID)
125 register struct dirent *tde;
126 afs_int32 dumpID, parent;
127 register FILE *tfile;
128 register afs_int32 code;
129 afs_int32 j2, j3, j4;
133 tdir = opendir(AFSDIR_SERVER_BACKUP_DIRPATH);
137 for (tde = readdir(tdir); tde; tde = readdir(tdir)) {
138 code = sscanf(tde->d_name, "D%ld.db", &dumpID);
142 tfile = OpenDump(dumpID, "r");
144 continue; /* shouldn't happen, but should continue anyway */
146 code = ScanDumpHdr(tfile, dname, dumpName, &parent, &j2, &j3, &j4);
149 printf("backup:dsstub: bad dump header for dump %d\n", dumpID);
153 /* if this guy's parent is the ID we're scanning for, delete it */
154 if (aparentID == parent) {
155 code = DeleteDump(dumpID);
157 printf("backup:dsstub: failed to delete child dump %d\n",
170 register afs_int32 code;
171 tp = DumpName(adumpID);
175 code = ScanForChildren(adumpID);
180 DeleteTape(atapeName)
184 register afs_int32 code;
185 tp = TapeName(atapeName);
191 * name is a pathname style name, determine trailing name and return
196 tailCompPtr(pathNamePtr)
200 ptr = strrchr(pathNamePtr, '/');
202 /* this should never happen */
203 printf("tailCompPtr: could not find / in name(%s)\n", pathNamePtr);
204 return (pathNamePtr);
206 ptr++; /* skip the / */
211 * scan a dump header out of a dump file, leaving the file ptr set after
214 * afile - ptr to file, for reading.
215 * various - ptrs for return values
217 * aname - string of form volume_set.dump_level
218 * dumpName - pathname of dump schedule node
219 * aparent - id of parent
221 * acreateTime - time at which dump was created
222 * alevel - level of dump (0 = full, 1+ are incrementals)
225 ScanDumpHdr(afile, aname, dumpName, aparent, aincTime, acreateTime, alevel)
226 register FILE *afile;
230 afs_int32 *acreateTime;
236 afs_int32 dbmagic, dbversion;
237 register afs_int32 code;
239 tp = fgets(tbuffer, sizeof(tbuffer), afile);
243 sscanf(tbuffer, "%d %d %s %s %ld %ld %ld %ld", &dbmagic, &dbversion,
244 aname, dumpName, aparent, aincTime, acreateTime, alevel);
248 /* now check the magic and version numbers */
249 if ((dbmagic != BC_DUMPDB_MAGIC) || (dbversion != BC_DUMPDB_VERSION))
255 /* scan a tape header out of a tape file, leaving the file ptr positioned just past the header */
257 ScanTapeHdr(afile, adumpID, aseq, adamage)
258 register FILE *afile;
265 register afs_int32 code;
267 tp = fgets(tbuffer, sizeof(tbuffer), afile);
270 code = sscanf(tbuffer, "%ld %ld %ld", adumpID, aseq, adamage);
277 * scan a tape volume record from a dump file, leaving the file ptr
278 * positioned past the just-scanned record.
286 ScanTapeVolume(afile, avolName, avolID, atapeName, apos, aseq, alastp,
292 afs_int32 *apos, *aseq, *alastp, *cloneTime;
295 register afs_int32 code;
298 tp = fgets(tbuffer, sizeof(tbuffer), afile);
299 if (!tp) { /* something went wrong, or eof hit */
301 return -1; /* error occurred */
306 sscanf(tbuffer, "%s %ld %s %ld %ld %ld %ld", avolName, avolID,
307 atapeName, apos, aseq, alastp, cloneTime);
309 return -1; /* bad input line */
314 * Search the dump for the volume with name volName, and return it's
318 * -1 - volume with volName not found
322 ScanVolClone(tdump, volName, cloneTime)
325 afs_int32 *cloneTime;
327 char avolName[256], atapeName[256];
328 afs_int32 retval, avolID, apos, aseq, alastp;
331 ScanTapeVolume(tdump, &avolName[0], &avolID, &atapeName[0], &apos,
332 &aseq, &alastp, cloneTime);
333 while (retval == 0) {
334 if (strcmp(avolName, volName) == 0)
337 ScanTapeVolume(tdump, &avolName[0], &avolID, &atapeName[0], &apos,
338 &aseq, &alastp, cloneTime);
343 /* seek a dump file (after a header scan has been done) to position apos */
345 SeekDump(afile, apos)
346 register FILE *afile;
349 register afs_int32 i;
353 /* now skip to appropriate position */
354 for (i = 0; i < apos; i++) {
355 tp = fgets(tbuffer, sizeof(tbuffer), afile);