* Note that dumpEndTime is stored and returned in the dump creation time field.
*/
-afs_int32 DeleteDump();
+static afs_int32 DeleteDump();
afs_int32 ScanDumpHdr();
/* return the tape file name corresponding to a particular tape */
/* create an empty volume set, new items are added via bc_AddVolumeItem */
-bc_CreateVolumeSet(aconfig, avolName, aflags)
- struct bc_config *aconfig;
- char *avolName;
- afs_int32 aflags;
+int
+bc_CreateVolumeSet(struct bc_config *aconfig, char *avolName,
+ afs_int32 aflags)
{
register struct bc_volumeSet **tlast, *tset, *nset;
return 0;
}
-
-
-void
-FreeVolumeSet(avset)
- struct bc_volumeSet *avset;
+static int
+FreeVolumeEntry(register struct bc_volumeEntry *aentry)
{
- FreeVolumeEntryList(avset->ventries);
- free(avset->name);
- free(avset);
+ free(aentry->name);
+ free(aentry->serverName);
+ free(aentry->partname);
+ free(aentry);
+ return 0;
}
-static
-FreeVolumeEntryList(aentry)
- register struct bc_volumeEntry *aentry;
+static int
+FreeVolumeEntryList(register struct bc_volumeEntry *aentry)
{
register struct bc_volumeEntry *tnext;
return 0;
}
-static
-FreeVolumeEntry(aentry)
- register struct bc_volumeEntry *aentry;
+
+
+void
+FreeVolumeSet(struct bc_volumeSet *avset)
{
- free(aentry->name);
- free(aentry->serverName);
- free(aentry->partname);
- free(aentry);
- return 0;
+ FreeVolumeEntryList(avset->ventries);
+ free(avset->name);
+ free(avset);
}
-bc_DeleteVolumeSet(aconfig, avolName, flags)
- struct bc_config *aconfig;
- char *avolName;
- afs_int32 *flags;
+int
+bc_DeleteVolumeSet(struct bc_config *aconfig, char *avolName,
+ afs_int32 *flags)
{
register struct bc_volumeSet **tlast, *tset;
return -1;
}
-bc_DeleteVolumeItem(aconfig, avolName, anumber)
- struct bc_config *aconfig;
- char *avolName;
- afs_int32 anumber;
+int
+bc_DeleteVolumeItem(struct bc_config *aconfig, char *avolName,
+ afs_int32 anumber)
{
register afs_int32 i;
register struct bc_volumeSet *tset;
return code;
}
+/* ListDumpSchedule
+ * Print out the dump schedule tree whose root is adump. Alevel should
+ * be passed in as 0, and is incremented for the recursive calls
+ * entry:
+ * adump - ptr to the root node of a dump schedule
+ * alevel - 0
+ */
+
+static int
+ListDumpSchedule(register struct bc_dumpSchedule *adump, int alevel)
+{
+ register int i;
+ register struct bc_dumpSchedule *child;
+ char *tailCompPtr();
+
+ /* sanity check for loops */
+ if (alevel > 100) {
+ printf("backup: recursing listing dump schedule\n");
+ return -1;
+ }
+
+ /* move to appropriate indentation level */
+ for (i = 0; i < alevel; i++)
+ printf(" ");
+
+ /* name is a pathname style name, determine trailing name and only print
+ * it
+ */
+
+ printf("/%s ", tailCompPtr(adump->name));
+
+
+ /* list expiration time */
+ switch (adump->expType) {
+ case BC_ABS_EXPDATE:
+ /* absolute expiration date. Never expires if date is 0 */
+ if (adump->expDate) {
+ time_t t = adump->expDate;
+ printf("expires at %.24s", cTIME(&t));
+ }
+ break;
+
+ case BC_REL_EXPDATE:
+ {
+ struct ktime_date kt;
+
+ /* expiration date relative to the time that the dump is done */
+ LongTo_ktimeRelDate(adump->expDate, &kt);
+ printf(" expires in %s", RelDatetoString(&kt));
+ }
+ break;
+
+ default:
+ break;
+ }
+ printf("\n");
+ for (child = adump->firstChild; child; child = child->nextSibling)
+ ListDumpSchedule(child, alevel + 1);
+
+ return 0;
+}
/* bc_ListDumpScheduleCmd
* list the (internally held) dump schedule tree
*/
afs_int32
-bc_ListDumpScheduleCmd(as, arock)
- struct cmd_syndesc *as;
- char *arock;
+bc_ListDumpScheduleCmd(struct cmd_syndesc *as, char *arock)
{
/* no parms */
afs_int32 code;
return (code);
}
-/* ListDumpSchedule
- * Print out the dump schedule tree whose root is adump. Alevel should
- * be passed in as 0, and is incremented for the recursive calls
- * entry:
- * adump - ptr to the root node of a dump schedule
- * alevel - 0
- */
-
-static
-ListDumpSchedule(adump, alevel)
- int alevel;
- register struct bc_dumpSchedule *adump;
-{
- register int i;
- register struct bc_dumpSchedule *child;
-
- char *tailCompPtr();
-
- /* sanity check for loops */
- if (alevel > 100) {
- printf("backup: recursing listing dump schedule\n");
- return -1;
- }
-
- /* move to appropriate indentation level */
- for (i = 0; i < alevel; i++)
- printf(" ");
-
- /* name is a pathname style name, determine trailing name and only print
- * it
- */
-
- printf("/%s ", tailCompPtr(adump->name));
-
-
- /* list expiration time */
- switch (adump->expType) {
- case BC_ABS_EXPDATE:
- /* absolute expiration date. Never expires if date is 0 */
- if (adump->expDate) {
- time_t t = adump->expDate;
- printf("expires at %.24s", cTIME(&t));
- }
- break;
-
- case BC_REL_EXPDATE:
- {
- struct ktime_date kt;
-
- /* expiration date relative to the time that the dump is done */
- LongTo_ktimeRelDate(adump->expDate, &kt);
- printf(" expires in %s", RelDatetoString(&kt));
- }
- break;
-
- default:
- break;
- }
- printf("\n");
- for (child = adump->firstChild; child; child = child->nextSibling)
- ListDumpSchedule(child, alevel + 1);
-
- return 0;
-}
}
}
-/*
- * match the argument string against the compiled re
- */
-int
-re_exec(p1)
- register char *p1;
+static int
+cclass(set, c, af)
+ register char *set, c;
+ int af;
{
- register char *p2 = expbuf;
- register int c;
- int rv;
+ register int n;
- for (c = 0; c < NBRA; c++) {
- braslist[c] = 0;
- braelist[c] = 0;
- }
- if (circf)
- return ((advance(p1, p2)));
- /*
- * fast check for first character
- */
- if (*p2 == CCHR) {
- c = p2[1];
- do {
- if (*p1 != c)
- continue;
- if (rv = advance(p1, p2))
- return (rv);
- } while (*p1++);
+ if (c == 0)
return (0);
- }
- /*
- * regular algorithm
- */
- do
- if (rv = advance(p1, p2))
- return (rv);
- while (*p1++);
+ n = *set++;
+ while (--n)
+ if (*set++ == c)
+ return (af);
+ return (!af);
+}
+
+static
+backref(i, lp)
+ register int i;
+ register char *lp;
+{
+ register char *bp;
+
+ bp = braslist[i];
+ while (*bp++ == *lp++)
+ if (bp >= braelist[i])
+ return (1);
return (0);
}
}
}
-static
-backref(i, lp)
- register int i;
- register char *lp;
+/*
+ * match the argument string against the compiled re
+ */
+int
+re_exec(p1)
+ register char *p1;
{
- register char *bp;
+ register char *p2 = expbuf;
+ register int c;
+ int rv;
- bp = braslist[i];
- while (*bp++ == *lp++)
- if (bp >= braelist[i])
- return (1);
+ for (c = 0; c < NBRA; c++) {
+ braslist[c] = 0;
+ braelist[c] = 0;
+ }
+ if (circf)
+ return ((advance(p1, p2)));
+ /*
+ * fast check for first character
+ */
+ if (*p2 == CCHR) {
+ c = p2[1];
+ do {
+ if (*p1 != c)
+ continue;
+ if (rv = advance(p1, p2))
+ return (rv);
+ } while (*p1++);
+ return (0);
+ }
+ /*
+ * regular algorithm
+ */
+ do
+ if (rv = advance(p1, p2))
+ return (rv);
+ while (*p1++);
return (0);
}
-static int
-cclass(set, c, af)
- register char *set, c;
- int af;
-{
- register int n;
-
- if (c == 0)
- return (0);
- n = *set++;
- while (--n)
- if (*set++ == c)
- return (af);
- return (!af);
-}
}
+static int
+ListVolSet(struct bc_volumeSet *aset)
+{
+ struct bc_volumeEntry *tentry;
+ int i;
+
+ printf("Volume set %s", aset->name);
+ if (aset->flags & VSFLAG_TEMPORARY)
+ printf(" (temporary)");
+ printf(":\n");
+ i = 1;
+ for (tentry = aset->ventries; tentry; tentry = tentry->next, i++) {
+ printf(" Entry %3d: server %s, partition %s, volumes: %s\n", i,
+ tentry->serverName, tentry->partname, tentry->name);
+ }
+ return 0;
+}
+
/* bc_ListVolSetCmd
* list out all the information (?) about a volumeset or about all
* volumesets
*/
afs_int32
-bc_ListVolSetCmd(as, arock)
- struct cmd_syndesc *as;
- char *arock;
+bc_ListVolSetCmd(struct cmd_syndesc *as, char *arock)
{
/* parm 0 is optional volume set to display */
register struct bc_volumeSet *tset;
return (0);
}
-static
-ListVolSet(aset)
- struct bc_volumeSet *aset;
-{
- struct bc_volumeEntry *tentry;
- int i;
-
- printf("Volume set %s", aset->name);
- if (aset->flags & VSFLAG_TEMPORARY)
- printf(" (temporary)");
- printf(":\n");
- i = 1;
- for (tentry = aset->ventries; tentry; tentry = tentry->next, i++) {
- printf(" Entry %3d: server %s, partition %s, volumes: %s\n", i,
- tentry->serverName, tentry->partname, tentry->name);
- }
- return 0;
-}
-
-
/* bc_ParseVolumeSet
* Open up the volume set configuration file as specified in our argument,
* then parse the file to set up our internal representation.
}
}
-/* Will read a dump, then see if there is a dump following it and
- * try to read that dump too.
- * The first tape label is the first dumpLabel.
- */
-readDumps(taskId, tapeInfoPtr, scanInfoPtr)
- afs_uint32 taskId;
- struct butm_tapeInfo *tapeInfoPtr;
- struct tapeScanInfo *scanInfoPtr;
-{
- afs_int32 code, c;
-
- memcpy(&scanInfoPtr->dumpLabel, &scanInfoPtr->tapeLabel,
- sizeof(struct butm_tapeLabel));
-
- while (1) {
- code = readDump(taskId, tapeInfoPtr, scanInfoPtr);
- if (code)
- ERROR_EXIT(code);
-
- if (scanInfoPtr->tapeLabel.structVersion < TAPE_VERSION_4)
- break;
-
- /* Remember the initial dump and see if appended dump exists */
-
- if (!scanInfoPtr->initialDumpId)
- scanInfoPtr->initialDumpId = scanInfoPtr->dumpEntry.id;
-
- c = butm_ReadLabel(tapeInfoPtr, &scanInfoPtr->dumpLabel, 0); /* no rewind */
- tapepos = tapeInfoPtr->position - 1;
- if (c)
- break;
- }
-
- error_exit:
- return (code);
-}
-
-afs_int32
-getScanTape(taskId, tapeInfoPtr, tname, tapeId, prompt, tapeLabelPtr)
- afs_int32 taskId;
- struct butm_tapeInfo *tapeInfoPtr;
- char *tname;
- afs_int32 tapeId;
- int prompt;
- struct butm_tapeLabel *tapeLabelPtr;
-{
- afs_int32 code = 0;
- int tapecount = 1;
- afs_int32 curseq;
- char tapename[BU_MAXTAPELEN + 32];
- char gotname[BU_MAXTAPELEN + 32];
-
- while (1) {
- /* prompt for a tape */
- if (prompt) {
- code =
- PromptForTape(SCANOPCODE, tname, tapeId, taskId, tapecount);
- if (code)
- ERROR_EXIT(code);
- }
- prompt = 1;
- tapecount++;
-
- code = butm_Mount(tapeInfoPtr, ""); /* open the tape device */
- if (code) {
- TapeLog(0, taskId, code, tapeInfoPtr->error, "Can't open tape\n");
- goto newtape;
- }
-
- /* read the label on the tape */
- code = butm_ReadLabel(tapeInfoPtr, tapeLabelPtr, 1); /* rewind tape */
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't read tape label\n");
- goto newtape;
- }
- tapepos = tapeInfoPtr->position - 1;
-
- /* Now check that the tape is good */
- TAPENAME(tapename, tname, tapeId);
- TAPENAME(gotname, tapeLabelPtr->AFSName, tapeLabelPtr->dumpid);
-
- curseq = extractTapeSeq(tapeLabelPtr->AFSName);
-
- /* Label can't be null or a bad name */
- if (!strcmp(tapeLabelPtr->AFSName, "") || (curseq <= 0)) {
- TLog(taskId, "Expected tape with dump, label seen %s\n", gotname);
- goto newtape;
- }
-
- /* Label can't be a database tape */
- if (databaseTape(tapeLabelPtr->AFSName)) {
- TLog(taskId,
- "Expected tape with dump. Can't scan database tape %s\n",
- gotname);
- goto newtape;
- }
-
- /* If no name, accept any tape */
- if (strcmp(tname, "") == 0) {
- break; /* Start scan on any tape */
-#ifdef notdef
- if (curseq == 1)
- break; /* The first tape */
- else {
- TLog(taskId, "Expected first tape of dump, label seen %s\n",
- gotname);
- goto newtape;
- }
-#endif
- }
-
- if (strcmp(tname, tapeLabelPtr->AFSName)
- || ((tapeLabelPtr->structVersion >= TAPE_VERSION_3)
- && (tapeLabelPtr->dumpid != tapeId))) {
- TLog(taskId, "Tape label expected %s, label seen %s\n", tapename,
- gotname);
- goto newtape;
- }
-
- /* We have the correct tape */
- break;
-
- newtape:
- unmountTape(taskId, tapeInfoPtr);
- }
-
- error_exit:
- return (code);
-}
-
-/* ScanDumps
- * This set of code fragments read a tape, and add the information to
- * the database. Builds a literal structure.
- *
- */
-
-ScanDumps(ptr)
- struct scanTapeIf *ptr;
-{
- struct butm_tapeInfo curTapeInfo;
- struct tapeScanInfo tapeScanInfo;
- afs_uint32 taskId;
- afs_int32 code = 0;
-
- taskId = ptr->taskId;
- setStatus(taskId, DRIVE_WAIT);
- EnterDeviceQueue(deviceLatch);
- clearStatus(taskId, DRIVE_WAIT);
-
- printf("\n\n");
- if (ptr->addDbFlag)
- TLog(taskId, "ScanTape and add to the database\n");
- else
- TLog(taskId, "Scantape\n");
-
- memset(&tapeScanInfo, 0, sizeof(tapeScanInfo));
- tapeScanInfo.addDbFlag = ptr->addDbFlag;
-
- memset(&curTapeInfo, 0, sizeof(curTapeInfo));
- curTapeInfo.structVersion = BUTM_MAJORVERSION;
- code = butm_file_Instantiate(&curTapeInfo, &globalTapeConfig);
- if (code) {
- ErrorLog(0, taskId, code, curTapeInfo.error,
- "Can't initialize tape module\n");
- ERROR_EXIT(code);
- }
-
- code =
- getScanTape(taskId, &curTapeInfo, "", 0, autoQuery,
- &tapeScanInfo.tapeLabel);
- if (code)
- ERROR_EXIT(code);
-
- code = readDumps(taskId, &curTapeInfo, &tapeScanInfo);
- if (code)
- ERROR_EXIT(code);
-
- error_exit:
- unmountTape(taskId, &curTapeInfo);
- waitDbWatcher();
-
- if (code == TC_ABORTEDBYREQUEST) {
- ErrorLog(0, taskId, 0, 0, "Scantape: Aborted by request\n");
- clearStatus(taskId, ABORT_REQUEST);
- setStatus(taskId, ABORT_DONE);
- } else if (code) {
- ErrorLog(0, taskId, code, 0, "Scantape: Finished with errors\n");
- setStatus(taskId, TASK_ERROR);
- } else {
- TLog(taskId, "Scantape: Finished\n");
- }
-
- free(ptr);
- setStatus(taskId, TASK_DONE);
- LeaveDeviceQueue(deviceLatch);
- return (code);
-}
-
/* scanVolData
* Skips the volume data on the tape. The end of the volume data is
* detected by the presence of the volume trailer or by an EOF indication
return (code);
}
+/* Will read a dump, then see if there is a dump following it and
+ * try to read that dump too.
+ * The first tape label is the first dumpLabel.
+ */
+readDumps(taskId, tapeInfoPtr, scanInfoPtr)
+ afs_uint32 taskId;
+ struct butm_tapeInfo *tapeInfoPtr;
+ struct tapeScanInfo *scanInfoPtr;
+{
+ afs_int32 code, c;
+
+ memcpy(&scanInfoPtr->dumpLabel, &scanInfoPtr->tapeLabel,
+ sizeof(struct butm_tapeLabel));
+
+ while (1) {
+ code = readDump(taskId, tapeInfoPtr, scanInfoPtr);
+ if (code)
+ ERROR_EXIT(code);
+
+ if (scanInfoPtr->tapeLabel.structVersion < TAPE_VERSION_4)
+ break;
+
+ /* Remember the initial dump and see if appended dump exists */
+
+ if (!scanInfoPtr->initialDumpId)
+ scanInfoPtr->initialDumpId = scanInfoPtr->dumpEntry.id;
+
+ c = butm_ReadLabel(tapeInfoPtr, &scanInfoPtr->dumpLabel, 0); /* no rewind */
+ tapepos = tapeInfoPtr->position - 1;
+ if (c)
+ break;
+ }
+
+ error_exit:
+ return (code);
+}
+
+afs_int32
+getScanTape(taskId, tapeInfoPtr, tname, tapeId, prompt, tapeLabelPtr)
+ afs_int32 taskId;
+ struct butm_tapeInfo *tapeInfoPtr;
+ char *tname;
+ afs_int32 tapeId;
+ int prompt;
+ struct butm_tapeLabel *tapeLabelPtr;
+{
+ afs_int32 code = 0;
+ int tapecount = 1;
+ afs_int32 curseq;
+ char tapename[BU_MAXTAPELEN + 32];
+ char gotname[BU_MAXTAPELEN + 32];
+
+ while (1) {
+ /* prompt for a tape */
+ if (prompt) {
+ code =
+ PromptForTape(SCANOPCODE, tname, tapeId, taskId, tapecount);
+ if (code)
+ ERROR_EXIT(code);
+ }
+ prompt = 1;
+ tapecount++;
+
+ code = butm_Mount(tapeInfoPtr, ""); /* open the tape device */
+ if (code) {
+ TapeLog(0, taskId, code, tapeInfoPtr->error, "Can't open tape\n");
+ goto newtape;
+ }
+
+ /* read the label on the tape */
+ code = butm_ReadLabel(tapeInfoPtr, tapeLabelPtr, 1); /* rewind tape */
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't read tape label\n");
+ goto newtape;
+ }
+ tapepos = tapeInfoPtr->position - 1;
+
+ /* Now check that the tape is good */
+ TAPENAME(tapename, tname, tapeId);
+ TAPENAME(gotname, tapeLabelPtr->AFSName, tapeLabelPtr->dumpid);
+
+ curseq = extractTapeSeq(tapeLabelPtr->AFSName);
+
+ /* Label can't be null or a bad name */
+ if (!strcmp(tapeLabelPtr->AFSName, "") || (curseq <= 0)) {
+ TLog(taskId, "Expected tape with dump, label seen %s\n", gotname);
+ goto newtape;
+ }
+
+ /* Label can't be a database tape */
+ if (databaseTape(tapeLabelPtr->AFSName)) {
+ TLog(taskId,
+ "Expected tape with dump. Can't scan database tape %s\n",
+ gotname);
+ goto newtape;
+ }
+
+ /* If no name, accept any tape */
+ if (strcmp(tname, "") == 0) {
+ break; /* Start scan on any tape */
+#ifdef notdef
+ if (curseq == 1)
+ break; /* The first tape */
+ else {
+ TLog(taskId, "Expected first tape of dump, label seen %s\n",
+ gotname);
+ goto newtape;
+ }
+#endif
+ }
+
+ if (strcmp(tname, tapeLabelPtr->AFSName)
+ || ((tapeLabelPtr->structVersion >= TAPE_VERSION_3)
+ && (tapeLabelPtr->dumpid != tapeId))) {
+ TLog(taskId, "Tape label expected %s, label seen %s\n", tapename,
+ gotname);
+ goto newtape;
+ }
+
+ /* We have the correct tape */
+ break;
+
+ newtape:
+ unmountTape(taskId, tapeInfoPtr);
+ }
+
+ error_exit:
+ return (code);
+}
+
+/* ScanDumps
+ * This set of code fragments read a tape, and add the information to
+ * the database. Builds a literal structure.
+ *
+ */
+
+ScanDumps(ptr)
+ struct scanTapeIf *ptr;
+{
+ struct butm_tapeInfo curTapeInfo;
+ struct tapeScanInfo tapeScanInfo;
+ afs_uint32 taskId;
+ afs_int32 code = 0;
+
+ taskId = ptr->taskId;
+ setStatus(taskId, DRIVE_WAIT);
+ EnterDeviceQueue(deviceLatch);
+ clearStatus(taskId, DRIVE_WAIT);
+
+ printf("\n\n");
+ if (ptr->addDbFlag)
+ TLog(taskId, "ScanTape and add to the database\n");
+ else
+ TLog(taskId, "Scantape\n");
+
+ memset(&tapeScanInfo, 0, sizeof(tapeScanInfo));
+ tapeScanInfo.addDbFlag = ptr->addDbFlag;
+
+ memset(&curTapeInfo, 0, sizeof(curTapeInfo));
+ curTapeInfo.structVersion = BUTM_MAJORVERSION;
+ code = butm_file_Instantiate(&curTapeInfo, &globalTapeConfig);
+ if (code) {
+ ErrorLog(0, taskId, code, curTapeInfo.error,
+ "Can't initialize tape module\n");
+ ERROR_EXIT(code);
+ }
+
+ code =
+ getScanTape(taskId, &curTapeInfo, "", 0, autoQuery,
+ &tapeScanInfo.tapeLabel);
+ if (code)
+ ERROR_EXIT(code);
+
+ code = readDumps(taskId, &curTapeInfo, &tapeScanInfo);
+ if (code)
+ ERROR_EXIT(code);
+
+ error_exit:
+ unmountTape(taskId, &curTapeInfo);
+ waitDbWatcher();
+
+ if (code == TC_ABORTEDBYREQUEST) {
+ ErrorLog(0, taskId, 0, 0, "Scantape: Aborted by request\n");
+ clearStatus(taskId, ABORT_REQUEST);
+ setStatus(taskId, ABORT_DONE);
+ } else if (code) {
+ ErrorLog(0, taskId, code, 0, "Scantape: Finished with errors\n");
+ setStatus(taskId, TASK_ERROR);
+ } else {
+ TLog(taskId, "Scantape: Finished\n");
+ }
+
+ free(ptr);
+ setStatus(taskId, TASK_DONE);
+ LeaveDeviceQueue(deviceLatch);
+ return (code);
+}
+
+
/* validatePath
* exit:
* 0 - not ok
return 1;
}
+/* -----------------------------
+ * misc. routines
+ * -----------------------------
+ */
+
+static int
+CopyDumpDesc(toDump, fromDump)
+ struct tc_dumpDesc *toDump;
+ tc_dumpArray *fromDump;
+{
+ struct tc_dumpDesc *toPtr, *fromPtr;
+ int i;
+
+ toPtr = toDump;
+ fromPtr = fromDump->tc_dumpArray_val;
+ for (i = 0; i < fromDump->tc_dumpArray_len; i++) {
+ toPtr->vid = fromPtr->vid;
+ toPtr->vtype = fromPtr->vtype;
+ toPtr->partition = fromPtr->partition;
+ toPtr->date = fromPtr->date;
+ toPtr->cloneDate = fromPtr->cloneDate;
+ toPtr->hostAddr = fromPtr->hostAddr;
+ strcpy(toPtr->name, fromPtr->name);
+ fromPtr++;
+ toPtr++;
+ }
+ return 0;
+}
+
+
+static int
+CopyRestoreDesc(toRestore, fromRestore)
+ struct tc_restoreDesc *toRestore;
+ tc_restoreArray *fromRestore;
+{
+ struct tc_restoreDesc *toPtr, *fromPtr;
+ int i;
+
+ toPtr = toRestore;
+ fromPtr = fromRestore->tc_restoreArray_val;
+ for (i = 0; i < fromRestore->tc_restoreArray_len; i++) {
+ toPtr->flags = fromPtr->flags;
+ toPtr->position = fromPtr->position;
+ strcpy(toPtr->tapeName, fromPtr->tapeName);
+ toPtr->dbDumpId = fromPtr->dbDumpId;
+ toPtr->initialDumpId = fromPtr->initialDumpId;
+ toPtr->origVid = fromPtr->origVid;
+ toPtr->vid = fromPtr->vid;
+ toPtr->partition = fromPtr->partition;
+ toPtr->dumpLevel = fromPtr->dumpLevel;
+ toPtr->hostAddr = fromPtr->hostAddr;
+ strcpy(toPtr->newName, fromPtr->newName);
+ strcpy(toPtr->oldName, fromPtr->oldName);
+ fromPtr++;
+ toPtr++;
+
+ }
+ return 0;
+}
+
+static int
+CopyTapeSetDesc(toPtr, fromPtr)
+ struct tc_tapeSet *toPtr, *fromPtr;
+{
+
+ toPtr->id = fromPtr->id;
+ toPtr->maxTapes = fromPtr->maxTapes;
+ toPtr->a = fromPtr->a;
+ toPtr->b = fromPtr->b;
+ strcpy(toPtr->tapeServer, fromPtr->tapeServer);
+ strcpy(toPtr->format, fromPtr->format);
+
+ toPtr->expDate = fromPtr->expDate;
+ toPtr->expType = fromPtr->expType;
+ return 0;
+}
+
/* -------------------------
* butc - interface routines - alphabetic order
* -------------------------
return (code);
}
-/* -----------------------------
- * misc. routines
- * -----------------------------
- */
-
-static
-CopyDumpDesc(toDump, fromDump)
- struct tc_dumpDesc *toDump;
- tc_dumpArray *fromDump;
-{
- struct tc_dumpDesc *toPtr, *fromPtr;
- int i;
-
- toPtr = toDump;
- fromPtr = fromDump->tc_dumpArray_val;
- for (i = 0; i < fromDump->tc_dumpArray_len; i++) {
- toPtr->vid = fromPtr->vid;
- toPtr->vtype = fromPtr->vtype;
- toPtr->partition = fromPtr->partition;
- toPtr->date = fromPtr->date;
- toPtr->cloneDate = fromPtr->cloneDate;
- toPtr->hostAddr = fromPtr->hostAddr;
- strcpy(toPtr->name, fromPtr->name);
- fromPtr++;
- toPtr++;
- }
- return 0;
-}
-
-
-static
-CopyRestoreDesc(toRestore, fromRestore)
- struct tc_restoreDesc *toRestore;
- tc_restoreArray *fromRestore;
-{
- struct tc_restoreDesc *toPtr, *fromPtr;
- int i;
-
- toPtr = toRestore;
- fromPtr = fromRestore->tc_restoreArray_val;
- for (i = 0; i < fromRestore->tc_restoreArray_len; i++) {
- toPtr->flags = fromPtr->flags;
- toPtr->position = fromPtr->position;
- strcpy(toPtr->tapeName, fromPtr->tapeName);
- toPtr->dbDumpId = fromPtr->dbDumpId;
- toPtr->initialDumpId = fromPtr->initialDumpId;
- toPtr->origVid = fromPtr->origVid;
- toPtr->vid = fromPtr->vid;
- toPtr->partition = fromPtr->partition;
- toPtr->dumpLevel = fromPtr->dumpLevel;
- toPtr->hostAddr = fromPtr->hostAddr;
- strcpy(toPtr->newName, fromPtr->newName);
- strcpy(toPtr->oldName, fromPtr->oldName);
- fromPtr++;
- toPtr++;
-
- }
- return 0;
-}
-
-static
-CopyTapeSetDesc(toPtr, fromPtr)
- struct tc_tapeSet *toPtr, *fromPtr;
-{
-
- toPtr->id = fromPtr->id;
- toPtr->maxTapes = fromPtr->maxTapes;
- toPtr->a = fromPtr->a;
- toPtr->b = fromPtr->b;
- strcpy(toPtr->tapeServer, fromPtr->tapeServer);
- strcpy(toPtr->format, fromPtr->format);
-
- toPtr->expDate = fromPtr->expDate;
- toPtr->expType = fromPtr->expType;
- return 0;
-}
#include "error_macros.h"
/* GLOBAL CONFIGURATION PARAMETERS */
+#define BIGCHUNK 102400
+
extern int dump_namecheck;
extern int autoQuery;
return (code);
}
+/* writeDbDump
+ * notes:
+ * this code assumes that the blocksize on reads is smaller than
+ * the blocksize on writes
+ */
+
+static
+writeDbDump(tapeInfoPtr, taskId, expires, dumpid)
+ struct butm_tapeInfo *tapeInfoPtr;
+ afs_uint32 taskId;
+ Date expires;
+ afs_uint32 dumpid;
+{
+ afs_int32 blockSize;
+ afs_int32 writeBufNbytes = 0;
+ char *writeBlock = 0;
+ char *writeBuffer = 0;
+ char *writeBufPtr;
+ afs_int32 transferSize;
+
+ char *readBufPtr;
+ afs_int32 maxReadSize;
+
+ charListT charList;
+ afs_int32 done;
+ afs_int32 code;
+ afs_int32 chunksize = 0;
+ afs_int32 tc_EndMargin, tc_KEndMargin, kRemaining;
+ int sequence;
+ int wroteLabel;
+ int firstcall;
+#ifdef AFS_PTHREAD_ENV
+ pthread_t alivePid;
+ pthread_attr_t tattr;
+ AFS_SIGSET_DECL;
+#else
+ PROCESS alivePid;
+#endif
+
+ extern struct tapeConfig globalTapeConfig;
+ extern struct udbHandleS udbHandle;
+
+ extern int KeepAlive();
+
+ blockSize = BUTM_BLKSIZE;
+ writeBlock = (char *)malloc(BUTM_BLOCKSIZE);
+ if (!writeBlock)
+ ERROR_EXIT(TC_NOMEMORY);
+
+ writeBuffer = writeBlock + sizeof(struct blockMark);
+ memset(writeBuffer, 0, BUTM_BLKSIZE);
+ maxReadSize = 1024;
+
+ /*
+ * The margin of space to check for end of tape is set to the
+ * amount of space used to write an end-of-tape multiplied by 2.
+ * The amount of space is size of a 16K EODump marker, its EOF
+ * marker, and up to two EOF markers done on close (1 16K blocks +
+ * 3 EOF * markers).
+ */
+ tc_EndMargin = (16384 + 3 * globalTapeConfig.fileMarkSize) * 2;
+ tc_KEndMargin = tc_EndMargin / 1024;
+
+ /* have to write enclose the dump in file marks */
+ code = butm_WriteFileBegin(tapeInfoPtr);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't write FileBegin on tape\n");
+ ERROR_EXIT(code);
+ }
+
+ writeBufPtr = &writeBuffer[0];
+ firstcall = 1;
+ sequence = 1;
+ charList.charListT_val = 0;
+ charList.charListT_len = 0;
+
+ while (1) { /*w */
+ /* When no data in buffer, read data from the budb_server */
+ if (charList.charListT_len == 0) {
+ /* get more data. let rx allocate space */
+ if (charList.charListT_val) {
+ free(charList.charListT_val);
+ charList.charListT_val = 0;
+ }
+
+ /* get the data */
+ code =
+ ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client,
+ UF_SINGLESERVER, firstcall,
+ maxReadSize, &charList, &done);
+ if (code) {
+ ErrorLog(0, taskId, code, 0, "Can't read database\n");
+ ERROR_EXIT(code);
+ }
+
+ /* If this if the first call to the budb server, create a thread
+ * that will keep the connection alive (during tape changes).
+ */
+ if (firstcall) {
+#ifdef AFS_PTHREAD_ENV
+ code = pthread_attr_init(&tattr);
+ if (code) {
+ ErrorLog(0, taskId, code, 0,
+ "Can't pthread_attr_init Keep-alive process\n");
+ ERROR_EXIT(code);
+ }
+
+ code =
+ pthread_attr_setdetachstate(&tattr,
+ PTHREAD_CREATE_DETACHED);
+ if (code) {
+ ErrorLog(0, taskId, code, 0,
+ "Can't pthread_attr_setdetachstate Keep-alive process\n");
+ ERROR_EXIT(code);
+ }
+
+ AFS_SIGSET_CLEAR();
+ code = pthread_create(&alivePid, &tattr, KeepAlive, 0);
+ AFS_SIGSET_RESTORE();
+#else
+ code =
+ LWP_CreateProcess(KeepAlive, 16384, 1, (void *)NULL,
+ "Keep-alive process", &alivePid);
+#endif
+ /* XXX should we check code here ??? XXX */
+ }
+ firstcall = 0;
+
+ readBufPtr = charList.charListT_val;
+ }
+
+ if ((charList.charListT_len == 0) && done)
+ break;
+
+ /* compute how many bytes and transfer to the write Buffer */
+ transferSize =
+ (charList.charListT_len <
+ (blockSize -
+ writeBufNbytes)) ? charList.charListT_len : (blockSize -
+ writeBufNbytes);
+
+ memcpy(writeBufPtr, readBufPtr, transferSize);
+ charList.charListT_len -= transferSize;
+ writeBufPtr += transferSize;
+ readBufPtr += transferSize;
+ writeBufNbytes += transferSize;
+
+ /* If filled the write buffer, then write it to tape */
+ if (writeBufNbytes == blockSize) {
+ code = butm_WriteFileData(tapeInfoPtr, writeBuffer, 1, blockSize);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't write data on tape\n");
+ ERROR_EXIT(code);
+ }
+
+ memset(writeBuffer, 0, blockSize);
+ writeBufPtr = &writeBuffer[0];
+ writeBufNbytes = 0;
+
+ /* Every BIGCHUNK bytes check if aborted */
+ chunksize += blockSize;
+ if (chunksize > BIGCHUNK) {
+ chunksize = 0;
+ if (checkAbortByTaskId(taskId))
+ ERROR_EXIT(TC_ABORTEDBYREQUEST);
+ }
+
+ /*
+ * check if tape is full - since we filled a blockSize worth of data
+ * assume that there is more data.
+ */
+ kRemaining = butm_remainingKSpace(tapeInfoPtr);
+ if (kRemaining < tc_KEndMargin) {
+ code = butm_WriteFileEnd(tapeInfoPtr);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't write FileEnd on tape\n");
+ ERROR_EXIT(code);
+ }
+
+ code = butm_WriteEOT(tapeInfoPtr);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't write end-of-dump on tape\n");
+ ERROR_EXIT(code);
+ }
+
+ /* Mark tape as having been written */
+ tapeEntryPtr->useKBytes =
+ tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
+ tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
+
+ unmountTape(taskId, tapeInfoPtr);
+
+ /* Get next tape and writes its label */
+ sequence++;
+ code =
+ GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence,
+ 1, &wroteLabel);
+ if (code)
+ ERROR_EXIT(code);
+
+ code = butm_WriteFileBegin(tapeInfoPtr);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't write FileBegin on tape\n");
+ ERROR_EXIT(code);
+ }
+ }
+ }
+ } /*w */
+
+ /* no more data to be read - if necessary, flush out the last buffer */
+ if (writeBufNbytes > 0) {
+ code = butm_WriteFileData(tapeInfoPtr, writeBuffer, 1, blockSize);
+ if (code) {
+ ErrorLog(1, taskId, code, tapeInfoPtr->error,
+ "Can't write data on tape\n");
+ ERROR_EXIT(code);
+ }
+ }
+
+ code = butm_WriteFileEnd(tapeInfoPtr);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't write FileEnd on tape\n");
+ ERROR_EXIT(code);
+ }
+
+ /* Mark tape as having been written */
+ tapeEntryPtr->useKBytes =
+ tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
+ tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
+
+ error_exit:
+ /* Let the KeepAlive process stop on its own */
+ code =
+ ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client,
+ UF_END_SINGLESERVER, 0);
+
+ if (writeBlock)
+ free(writeBlock);
+ if (charList.charListT_val)
+ free(charList.charListT_val);
+ return (code);
+}
+
/* saveDbToTape
* dump backup database to tape
*/
return (code);
}
-/* restoreDbFromTape
- * restore the backup database from tape.
- */
-
-afs_int32
+static afs_int32 nbytes = 0; /* # bytes left in buffer */
+static
+initTapeBuffering()
+{
+ nbytes = 0;
+}
+
+
+/* restoreDbEntries
+ * restore all the items on the tape
+ * entry:
+ * tape positioned after tape label
+ */
+
+static
+restoreDbEntries(tapeInfoPtr, rstTapeInfoPtr)
+ struct butm_tapeInfo *tapeInfoPtr;
+ struct rstTapeInfo *rstTapeInfoPtr;
+{
+ struct structDumpHeader netItemHeader, hostItemHeader;
+ afs_int32 more = 1;
+ afs_int32 taskId, code = 0;
+ int count = 0;
+
+ taskId = rstTapeInfoPtr->taskId;
+
+ /* clear state for the buffer routine(s) */
+ initTapeBuffering();
+
+ code = butm_ReadFileBegin(tapeInfoPtr);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't read FileBegin on tape\n");
+ ERROR_EXIT(code);
+ }
+
+ /* get the first item-header */
+ memset(&netItemHeader, 0, sizeof(netItemHeader));
+ code =
+ getTapeData(tapeInfoPtr, rstTapeInfoPtr, &netItemHeader,
+ sizeof(netItemHeader));
+ if (code)
+ ERROR_EXIT(code);
+ structDumpHeader_ntoh(&netItemHeader, &hostItemHeader);
+
+ while (more) {
+ switch (hostItemHeader.type) {
+ case SD_DBHEADER:
+ code =
+ restoreDbHeader(tapeInfoPtr, rstTapeInfoPtr, &hostItemHeader);
+ if (code)
+ ERROR_EXIT(code);
+ break;
+
+ case SD_DUMP:
+ if (++count > 25) { /*every 25 dumps, wait */
+ waitDbWatcher();
+ count = 0;
+ }
+ code =
+ restoreDbDump(tapeInfoPtr, rstTapeInfoPtr, &hostItemHeader);
+ if (code)
+ ERROR_EXIT(code);
+ break;
+
+ case SD_TAPE:
+ case SD_VOLUME:
+ ERROR_EXIT(-1);
+ break;
+
+ case SD_TEXT_DUMPSCHEDULE:
+ case SD_TEXT_VOLUMESET:
+ case SD_TEXT_TAPEHOSTS:
+ code = restoreText(tapeInfoPtr, rstTapeInfoPtr, &hostItemHeader);
+ if (code)
+ ERROR_EXIT(code);
+ break;
+
+ case SD_END:
+ more = 0;
+ break;
+
+ default:
+ TLog(taskId, "Unknown database header type %d\n",
+ hostItemHeader.type);
+ ERROR_EXIT(-1);
+ break;
+ }
+ }
+
+ code = butm_ReadFileEnd(tapeInfoPtr);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't read EOF on tape\n");
+ ERROR_EXIT(code);
+ }
+
+ /* Mark tape as having been written */
+ tapeEntryPtr->useKBytes =
+ tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
+ tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
+
+ error_exit:
+ return (code);
+}
+
+/* restoreDbFromTape
+ * restore the backup database from tape.
+ */
+
+afs_int32
restoreDbFromTape(taskId)
afs_uint32 taskId;
{
return 0;
}
-#define BIGCHUNK 102400
-
-/* writeDbDump
- * notes:
- * this code assumes that the blocksize on reads is smaller than
- * the blocksize on writes
- */
-
-static
-writeDbDump(tapeInfoPtr, taskId, expires, dumpid)
- struct butm_tapeInfo *tapeInfoPtr;
- afs_uint32 taskId;
- Date expires;
- afs_uint32 dumpid;
-{
- afs_int32 blockSize;
- afs_int32 writeBufNbytes = 0;
- char *writeBlock = 0;
- char *writeBuffer = 0;
- char *writeBufPtr;
- afs_int32 transferSize;
-
- char *readBufPtr;
- afs_int32 maxReadSize;
-
- charListT charList;
- afs_int32 done;
- afs_int32 code;
- afs_int32 chunksize = 0;
- afs_int32 tc_EndMargin, tc_KEndMargin, kRemaining;
- int sequence;
- int wroteLabel;
- int firstcall;
-#ifdef AFS_PTHREAD_ENV
- pthread_t alivePid;
- pthread_attr_t tattr;
- AFS_SIGSET_DECL;
-#else
- PROCESS alivePid;
-#endif
-
- extern struct tapeConfig globalTapeConfig;
- extern struct udbHandleS udbHandle;
-
- extern int KeepAlive();
-
- blockSize = BUTM_BLKSIZE;
- writeBlock = (char *)malloc(BUTM_BLOCKSIZE);
- if (!writeBlock)
- ERROR_EXIT(TC_NOMEMORY);
-
- writeBuffer = writeBlock + sizeof(struct blockMark);
- memset(writeBuffer, 0, BUTM_BLKSIZE);
- maxReadSize = 1024;
-
- /*
- * The margin of space to check for end of tape is set to the
- * amount of space used to write an end-of-tape multiplied by 2.
- * The amount of space is size of a 16K EODump marker, its EOF
- * marker, and up to two EOF markers done on close (1 16K blocks +
- * 3 EOF * markers).
- */
- tc_EndMargin = (16384 + 3 * globalTapeConfig.fileMarkSize) * 2;
- tc_KEndMargin = tc_EndMargin / 1024;
-
- /* have to write enclose the dump in file marks */
- code = butm_WriteFileBegin(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write FileBegin on tape\n");
- ERROR_EXIT(code);
- }
-
- writeBufPtr = &writeBuffer[0];
- firstcall = 1;
- sequence = 1;
- charList.charListT_val = 0;
- charList.charListT_len = 0;
-
- while (1) { /*w */
- /* When no data in buffer, read data from the budb_server */
- if (charList.charListT_len == 0) {
- /* get more data. let rx allocate space */
- if (charList.charListT_val) {
- free(charList.charListT_val);
- charList.charListT_val = 0;
- }
-
- /* get the data */
- code =
- ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client,
- UF_SINGLESERVER, firstcall,
- maxReadSize, &charList, &done);
- if (code) {
- ErrorLog(0, taskId, code, 0, "Can't read database\n");
- ERROR_EXIT(code);
- }
-
- /* If this if the first call to the budb server, create a thread
- * that will keep the connection alive (during tape changes).
- */
- if (firstcall) {
-#ifdef AFS_PTHREAD_ENV
- code = pthread_attr_init(&tattr);
- if (code) {
- ErrorLog(0, taskId, code, 0,
- "Can't pthread_attr_init Keep-alive process\n");
- ERROR_EXIT(code);
- }
-
- code =
- pthread_attr_setdetachstate(&tattr,
- PTHREAD_CREATE_DETACHED);
- if (code) {
- ErrorLog(0, taskId, code, 0,
- "Can't pthread_attr_setdetachstate Keep-alive process\n");
- ERROR_EXIT(code);
- }
-
- AFS_SIGSET_CLEAR();
- code = pthread_create(&alivePid, &tattr, KeepAlive, 0);
- AFS_SIGSET_RESTORE();
-#else
- code =
- LWP_CreateProcess(KeepAlive, 16384, 1, (void *)NULL,
- "Keep-alive process", &alivePid);
-#endif
- /* XXX should we check code here ??? XXX */
- }
- firstcall = 0;
-
- readBufPtr = charList.charListT_val;
- }
-
- if ((charList.charListT_len == 0) && done)
- break;
-
- /* compute how many bytes and transfer to the write Buffer */
- transferSize =
- (charList.charListT_len <
- (blockSize -
- writeBufNbytes)) ? charList.charListT_len : (blockSize -
- writeBufNbytes);
-
- memcpy(writeBufPtr, readBufPtr, transferSize);
- charList.charListT_len -= transferSize;
- writeBufPtr += transferSize;
- readBufPtr += transferSize;
- writeBufNbytes += transferSize;
-
- /* If filled the write buffer, then write it to tape */
- if (writeBufNbytes == blockSize) {
- code = butm_WriteFileData(tapeInfoPtr, writeBuffer, 1, blockSize);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write data on tape\n");
- ERROR_EXIT(code);
- }
-
- memset(writeBuffer, 0, blockSize);
- writeBufPtr = &writeBuffer[0];
- writeBufNbytes = 0;
-
- /* Every BIGCHUNK bytes check if aborted */
- chunksize += blockSize;
- if (chunksize > BIGCHUNK) {
- chunksize = 0;
- if (checkAbortByTaskId(taskId))
- ERROR_EXIT(TC_ABORTEDBYREQUEST);
- }
-
- /*
- * check if tape is full - since we filled a blockSize worth of data
- * assume that there is more data.
- */
- kRemaining = butm_remainingKSpace(tapeInfoPtr);
- if (kRemaining < tc_KEndMargin) {
- code = butm_WriteFileEnd(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write FileEnd on tape\n");
- ERROR_EXIT(code);
- }
-
- code = butm_WriteEOT(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write end-of-dump on tape\n");
- ERROR_EXIT(code);
- }
-
- /* Mark tape as having been written */
- tapeEntryPtr->useKBytes =
- tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
- tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
-
- unmountTape(taskId, tapeInfoPtr);
-
- /* Get next tape and writes its label */
- sequence++;
- code =
- GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence,
- 1, &wroteLabel);
- if (code)
- ERROR_EXIT(code);
-
- code = butm_WriteFileBegin(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write FileBegin on tape\n");
- ERROR_EXIT(code);
- }
- }
- }
- } /*w */
-
- /* no more data to be read - if necessary, flush out the last buffer */
- if (writeBufNbytes > 0) {
- code = butm_WriteFileData(tapeInfoPtr, writeBuffer, 1, blockSize);
- if (code) {
- ErrorLog(1, taskId, code, tapeInfoPtr->error,
- "Can't write data on tape\n");
- ERROR_EXIT(code);
- }
- }
-
- code = butm_WriteFileEnd(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write FileEnd on tape\n");
- ERROR_EXIT(code);
- }
-
- /* Mark tape as having been written */
- tapeEntryPtr->useKBytes =
- tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
- tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
-
- error_exit:
- /* Let the KeepAlive process stop on its own */
- code =
- ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client,
- UF_END_SINGLESERVER, 0);
-
- if (writeBlock)
- free(writeBlock);
- if (charList.charListT_val)
- free(charList.charListT_val);
- return (code);
-}
-
-
-/* restoreDbEntries
- * restore all the items on the tape
- * entry:
- * tape positioned after tape label
- */
-
-static
-restoreDbEntries(tapeInfoPtr, rstTapeInfoPtr)
- struct butm_tapeInfo *tapeInfoPtr;
- struct rstTapeInfo *rstTapeInfoPtr;
-{
- struct structDumpHeader netItemHeader, hostItemHeader;
- afs_int32 more = 1;
- afs_int32 taskId, code = 0;
- int count = 0;
-
- taskId = rstTapeInfoPtr->taskId;
-
- /* clear state for the buffer routine(s) */
- initTapeBuffering();
-
- code = butm_ReadFileBegin(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't read FileBegin on tape\n");
- ERROR_EXIT(code);
- }
-
- /* get the first item-header */
- memset(&netItemHeader, 0, sizeof(netItemHeader));
- code =
- getTapeData(tapeInfoPtr, rstTapeInfoPtr, &netItemHeader,
- sizeof(netItemHeader));
- if (code)
- ERROR_EXIT(code);
- structDumpHeader_ntoh(&netItemHeader, &hostItemHeader);
-
- while (more) {
- switch (hostItemHeader.type) {
- case SD_DBHEADER:
- code =
- restoreDbHeader(tapeInfoPtr, rstTapeInfoPtr, &hostItemHeader);
- if (code)
- ERROR_EXIT(code);
- break;
-
- case SD_DUMP:
- if (++count > 25) { /*every 25 dumps, wait */
- waitDbWatcher();
- count = 0;
- }
- code =
- restoreDbDump(tapeInfoPtr, rstTapeInfoPtr, &hostItemHeader);
- if (code)
- ERROR_EXIT(code);
- break;
-
- case SD_TAPE:
- case SD_VOLUME:
- ERROR_EXIT(-1);
- break;
-
- case SD_TEXT_DUMPSCHEDULE:
- case SD_TEXT_VOLUMESET:
- case SD_TEXT_TAPEHOSTS:
- code = restoreText(tapeInfoPtr, rstTapeInfoPtr, &hostItemHeader);
- if (code)
- ERROR_EXIT(code);
- break;
-
- case SD_END:
- more = 0;
- break;
-
- default:
- TLog(taskId, "Unknown database header type %d\n",
- hostItemHeader.type);
- ERROR_EXIT(-1);
- break;
- }
- }
-
- code = butm_ReadFileEnd(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't read EOF on tape\n");
- ERROR_EXIT(code);
- }
-
- /* Mark tape as having been written */
- tapeEntryPtr->useKBytes =
- tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
- tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
-
- error_exit:
- return (code);
-}
/* restoreDbHeader
* restore special items in the header
static char *tapeReadBuffer = 0; /* input buffer */
static char *tapeReadBufferPtr = 0; /* position in buffer */
-static afs_int32 nbytes = 0; /* # bytes left in buffer */
-
-static
-initTapeBuffering()
-{
- nbytes = 0;
-}
/* getTapeData
* Read information from tape, and place the requested number of bytes
static int ks_perm[16 + 1][48 + 1];
-static int des_debug;
+int des_debug;
void
gen(FILE * stream)