/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
+#include <afs/procmgmt.h>
+#include <roken.h>
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#include <io.h>
-#else
-#include <sys/time.h>
-#include <sys/file.h>
-#include <netinet/in.h>
-#include <netdb.h>
+#ifdef IGNORE_SOME_GCC_WARNINGS
+# pragma GCC diagnostic warning "-Wimplicit-function-declaration"
#endif
-#include <errno.h>
+
#include <rx/xdr.h>
#include <rx/rx.h>
#include <afs/afsint.h>
-#include <stdio.h>
-#include <afs/procmgmt.h>
-#include <afs/assert.h>
+#include <afs/afs_assert.h>
#include <afs/prs_fs.h>
-#include <fcntl.h>
#include <afs/nfs.h>
#include <lwp.h>
#include <lock.h>
-#include <afs/auth.h>
#include <afs/cellconfig.h>
#include <afs/keys.h>
#include <ubik.h>
#include <afs/acl.h>
+#include <afs/volser.h>
+#include <afs/vlserver.h>
#include <afs/tcdata.h>
#include <afs/budb.h>
#include <afs/budb_client.h>
#include <afs/bubasics.h>
+#include <afs/bucoord_prototypes.h>
+#include <afs/butm_prototypes.h>
+#include <afs/budb_prototypes.h>
+#include <afs/afsutil.h>
+
+#include "butc_internal.h"
#include "error_macros.h"
/* GLOBAL CONFIGURATION PARAMETERS */
+#define BIGCHUNK 102400
+
extern int dump_namecheck;
extern int autoQuery;
+struct rstTapeInfo {
+ afs_int32 taskId;
+ afs_int32 tapeSeq;
+ afs_uint32 dumpid;
+};
+
+static void initTapeBuffering(void);
+static int writeDbDump(struct butm_tapeInfo *, afs_uint32, Date, afs_uint32);
+static int restoreDbEntries(struct butm_tapeInfo *, struct rstTapeInfo *);
+
+int getTapeData(struct butm_tapeInfo *, struct rstTapeInfo *, void *,
+ afs_int32);
+int restoreDbHeader(struct butm_tapeInfo *, struct rstTapeInfo *,
+ struct structDumpHeader *);
+int restoreDbDump(struct butm_tapeInfo *, struct rstTapeInfo *,
+ struct structDumpHeader *);
+int restoreText(struct butm_tapeInfo *, struct rstTapeInfo *,
+ struct structDumpHeader *);
+
+
+
+void * KeepAlive(void *);
/* CreateDBDump
- * create a dump entry for a saved database
+ * create a dump entry for a saved database
*/
afs_int32
-CreateDBDump(dumpEntryPtr)
- struct budb_dumpEntry *dumpEntryPtr;
+CreateDBDump(struct budb_dumpEntry *dumpEntryPtr)
{
afs_int32 code = 0;
* Leave the tape mounted.
*/
afs_int32
-GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence, queryFlag,
- wroteLabel)
- afs_int32 taskId;
- Date expires;
- struct butm_tapeInfo *tapeInfoPtr;
- afs_uint32 dumpid;
- afs_int32 sequence;
- int queryFlag;
- int *wroteLabel;
+GetDBTape(afs_int32 taskId, Date expires, struct butm_tapeInfo *tapeInfoPtr,
+ afs_uint32 dumpid, afs_int32 sequence, int queryFlag,
+ int *wroteLabel)
{
afs_int32 code = 0;
int interactiveFlag;
char tapeName[BU_MAXTAPELEN];
char strlevel[5];
struct timeval tp;
- struct timezone tzp;
afs_int32 curTime;
int tapecount = 1;
struct butm_tapeLabel oldTapeLabel, newLabel;
struct tapeEntryList *endList;
- extern struct tapeConfig globalTapeConfig;
/* construct the name of the tape */
sprintf(tapeName, "%s.%-d", DUMP_TAPE_NAME, sequence);
goto getNewTape;
}
- /* On first tape, the savedb has not started yet, so the database is not locked
+ /* On first tape, the savedb has not started yet, so the database is not locked
* and we can therefore, access information from it. This is easier to do because
* database dumps don't have appended dumps (nor appended).
*/
struct budb_dumpEntry de, de2;
/* Verify the tape has not expired
- * Early database dumps don't have a dumpid
+ * Early database dumps don't have a dumpid
*/
if (!tapeExpired(&oldTapeLabel)) {
TLog(taskId, "This tape has not expired\n");
}
/* Otherwise, the savedb is in progress and we can't
- * access the database (it's locked). So we rely on the
+ * access the database (it's locked). So we rely on the
* information available (and not the backup database).
*/
else {
/* Check the tape's expiration date. Use the expiration on the label */
- gettimeofday(&tp, &tzp);
+ gettimeofday(&tp, NULL);
curTime = tp.tv_sec;
if (curTime < oldTapeLabel.expirationDate) {
TLog(taskId, "This tape has not expired\n");
*/
afs_int32
-freeTapeList()
+freeTapeList(void)
{
struct tapeEntryList *next;
}
/* addTapesToDb
- * With the list of tapes, add them to the database.
+ * With the list of tapes, add them to the database.
* Also delete any olddumpids that are around.
*/
afs_int32
-addTapesToDb(taskId)
- afs_int32 taskId;
+addTapesToDb(afs_int32 taskId)
{
afs_int32 code = 0;
afs_int32 i, new;
return (code);
}
-/* saveDbToTape
- * dump backup database to tape
+/* writeDbDump
+ * notes:
+ * this code assumes that the blocksize on reads is smaller than
+ * the blocksize on writes
*/
-afs_int32
-saveDbToTape(saveDbIfPtr)
- struct saveDbIf *saveDbIfPtr;
+static int
+writeDbDump(struct butm_tapeInfo *tapeInfoPtr, afs_uint32 taskId,
+ Date expires, afs_uint32 dumpid)
{
- afs_int32 code = 0;
- afs_int32 i;
- int wroteLabel;
- afs_uint32 taskId;
- Date expires;
+ afs_int32 blockSize;
+ afs_int32 writeBufNbytes = 0;
+ char *writeBlock = 0;
+ char *writeBuffer = 0;
+ char *writeBufPtr;
+ afs_int32 transferSize;
- struct butm_tapeInfo tapeInfo;
- struct budb_dumpEntry dumpEntry;
+ char *readBufPtr = NULL;
+ 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 deviceSyncNode *deviceLatch;
extern struct tapeConfig globalTapeConfig;
+ extern struct udbHandleS udbHandle;
- expires = (saveDbIfPtr->archiveTime ? NEVERDATE : 0);
- taskId = saveDbIfPtr->taskId;
+ blockSize = BUTM_BLKSIZE;
+ writeBlock = (char *)malloc(BUTM_BLOCKSIZE);
+ if (!writeBlock)
+ ERROR_EXIT(TC_NOMEMORY);
- setStatus(taskId, DRIVE_WAIT);
- EnterDeviceQueue(deviceLatch); /* lock tape device */
- clearStatus(taskId, DRIVE_WAIT);
+ writeBuffer = writeBlock + sizeof(struct blockMark);
+ memset(writeBuffer, 0, BUTM_BLKSIZE);
+ maxReadSize = 1024;
- printf("\n\n");
- TLog(taskId, "SaveDb\n");
+ /*
+ * 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;
- tapeInfo.structVersion = BUTM_MAJORVERSION;
- code = butm_file_Instantiate(&tapeInfo, &globalTapeConfig);
+ /* have to write enclose the dump in file marks */
+ code = butm_WriteFileBegin(tapeInfoPtr);
if (code) {
- ErrorLog(0, taskId, code, tapeInfo.error,
- "Can't initialize tape module\n");
+ ErrorLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't write FileBegin on tape\n");
ERROR_EXIT(code);
}
- /* Determine what the last database dump was */
- memset(&lastDump, 0, sizeof(lastDump));
- code = bcdb_FindLatestDump("", "", &lastDump);
- if (code) {
- if (code != BUDB_NODUMPNAME) {
- ErrorLog(0, taskId, code, 0, "Can't read backup database\n");
- ERROR_EXIT(code);
- }
- memset(&lastDump, 0, sizeof(lastDump));
- }
+ writeBufPtr = &writeBuffer[0];
+ firstcall = 1;
+ sequence = 1;
+ charList.charListT_val = 0;
+ charList.charListT_len = 0;
- code = CreateDBDump(&dumpEntry); /* Create a dump for this tape */
- if (code) {
- ErrorLog(0, taskId, code, 0, "Can't create dump in database\n");
- ERROR_EXIT(code);
- }
+ 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);
+ }
- listEntryHead = NULL;
+ /* 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);
+ }
- /* Get the tape and write a new label to it */
- code =
- GetDBTape(taskId, expires, &tapeInfo, dumpEntry.id, 1, autoQuery,
- &wroteLabel);
+ 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);
+ }
- /*
- * If did not write the label, remove created dump
- * Else if wrote the label, remove old dump from db so it's not saved.
- */
- if (!wroteLabel) {
- i = bcdb_deleteDump(dumpEntry.id, 0, 0, 0);
- dumpEntry.id = 0;
- if (i && (i != BUDB_NOENT))
- ErrorLog(0, taskId, i, 0, "Unable to delete DB entry %u.\n",
- dumpEntry.id);
- } else if (listEntryHead->oldDumpId) {
- i = bcdb_deleteDump(listEntryHead->oldDumpId, 0, 0, 0);
- listEntryHead->oldDumpId = 0;
- if (i && (i != BUDB_NOENT)) {
- ErrorLog(0, taskId, i, 0, "Unable to delete old DB entry %u.\n",
- listEntryHead->oldDumpId);
- ERROR_EXIT(i);
+ 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 (code)
- ERROR_EXIT(code);
- TapeLog(1, taskId, 0, 0, "Tape accepted - now dumping database\n");
+ if ((charList.charListT_len == 0) && done)
+ break;
- /* we have a writable tape */
- code = writeDbDump(&tapeInfo, taskId, expires, dumpEntry.id);
- if (code)
- ERROR_EXIT(code);
+ /* compute how many bytes and transfer to the write Buffer */
+ transferSize =
+ (charList.charListT_len <
+ (blockSize -
+ writeBufNbytes)) ? charList.charListT_len : (blockSize -
+ writeBufNbytes);
- /* Now delete the entries between time 0 and archive-time */
- if (saveDbIfPtr->archiveTime)
- code = bcdb_deleteDump(0, 0, saveDbIfPtr->archiveTime, 0);
+ memcpy(writeBufPtr, readBufPtr, transferSize);
+ charList.charListT_len -= transferSize;
+ writeBufPtr += transferSize;
+ readBufPtr += transferSize;
+ writeBufNbytes += transferSize;
- error_exit:
- unmountTape(taskId, &tapeInfo);
+ /* 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);
+ }
- /* Add this dump's tapes to the database and mark it finished */
- if (dumpEntry.id) {
- i = addTapesToDb(taskId);
- if (!code)
- code = i;
+ memset(writeBuffer, 0, blockSize);
+ writeBufPtr = &writeBuffer[0];
+ writeBufNbytes = 0;
- i = bcdb_FinishDump(&dumpEntry);
- if (!code)
- code = i;
- }
- freeTapeList();
+ /* Every BIGCHUNK bytes check if aborted */
+ chunksize += blockSize;
+ if (chunksize > BIGCHUNK) {
+ chunksize = 0;
+ if (checkAbortByTaskId(taskId))
+ ERROR_EXIT(TC_ABORTEDBYREQUEST);
+ }
- if (code == TC_ABORTEDBYREQUEST) {
- TLog(taskId, "SaveDb: Aborted by request\n");
- clearStatus(taskId, ABORT_REQUEST);
- setStatus(taskId, ABORT_DONE);
- } else if (code) {
- TapeLog(0, taskId, code, 0, "SaveDb: Finished with errors\n");
- setStatus(taskId, TASK_ERROR);
- } else {
- TLog(taskId, "SaveDb: Finished\n");
- }
- setStatus(taskId, TASK_DONE);
+ /*
+ * 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);
+ }
- free(saveDbIfPtr);
- LeaveDeviceQueue(deviceLatch);
- return (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
+ */
+
+void *
+saveDbToTape(void *param)
+{
+ struct saveDbIf *saveDbIfPtr = (struct saveDbIf *)param;
+ afs_int32 code;
+ afs_int32 i;
+ int wroteLabel;
+ afs_uint32 taskId;
+ Date expires;
+
+ struct butm_tapeInfo tapeInfo;
+ struct budb_dumpEntry dumpEntry;
+
+ extern struct deviceSyncNode *deviceLatch;
+ extern struct tapeConfig globalTapeConfig;
+
+ afs_pthread_setname_self("Db save");
+ expires = (saveDbIfPtr->archiveTime ? NEVERDATE : 0);
+ taskId = saveDbIfPtr->taskId;
+ dumpEntry.id = 0;
+
+ setStatus(taskId, DRIVE_WAIT);
+ EnterDeviceQueue(deviceLatch); /* lock tape device */
+ clearStatus(taskId, DRIVE_WAIT);
+
+ printf("\n\n");
+ TLog(taskId, "SaveDb\n");
+
+ tapeInfo.structVersion = BUTM_MAJORVERSION;
+ code = butm_file_Instantiate(&tapeInfo, &globalTapeConfig);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfo.error,
+ "Can't initialize tape module\n");
+ ERROR_EXIT(code);
+ }
+
+ /* Determine what the last database dump was */
+ memset(&lastDump, 0, sizeof(lastDump));
+ code = bcdb_FindLatestDump("", "", &lastDump);
+ if (code) {
+ if (code != BUDB_NODUMPNAME) {
+ ErrorLog(0, taskId, code, 0, "Can't read backup database\n");
+ ERROR_EXIT(code);
+ }
+ memset(&lastDump, 0, sizeof(lastDump));
+ }
+
+ code = CreateDBDump(&dumpEntry); /* Create a dump for this tape */
+ if (code) {
+ ErrorLog(0, taskId, code, 0, "Can't create dump in database\n");
+ ERROR_EXIT(code);
+ }
+
+
+ listEntryHead = NULL;
+
+ /* Get the tape and write a new label to it */
+ code =
+ GetDBTape(taskId, expires, &tapeInfo, dumpEntry.id, 1, autoQuery,
+ &wroteLabel);
+
+ /*
+ * If did not write the label, remove created dump
+ * Else if wrote the label, remove old dump from db so it's not saved.
+ */
+ if (!wroteLabel) {
+ i = bcdb_deleteDump(dumpEntry.id, 0, 0, 0);
+ dumpEntry.id = 0;
+ if (i && (i != BUDB_NOENT))
+ ErrorLog(0, taskId, i, 0, "Unable to delete DB entry %u.\n",
+ dumpEntry.id);
+ } else if (listEntryHead->oldDumpId) {
+ i = bcdb_deleteDump(listEntryHead->oldDumpId, 0, 0, 0);
+ listEntryHead->oldDumpId = 0;
+ if (i && (i != BUDB_NOENT)) {
+ ErrorLog(0, taskId, i, 0, "Unable to delete old DB entry %u.\n",
+ listEntryHead->oldDumpId);
+ ERROR_EXIT(i);
+ }
+ }
+ if (code)
+ ERROR_EXIT(code);
+
+ TapeLog(1, taskId, 0, 0, "Tape accepted - now dumping database\n");
+
+ /* we have a writable tape */
+ code = writeDbDump(&tapeInfo, taskId, expires, dumpEntry.id);
+ if (code)
+ ERROR_EXIT(code);
+
+ /* Now delete the entries between time 0 and archive-time */
+ if (saveDbIfPtr->archiveTime)
+ code = bcdb_deleteDump(0, 0, saveDbIfPtr->archiveTime, 0);
+
+ error_exit:
+ unmountTape(taskId, &tapeInfo);
+
+ /* Add this dump's tapes to the database and mark it finished */
+ if (dumpEntry.id) {
+ i = addTapesToDb(taskId);
+ if (!code)
+ code = i;
+
+ i = bcdb_FinishDump(&dumpEntry);
+ if (!code)
+ code = i;
+ }
+ freeTapeList();
+
+ if (code == TC_ABORTEDBYREQUEST) {
+ TLog(taskId, "SaveDb: Aborted by request\n");
+ clearStatus(taskId, ABORT_REQUEST);
+ setStatus(taskId, ABORT_DONE);
+ } else if (code) {
+ TapeLog(0, taskId, code, 0, "SaveDb: Finished with errors\n");
+ setStatus(taskId, TASK_ERROR);
+ } else {
+ TLog(taskId, "SaveDb: Finished\n");
+ }
+ setStatus(taskId, TASK_DONE);
+
+ free(saveDbIfPtr);
+ LeaveDeviceQueue(deviceLatch);
+ return (void *)(intptr_t)(code);
+}
-struct rstTapeInfo {
- afs_int32 taskId;
- afs_int32 tapeSeq;
- afs_uint32 dumpid;
-};
/* makeDbDumpEntry()
* Make a database dump entry given a tape label.
*/
afs_int32
-makeDbDumpEntry(tapeEntPtr, dumpEntryPtr)
- struct budb_tapeEntry *tapeEntPtr;
- struct budb_dumpEntry *dumpEntryPtr;
+makeDbDumpEntry(struct budb_tapeEntry *tapeEntPtr,
+ struct budb_dumpEntry *dumpEntryPtr)
{
memset(dumpEntryPtr, 0, sizeof(struct budb_dumpEntry));
strcat(dumpEntryPtr->tapes.format, ".%d");
dumpEntryPtr->tapes.b = tapeEntPtr->seq;
dumpEntryPtr->tapes.maxTapes = 0;
+ return 0;
}
/* readDbTape
*/
afs_int32
-readDbTape(tapeInfoPtr, rstTapeInfoPtr, query)
- struct butm_tapeInfo *tapeInfoPtr;
- struct rstTapeInfo *rstTapeInfoPtr;
- int query;
+readDbTape(struct butm_tapeInfo *tapeInfoPtr,
+ struct rstTapeInfo *rstTapeInfoPtr, int query)
{
afs_int32 code = 0;
int interactiveFlag;
if (interactiveFlag) { /* need a tape to read */
code =
PromptForTape(RESTOREDBOPCODE, tapeName,
- rstTapeInfoPtr->dumpid, taskId, tapecount);
- if (code)
- ERROR_EXIT(code);
- }
- interactiveFlag = 1;
- tapecount++;
-
- code = butm_Mount(tapeInfoPtr, tapeName);
- if (code) {
- TapeLog(0, taskId, code, tapeInfoPtr->error, "Can't open tape\n");
- goto getNewTape;
- }
-
- code = butm_ReadLabel(tapeInfoPtr, &oldTapeLabel, 1); /* will rewind the tape */
- if (code) {
- TapeLog(0, taskId, code, tapeInfoPtr->error,
- "Can't read tape label\n");
- goto getNewTape;
- }
-
- /* Check for name of tape and matching dump id (if applicable). */
- if ((strcmp(oldTapeLabel.AFSName, AFStapeName) != 0)
- || ((rstTapeInfoPtr->tapeSeq != 1)
- && (oldTapeLabel.dumpid != rstTapeInfoPtr->dumpid))) {
- char expTape[BU_MAXTAPELEN + 32];
- char gotTape[BU_MAXTAPELEN + 32];
-
- TAPENAME(expTape, tapeName, rstTapeInfoPtr->dumpid);
- TAPENAME(gotTape, oldTapeLabel.AFSName, oldTapeLabel.dumpid);
-
- TLog(taskId, "Tape label expected %s, label seen %s\n", expTape,
- gotTape);
- goto getNewTape;
- }
-
- if (rstTapeInfoPtr->tapeSeq == 1) /* Remember this dumpId */
- rstTapeInfoPtr->dumpid = oldTapeLabel.dumpid;
-
- break;
-
- getNewTape:
- unmountTape(taskId, tapeInfoPtr);
- } /*w */
-
-
- /* Initialize a tapeEntry for later inclusion into the database */
- listEntryPtr =
- (struct tapeEntryList *)malloc(sizeof(struct tapeEntryList));
- if (!listEntryPtr)
- ERROR_EXIT(TC_NOMEMORY);
- memset(listEntryPtr, 0, sizeof(struct tapeEntryList));
-
- /* Fill in tape entry so we can save it later */
- strcpy(tapeEntryPtr->name, TNAME(&oldTapeLabel));
- tapeEntryPtr->dump = oldTapeLabel.dumpid;
- tapeEntryPtr->flags = BUDB_TAPE_BEINGWRITTEN;
- tapeEntryPtr->written = oldTapeLabel.creationTime;
- tapeEntryPtr->expires = oldTapeLabel.expirationDate;
- tapeEntryPtr->seq = extractTapeSeq(oldTapeLabel.AFSName);
- tapeEntryPtr->useCount = oldTapeLabel.useCount;
- tapeEntryPtr->useKBytes = 0;
- tapeEntryPtr->labelpos = 0;
-
- /* Thread onto end of single-linked list */
- if (listEntryHead) {
- endList = listEntryHead;
- while (endList->next)
- endList = endList->next;
- endList->next = listEntryPtr;
- } else
- listEntryHead = listEntryPtr;
-
- error_exit:
- return (code);
-}
-
-/* restoreDbFromTape
- * restore the backup database from tape.
- */
-
-afs_int32
-restoreDbFromTape(taskId)
- afs_uint32 taskId;
-{
- afs_int32 code = 0;
- afs_int32 i;
- struct butm_tapeInfo tapeInfo;
- struct rstTapeInfo rstTapeInfo;
- struct budb_dumpEntry dumpEntry;
-
- extern struct tapeConfig globalTapeConfig;
- extern struct deviceSyncNode *deviceLatch;
-
- setStatus(taskId, DRIVE_WAIT);
- EnterDeviceQueue(deviceLatch); /* lock tape device */
- clearStatus(taskId, DRIVE_WAIT);
-
- printf("\n\n");
- TLog(taskId, "RestoreDb\n");
-
- tapeInfo.structVersion = BUTM_MAJORVERSION;
- code = butm_file_Instantiate(&tapeInfo, &globalTapeConfig);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfo.error,
- "Can't initialize tape module\n");
- ERROR_EXIT(code);
- }
-
- listEntryHead = NULL;
-
- rstTapeInfo.taskId = taskId;
- rstTapeInfo.tapeSeq = 1;
- rstTapeInfo.dumpid = 0;
-
- code = readDbTape(&tapeInfo, &rstTapeInfo, autoQuery);
- if (code)
- ERROR_EXIT(code);
-
- code = restoreDbEntries(&tapeInfo, &rstTapeInfo);
- if (code)
- ERROR_EXIT(code);
-
- error_exit:
- /* Now put this dump into the database */
- /* Make a dump entry from first tape */
- listEntryPtr = listEntryHead;
- if (listEntryPtr) {
- makeDbDumpEntry(tapeEntryPtr, &dumpEntry);
- if (dumpEntry.id != 0) {
- i = bcdb_CreateDump(&dumpEntry);
- if (i) {
- if (i == BUDB_DUMPIDEXISTS)
- fprintf(stderr,
- "Dump id %d not added to database - already exists\n",
- dumpEntry.id);
- else
- TapeLog(0, taskId, i, 0,
- "Dump id %d not added to database\n",
- dumpEntry.id);
- } else {
- i = addTapesToDb(taskId);
- if (!code)
- code = i;
-
- i = bcdb_FinishDump(&dumpEntry);
- if (!code)
- code = i;
- }
- }
- freeTapeList();
- }
-
- unmountTape(taskId, &tapeInfo);
- waitDbWatcher();
-
- if (code == TC_ABORTEDBYREQUEST) {
- TLog(taskId, "RestoreDb: Aborted by request\n");
- clearStatus(taskId, ABORT_REQUEST);
- setStatus(taskId, ABORT_DONE);
- } else if (code) {
- TapeLog(0, taskId, code, 0, "RestoreDb: Finished with errors\n");
- setStatus(taskId, TASK_ERROR);
- } else {
- TLog(taskId, "RestoreDb: Finished\n");
- }
-
- LeaveDeviceQueue(deviceLatch);
- setStatus(taskId, TASK_DONE);
-
- return (code);
-}
-
-/* KeepAlive
- *
- * While dumping the database, keeps the connection alive.
- * Every 10 seconds, wake up and ask to read 0 bytes of the database.
- * This resets the database's internal timer so that it does not
- * prematuraly quit (on asking for new tapes and such).
- *
- * Use the same udbHandle as writeDbDump so we go to the same server.
- */
-int
-KeepAlive()
-{
- charListT charList;
- afs_int32 code;
- afs_int32 done;
-
- extern struct udbHandleS udbHandle;
-
- while (1) {
-#ifdef AFS_PTHREAD_ENV
- sleep(5);
-#else
- IOMGR_Sleep(5);
-#endif
- charList.charListT_val = 0;
- charList.charListT_len = 0;
- code =
- ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client,
- UF_SINGLESERVER, 0, 0, &charList, &done);
- if (code || done)
- break;
- }
-}
-
-#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);
- }
+ rstTapeInfoPtr->dumpid, taskId, tapecount);
+ if (code)
+ ERROR_EXIT(code);
+ }
+ interactiveFlag = 1;
+ tapecount++;
- code = butm_WriteEOT(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write end-of-dump on tape\n");
- ERROR_EXIT(code);
- }
+ code = butm_Mount(tapeInfoPtr, tapeName);
+ if (code) {
+ TapeLog(0, taskId, code, tapeInfoPtr->error, "Can't open tape\n");
+ goto getNewTape;
+ }
- /* Mark tape as having been written */
- tapeEntryPtr->useKBytes =
- tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
- tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
+ code = butm_ReadLabel(tapeInfoPtr, &oldTapeLabel, 1); /* will rewind the tape */
+ if (code) {
+ TapeLog(0, taskId, code, tapeInfoPtr->error,
+ "Can't read tape label\n");
+ goto getNewTape;
+ }
- unmountTape(taskId, tapeInfoPtr);
+ /* Check for name of tape and matching dump id (if applicable). */
+ if ((strcmp(oldTapeLabel.AFSName, AFStapeName) != 0)
+ || ((rstTapeInfoPtr->tapeSeq != 1)
+ && (oldTapeLabel.dumpid != rstTapeInfoPtr->dumpid))) {
+ char expTape[BU_MAXTAPELEN + 32];
+ char gotTape[BU_MAXTAPELEN + 32];
- /* Get next tape and writes its label */
- sequence++;
- code =
- GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence,
- 1, &wroteLabel);
- if (code)
- ERROR_EXIT(code);
+ TAPENAME(expTape, tapeName, rstTapeInfoPtr->dumpid);
+ TAPENAME(gotTape, oldTapeLabel.AFSName, oldTapeLabel.dumpid);
- code = butm_WriteFileBegin(tapeInfoPtr);
- if (code) {
- ErrorLog(0, taskId, code, tapeInfoPtr->error,
- "Can't write FileBegin on tape\n");
- ERROR_EXIT(code);
- }
- }
+ TLog(taskId, "Tape label expected %s, label seen %s\n", expTape,
+ gotTape);
+ goto getNewTape;
}
+
+ if (rstTapeInfoPtr->tapeSeq == 1) /* Remember this dumpId */
+ rstTapeInfoPtr->dumpid = oldTapeLabel.dumpid;
+
+ break;
+
+ getNewTape:
+ unmountTape(taskId, tapeInfoPtr);
} /*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);
- }
+ /* Initialize a tapeEntry for later inclusion into the database */
+ listEntryPtr =
+ (struct tapeEntryList *)malloc(sizeof(struct tapeEntryList));
+ if (!listEntryPtr)
+ ERROR_EXIT(TC_NOMEMORY);
+ memset(listEntryPtr, 0, sizeof(struct tapeEntryList));
- /* Mark tape as having been written */
- tapeEntryPtr->useKBytes =
- tapeInfoPtr->kBytes + (tapeInfoPtr->nBytes ? 1 : 0);
- tapeEntryPtr->flags = BUDB_TAPE_WRITTEN;
+ /* Fill in tape entry so we can save it later */
+ strcpy(tapeEntryPtr->name, TNAME(&oldTapeLabel));
+ tapeEntryPtr->dump = oldTapeLabel.dumpid;
+ tapeEntryPtr->flags = BUDB_TAPE_BEINGWRITTEN;
+ tapeEntryPtr->written = oldTapeLabel.creationTime;
+ tapeEntryPtr->expires = oldTapeLabel.expirationDate;
+ tapeEntryPtr->seq = extractTapeSeq(oldTapeLabel.AFSName);
+ tapeEntryPtr->useCount = oldTapeLabel.useCount;
+ tapeEntryPtr->useKBytes = 0;
+ tapeEntryPtr->labelpos = 0;
- error_exit:
- /* Let the KeepAlive process stop on its own */
- code =
- ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client,
- UF_END_SINGLESERVER, 0);
+ /* Thread onto end of single-linked list */
+ if (listEntryHead) {
+ endList = listEntryHead;
+ while (endList->next)
+ endList = endList->next;
+ endList->next = listEntryPtr;
+ } else
+ listEntryHead = listEntryPtr;
- if (writeBlock)
- free(writeBlock);
- if (charList.charListT_val)
- free(charList.charListT_val);
+ error_exit:
return (code);
}
+static afs_int32 nbytes = 0; /* # bytes left in buffer */
+static void
+initTapeBuffering(void)
+{
+ nbytes = 0;
+}
+
/* restoreDbEntries
* restore all the items on the tape
* tape positioned after tape label
*/
-static
-restoreDbEntries(tapeInfoPtr, rstTapeInfoPtr)
- struct butm_tapeInfo *tapeInfoPtr;
- struct rstTapeInfo *rstTapeInfoPtr;
+static int
+restoreDbEntries(struct butm_tapeInfo *tapeInfoPtr,
+ struct rstTapeInfo *rstTapeInfoPtr)
{
struct structDumpHeader netItemHeader, hostItemHeader;
afs_int32 more = 1;
return (code);
}
+/* restoreDbFromTape
+ * restore the backup database from tape.
+ */
+
+void *
+restoreDbFromTape(void *param)
+{
+ afs_uint32 taskId = (intptr_t) param;
+ afs_int32 code = 0;
+ afs_int32 i;
+ struct butm_tapeInfo tapeInfo;
+ struct rstTapeInfo rstTapeInfo;
+ struct budb_dumpEntry dumpEntry;
+
+ extern struct tapeConfig globalTapeConfig;
+ extern struct deviceSyncNode *deviceLatch;
+
+ afs_pthread_setname_self("Db restore");
+ setStatus(taskId, DRIVE_WAIT);
+ EnterDeviceQueue(deviceLatch); /* lock tape device */
+ clearStatus(taskId, DRIVE_WAIT);
+
+ printf("\n\n");
+ TLog(taskId, "RestoreDb\n");
+
+ tapeInfo.structVersion = BUTM_MAJORVERSION;
+ code = butm_file_Instantiate(&tapeInfo, &globalTapeConfig);
+ if (code) {
+ ErrorLog(0, taskId, code, tapeInfo.error,
+ "Can't initialize tape module\n");
+ ERROR_EXIT(code);
+ }
+
+ listEntryHead = NULL;
+
+ rstTapeInfo.taskId = taskId;
+ rstTapeInfo.tapeSeq = 1;
+ rstTapeInfo.dumpid = 0;
+
+ code = readDbTape(&tapeInfo, &rstTapeInfo, autoQuery);
+ if (code)
+ ERROR_EXIT(code);
+
+ code = restoreDbEntries(&tapeInfo, &rstTapeInfo);
+ if (code)
+ ERROR_EXIT(code);
+
+ error_exit:
+ /* Now put this dump into the database */
+ /* Make a dump entry from first tape */
+ listEntryPtr = listEntryHead;
+ if (listEntryPtr) {
+ makeDbDumpEntry(tapeEntryPtr, &dumpEntry);
+ if (dumpEntry.id != 0) {
+ i = bcdb_CreateDump(&dumpEntry);
+ if (i) {
+ if (i == BUDB_DUMPIDEXISTS)
+ fprintf(stderr,
+ "Dump id %d not added to database - already exists\n",
+ dumpEntry.id);
+ else
+ TapeLog(0, taskId, i, 0,
+ "Dump id %d not added to database\n",
+ dumpEntry.id);
+ } else {
+ i = addTapesToDb(taskId);
+ if (!code)
+ code = i;
+
+ i = bcdb_FinishDump(&dumpEntry);
+ if (!code)
+ code = i;
+ }
+ }
+ freeTapeList();
+ }
+
+ unmountTape(taskId, &tapeInfo);
+ waitDbWatcher();
+
+ if (code == TC_ABORTEDBYREQUEST) {
+ TLog(taskId, "RestoreDb: Aborted by request\n");
+ clearStatus(taskId, ABORT_REQUEST);
+ setStatus(taskId, ABORT_DONE);
+ } else if (code) {
+ TapeLog(0, taskId, code, 0, "RestoreDb: Finished with errors\n");
+ setStatus(taskId, TASK_ERROR);
+ } else {
+ TLog(taskId, "RestoreDb: Finished\n");
+ }
+
+ LeaveDeviceQueue(deviceLatch);
+ setStatus(taskId, TASK_DONE);
+
+ return (void *)(intptr_t)(code);
+}
+
+/* KeepAlive
+ *
+ * While dumping the database, keeps the connection alive.
+ * Every 10 seconds, wake up and ask to read 0 bytes of the database.
+ * This resets the database's internal timer so that it does not
+ * prematuraly quit (on asking for new tapes and such).
+ *
+ * Use the same udbHandle as writeDbDump so we go to the same server.
+ */
+void *
+KeepAlive(void *unused)
+{
+ charListT charList;
+ afs_int32 code;
+ afs_int32 done;
+
+ extern struct udbHandleS udbHandle;
+
+ afs_pthread_setname_self("Keep-alive");
+ while (1) {
+#ifdef AFS_PTHREAD_ENV
+ sleep(5);
+#else
+ IOMGR_Sleep(5);
+#endif
+ charList.charListT_val = 0;
+ charList.charListT_len = 0;
+ code =
+ ubik_Call_SingleServer(BUDB_DumpDB, udbHandle.uh_client,
+ UF_SINGLESERVER, 0, 0, &charList, &done);
+ if (code || done)
+ break;
+ }
+ return 0;
+}
+
+
/* restoreDbHeader
* restore special items in the header
*/
-restoreDbHeader(tapeInfo, rstTapeInfoPtr, nextHeader)
- struct butm_tapeInfo *tapeInfo;
- struct rstTapeInfo *rstTapeInfoPtr;
- struct structDumpHeader *nextHeader;
+int
+restoreDbHeader(struct butm_tapeInfo *tapeInfo,
+ struct rstTapeInfo *rstTapeInfoPtr,
+ struct structDumpHeader *nextHeader)
{
struct structDumpHeader netItemHeader;
struct DbHeader netDbHeader, hostDbHeader;
/* Add the database header to the database */
code =
- ubik_Call(BUDB_RestoreDbHeader, udbHandle.uh_client, 0,
+ ubik_BUDB_RestoreDbHeader(udbHandle.uh_client, 0,
&hostDbHeader);
if (code) {
ErrorLog(0, rstTapeInfoPtr->taskId, code, 0,
* nextHeader - ptr to structure for return value
* exit:
* nextHeader - next structure header from tape
- * notes:
+ * notes:
* upon entry, the dump structure header has been read confirming that
* a database dump tree exists on the tape
*/
-restoreDbDump(tapeInfo, rstTapeInfoPtr, nextHeader)
- struct butm_tapeInfo *tapeInfo;
- struct rstTapeInfo *rstTapeInfoPtr;
- struct structDumpHeader *nextHeader;
+int
+restoreDbDump(struct butm_tapeInfo *tapeInfo,
+ struct rstTapeInfo *rstTapeInfoPtr,
+ struct structDumpHeader *nextHeader)
{
struct budb_dumpEntry netDumpEntry, hostDumpEntry;
struct budb_tapeEntry netTapeEntry, hostTapeEntry;
struct budb_volumeEntry netVolumeEntry, hostVolumeEntry;
struct structDumpHeader netItemHeader;
- afs_int32 taskId;
int restoreThisDump = 1;
afs_int32 code = 0;
extern struct udbHandleS udbHandle;
- taskId = rstTapeInfoPtr->taskId;
-
/* read dump entry */
memset(&netDumpEntry, 0, sizeof(netDumpEntry));
code =
*/
afs_int32
-saveTextFile(taskId, textType, fileName)
- afs_int32 taskId;
- afs_int32 textType;
- char *fileName;
+saveTextFile(afs_int32 taskId, afs_int32 textType, char *fileName)
{
udbClientTextP ctPtr = 0;
afs_int32 code = 0;
* nextHeader - struct header for next item on the tape
*/
-restoreText(tapeInfo, rstTapeInfoPtr, nextHeader)
- struct butm_tapeInfo *tapeInfo;
- struct rstTapeInfo *rstTapeInfoPtr;
- struct structDumpHeader *nextHeader;
+int
+restoreText(struct butm_tapeInfo *tapeInfo,
+ struct rstTapeInfo *rstTapeInfoPtr,
+ struct structDumpHeader *nextHeader)
{
char filename[64];
afs_int32 nbytes;
/* open the text file */
sprintf(filename, "%s/bu_XXXXXX", gettmpdir());
-#if defined (HAVE_MKSTEMP)
fid = mkstemp(filename);
-#else
- fid = open(mktemp(filename), O_RDWR | O_CREAT | O_EXCL, 0600);
-#endif
if (fid < 0) {
ErrorLog(0, rstTapeInfoPtr->taskId, errno, 0,
"Can't open temporary text file: %s\n", filename);
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
- * in the buffer supplied
+ * in the buffer supplied
* entry:
* tapeInfo
* rstTapeInfoPtr - Info about the dump being restored.
* fn retn - 0, ok, n, error
*/
-getTapeData(tapeInfoPtr, rstTapeInfoPtr, buffer, requestedBytes)
- struct butm_tapeInfo *tapeInfoPtr;
- struct rstTapeInfo *rstTapeInfoPtr;
- char *buffer;
- afs_int32 requestedBytes;
+int
+getTapeData(struct butm_tapeInfo *tapeInfoPtr,
+ struct rstTapeInfo *rstTapeInfoPtr,
+ void *out, afs_int32 requestedBytes)
{
- afs_int32 taskId, transferBytes, new;
+ char *buffer = (char *) out;
+ afs_int32 taskId, transferBytes;
afs_int32 code = 0;
- afs_uint32 dumpid;
taskId = rstTapeInfoPtr->taskId;