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
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
21 #include <netinet/in.h>
22 #include <sys/socket.h>
32 #include <afs/tcdata.h>
33 #include <afs/bubasics.h>
34 #include <afs/budb_client.h>
35 #include <afs/vldbint.h>
37 #include <afs/vlserver.h>
38 #include <afs/volser.h>
39 #include <afs/volint.h>
40 #include <afs/cellconfig.h>
42 #include "error_macros.h"
44 dlqlinkT savedEntries;
45 dlqlinkT entries_to_flush;
47 int dbWatcherinprogress;
50 threadEntryDir(char *anEntry, afs_int32 size, afs_int32 type)
56 for (tried = 0; tried < 5; tried++) {
57 entryPtr = (dlqlinkP) malloc(sizeof(dlqlinkT));
58 entry = (char *)malloc(size);
59 if (entryPtr && entry)
62 /* sleep a minute and try again */
68 if ((tried > 0) && !dbWatcherinprogress)
70 #ifdef AFS_PTHREAD_ENV
76 entryPtr->dlq_prev = entryPtr->dlq_next = (dlqlinkP) NULL;
77 entryPtr->dlq_type = type;
78 entryPtr->dlq_structPtr = entry;
80 memcpy(entry, anEntry, size);
81 dlqLinkb(&entries_to_flush, entryPtr);
87 * Creates an entry and puts it onto the savedEntries list.
88 * Will retry up to 5 times if not enough memory. Hopfully, the
89 * Watcher thread will free up some memory for it to continue.
93 threadEntry(char *anEntry, afs_int32 size, afs_int32 type)
99 for (tried = 0; tried < 5; tried++) {
100 entryPtr = (dlqlinkP) malloc(sizeof(dlqlinkT));
101 entry = (char *)malloc(size);
102 if (entryPtr && entry)
105 /* sleep a minute and try again */
111 if ((tried > 0) && !dbWatcherinprogress)
112 return (TC_NOMEMORY);
113 #ifdef AFS_PTHREAD_ENV
120 entryPtr->dlq_prev = entryPtr->dlq_next = (dlqlinkP) NULL;
121 entryPtr->dlq_type = type;
122 entryPtr->dlq_structPtr = entry;
124 memcpy(entry, anEntry, size);
125 dlqLinkb(&savedEntries, (dlqlinkP) entryPtr);
129 /* ------------------------------------------------------------------ */
132 useDump(struct budb_dumpEntry *dumpEntryPtr)
137 threadEntry(dumpEntryPtr, sizeof(struct budb_dumpEntry), DLQ_USEDUMP);
143 * Creates a dump entry (finished) and puts it onto the savedEntries list.
146 finishDump(struct budb_dumpEntry *aDumpEntryPtr)
151 threadEntry(aDumpEntryPtr, sizeof(struct budb_dumpEntry),
158 * Creates a tape entry and puts it onto the savedEntries list.
161 useTape(struct budb_tapeEntry *aTapeEntryPtr, afs_int32 dumpID, char *tapename, afs_int32 tapeSeq, afs_int32 useCount, Date written, Date expiration, afs_int32 tapepos)
165 memset(aTapeEntryPtr, 0, sizeof(struct budb_tapeEntry));
166 strcpy(aTapeEntryPtr->name, tapename);
167 aTapeEntryPtr->flags = BUDB_TAPE_BEINGWRITTEN;
168 aTapeEntryPtr->written = written; /* When label was written */
169 aTapeEntryPtr->expires = expiration;
170 aTapeEntryPtr->seq = tapeSeq;
171 aTapeEntryPtr->useCount = useCount;
172 aTapeEntryPtr->dump = dumpID;
173 aTapeEntryPtr->labelpos = tapepos;
176 threadEntry(aTapeEntryPtr, sizeof(struct budb_tapeEntry),
183 * Creates a tape entry (finished) and puts it onto the savedEntries list.
186 finishTape(struct budb_tapeEntry *aTapeEntryPtr, afs_int32 useKBytes)
190 aTapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
191 aTapeEntryPtr->useKBytes = useKBytes;
194 threadEntry(aTapeEntryPtr, sizeof(struct budb_tapeEntry),
201 * Creates a volume entry and puts it onto the savedEntries list.
204 addVolume(struct budb_volumeEntry *aVolEntryPtr, afs_int32 dumpID, char *tapename, char *volname, afs_int32 volid, Date cloneDate, afs_int32 startPos, afs_int32 volBytes, int fragment, afs_int32 flags)
210 aVolEntryPtr = (struct budb_volumeEntry *)
211 malloc(sizeof(struct budb_volumeEntry));
213 ERROR_EXIT(TC_NOMEMORY);
217 memset(aVolEntryPtr, 0, sizeof(struct budb_volumeEntry));
218 strcpy(aVolEntryPtr->name, volname);
219 aVolEntryPtr->flags = flags;
220 aVolEntryPtr->id = volid;
221 aVolEntryPtr->position = startPos;
222 aVolEntryPtr->clone = cloneDate;
223 aVolEntryPtr->nBytes = volBytes;
224 aVolEntryPtr->seq = fragment;
225 aVolEntryPtr->dump = dumpID;
226 strcpy(aVolEntryPtr->tape, tapename);
229 threadEntry(aVolEntryPtr, sizeof(struct budb_volumeEntry),
240 * Runs through the list of savedEntries and adds the volumes and
241 * tapes to the database.
242 * A status of DUMP_NORETRYEOT means the tape(s) contains no useful data,
243 * and tapes and volumes should not be added to the DB.
246 flushSavedEntries(afs_int32 status)
249 struct budb_tapeEntry *tapePtr;
250 struct budb_volumeEntry *volPtr;
254 * On DUMP_NORETRYEOT, the volume being dumped was the first on the tape and hit the
255 * EOT. This means the volume is larger than the tape. Instead of going onto the next
256 * tape, backup reuses the tape. Thus, we must remove this tape entry and free it
257 * without adding it to the backup database.
259 if (status == DUMP_NORETRYEOT) {
260 entryPtr = dlqUnlinkb(&savedEntries);
261 if (!entryPtr || (entryPtr->dlq_type != DLQ_USETAPE))
262 ERROR_EXIT(TC_INTERNALERROR);
264 tapePtr = (struct budb_tapeEntry *)entryPtr->dlq_structPtr;
272 * Add dump, tape, and volume entries to the list for the dbWatcher to
273 * flush. Volume entries are not added if the volume failed to dump.
275 while (entryPtr = dlqUnlinkf(&savedEntries)) {
276 if ((entryPtr->dlq_type == DLQ_VOLENTRY) && (status != DUMP_SUCCESS)) {
277 volPtr = (struct budb_volumeEntry *)entryPtr->dlq_structPtr;
283 dlqLinkb(&entries_to_flush, entryPtr);
288 /* Free anything that remains on dlq */
289 dlqTraverseQueue(&savedEntries, free, free);
298 while (dbWatcherinprogress || !dlqEmpty(&entries_to_flush)) {
300 printf("Updating database\n");
303 #ifdef AFS_PTHREAD_ENV
311 printf("Updating database - done\n");
316 #define MAXVOLUMESTOADD 100
323 struct budb_dumpEntry *dumpPtr;
324 struct budb_tapeEntry *tapePtr;
325 struct budb_volumeEntry *volPtr, volumes[MAXVOLUMESTOADD];
330 dlqInit(&entries_to_flush);
331 dlqInit(&savedEntries);
333 dbWatcherinprogress = 0;
337 /* Add tape and volume enties to the backup database */
338 while (entryPtr = dlqUnlinkf(&entries_to_flush)) {
339 dbWatcherinprogress = 1;
341 if (!entryPtr->dlq_structPtr) {
342 ErrorLog(0, 0, TC_BADQUEUE, 0,
343 "Warning: Invalid database entry - nota added\n");
345 switch (entryPtr->dlq_type) {
348 (struct budb_dumpEntry *)entryPtr->dlq_structPtr;
349 /* Now call the database to create the entry */
350 code = bcdb_CreateDump(dumpPtr);
352 if (code == BUDB_DUMPIDEXISTS) {
354 ("Dump %s (DumpID %u) already exists in backup database\n",
355 dumpPtr->name, dumpPtr->id);
357 ErrorLog(0, 0, code, 0,
358 "Warning: Can't create dump %s (DumpID %u) in backup database\n",
359 dumpPtr->name, dumpPtr->id);
362 addedDump = (code ? 0 : 1);
367 (struct budb_dumpEntry *)entryPtr->dlq_structPtr;
369 code = bcdb_FinishDump(dumpPtr);
371 ErrorLog(0, 0, code, 0,
372 "Warning: Can't finish dump %s (DumpID %u) in backup database\n",
373 dumpPtr->name, dumpPtr->id);
381 (struct budb_tapeEntry *)entryPtr->dlq_structPtr;
383 code = bcdb_UseTape(tapePtr, &new);
385 ErrorLog(0, 0, code, 0,
386 "Warning: Can't add tape %s of DumpID %u to backup database\n",
387 tapePtr->name, tapePtr->dump);
394 (struct budb_tapeEntry *)entryPtr->dlq_structPtr;
396 code = bcdb_FinishTape(tapePtr, &new);
398 ErrorLog(0, 0, code, 0,
399 "Warning: Can't finish tape %s of DumpID %u in backup database\n",
400 tapePtr->name, tapePtr->dump);
406 /* collect array of volumes to add to the dump */
407 for (c = 0; c < MAXVOLUMESTOADD; c++) {
408 if (c > 0) { /* don't read the 1st - already did */
409 entryPtr = dlqUnlinkf(&entries_to_flush); /* Get the next entry */
414 if (entryPtr->dlq_type != DLQ_VOLENTRY) {
415 /* Place back onto list and add the vol entries we have */
416 dlqLinkf(&entries_to_flush, entryPtr);
417 entryPtr = (dlqlinkP) 0; /* don't want to deallocate below */
422 (struct budb_volumeEntry *)entryPtr->
425 ErrorLog(0, 0, TC_BADQUEUE, 0,
426 "Warning: Invalid database entry - not added\n");
430 memcpy(&volumes[c], volPtr,
431 sizeof(struct budb_volumeEntry));
434 entryPtr = (dlqlinkP) 0;
439 code = bcdb_AddVolumes(&volumes[0], c);
444 ErrorLog(0, 0, code, 0,
445 "Warning: Can't add %d volumes to dumpid %u\n",
451 for (i = 0; i < c; i++) {
452 code = bcdb_AddVolume(&volumes[i]);
454 ErrorLog(0, 0, code, 0,
455 "Warning: Can't add volume %s %u to backup database\n",
456 volumes[i].name, volumes[i].id);
465 "Warning: dbWatcher: Unrecognized entry type %d\n",
471 if (entryPtr->dlq_structPtr)
472 free(entryPtr->dlq_structPtr);
475 entryPtr = (dlqlinkP) 0;
476 dumpPtr = (budb_dumpEntry *) 0;
477 volPtr = (budb_volumeEntry *) 0;
478 tapePtr = (budb_tapeEntry *) 0;
481 dbWatcherinprogress = 0;
482 #ifdef AFS_PTHREAD_ENV