butc: Catch failures to start keep alive thread
[openafs.git] / src / butc / tcudbprocs.c
index cf677a0..322c617 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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>
 
+#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 <afs/opr.h>
 #include <rx/rx.h>
 #include <afs/afsint.h>
-#include <stdio.h>
-#include <string.h>
-#include <afs/procmgmt.h>
-#include <afs/assert.h>
 #include <afs/prs_fs.h>
-#include <fcntl.h>
 #include <afs/nfs.h>
 #include <lwp.h>
 #include <lock.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 */
 extern int dump_namecheck;
 extern int autoQuery;
 
-static void initTapeBuffering();
-static writeDbDump();
-static restoreDbEntries();
+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;
 
@@ -101,28 +115,20 @@ struct budb_dumpEntry lastDump;   /* the last dump of this volset */
  *      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);
@@ -176,7 +182,7 @@ GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence, queryFlag,
                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).
             */
@@ -185,7 +191,7 @@ GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence, queryFlag,
                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");
@@ -226,12 +232,12 @@ GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence, queryFlag,
            }
 
            /* 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");
@@ -265,11 +271,9 @@ GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence, queryFlag,
        *wroteLabel = 1;
 
        /* Initialize a tapeEntry for later inclusion into the database */
-       listEntryPtr =
-           (struct tapeEntryList *)malloc(sizeof(struct tapeEntryList));
+       listEntryPtr = calloc(1, sizeof(struct tapeEntryList));
        if (!listEntryPtr)
            ERROR_EXIT(TC_NOMEMORY);
-       memset(listEntryPtr, 0, sizeof(struct tapeEntryList));
 
        /* Remember dumpid so we can delete it later */
        if ((oldTapeLabel.structVersion >= TAPE_VERSION_3)
@@ -306,7 +310,7 @@ GetDBTape(taskId, expires, tapeInfoPtr, dumpid, sequence, queryFlag,
  */
 
 afs_int32
-freeTapeList()
+freeTapeList(void)
 {
     struct tapeEntryList *next;
 
@@ -322,13 +326,12 @@ freeTapeList()
 }
 
 /* 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;
@@ -376,12 +379,9 @@ addTapesToDb(taskId)
  *     the blocksize on writes
  */
 
-static
-writeDbDump(tapeInfoPtr, taskId, expires, dumpid)
-     struct butm_tapeInfo *tapeInfoPtr;
-     afs_uint32 taskId;
-     Date expires;
-     afs_uint32 dumpid;
+static int
+writeDbDump(struct butm_tapeInfo *tapeInfoPtr, afs_uint32 taskId,
+           Date expires, afs_uint32 dumpid)
 {
     afs_int32 blockSize;
     afs_int32 writeBufNbytes = 0;
@@ -412,8 +412,10 @@ writeDbDump(tapeInfoPtr, taskId, expires, dumpid)
     extern struct tapeConfig globalTapeConfig;
     extern struct udbHandleS udbHandle;
 
+    charList.charListT_val = 0;
+    charList.charListT_len = 0;
     blockSize = BUTM_BLKSIZE;
-    writeBlock = (char *)malloc(BUTM_BLOCKSIZE);
+    writeBlock = malloc(BUTM_BLOCKSIZE);
     if (!writeBlock)
        ERROR_EXIT(TC_NOMEMORY);
 
@@ -421,12 +423,12 @@ writeDbDump(tapeInfoPtr, taskId, expires, dumpid)
     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 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). 
+     * 3 EOF * markers).
      */
     tc_EndMargin = (16384 + 3 * globalTapeConfig.fileMarkSize) * 2;
     tc_KEndMargin = tc_EndMargin / 1024;
@@ -442,8 +444,6 @@ writeDbDump(tapeInfoPtr, taskId, expires, dumpid)
     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 */
@@ -490,10 +490,14 @@ writeDbDump(tapeInfoPtr, taskId, expires, dumpid)
                AFS_SIGSET_RESTORE();
 #else
                code =
-                   LWP_CreateProcess(KeepAlive, 16384, 1, (void *)NULL,
+                   LWP_CreateProcess(KeepAlive, 16384, 1, NULL,
                                      "Keep-alive process", &alivePid);
 #endif
-               /* XXX should we check code here ??? XXX */
+               if (code) {
+                   ErrorLog(0, taskId, code, 0,
+                            "Failed to create keep alive process\n");
+                   ERROR_EXIT(code);
+               }
            }
            firstcall = 0;
 
@@ -625,7 +629,7 @@ void *
 saveDbToTape(void *param)
 {
     struct saveDbIf *saveDbIfPtr = (struct saveDbIf *)param;
-    afs_int32 code = 0;
+    afs_int32 code;
     afs_int32 i;
     int wroteLabel;
     afs_uint32 taskId;
@@ -637,8 +641,10 @@ saveDbToTape(void *param)
     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 */
@@ -681,7 +687,7 @@ saveDbToTape(void *param)
                  &wroteLabel);
 
     /*
-     * If did not write the label, remove created dump 
+     * 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) {
@@ -742,23 +748,17 @@ saveDbToTape(void *param)
 
     free(saveDbIfPtr);
     LeaveDeviceQueue(deviceLatch);
-    return (void *)(code);
+    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));
 
@@ -788,10 +788,8 @@ makeDbDumpEntry(tapeEntPtr, dumpEntryPtr)
  */
 
 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;
@@ -875,11 +873,9 @@ readDbTape(tapeInfoPtr, rstTapeInfoPtr, query)
 
 
     /* Initialize a tapeEntry for later inclusion into the database */
-    listEntryPtr =
-       (struct tapeEntryList *)malloc(sizeof(struct tapeEntryList));
+    listEntryPtr = calloc(1, 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));
@@ -907,7 +903,7 @@ readDbTape(tapeInfoPtr, rstTapeInfoPtr, query)
 
 static afs_int32 nbytes = 0;   /* # bytes left in buffer */
 static void
-initTapeBuffering()
+initTapeBuffering(void)
 {
     nbytes = 0;
 }
@@ -919,10 +915,9 @@ initTapeBuffering()
  *     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;
@@ -1018,7 +1013,7 @@ restoreDbEntries(tapeInfoPtr, rstTapeInfoPtr)
 void *
 restoreDbFromTape(void *param)
 {
-    afs_uint32 taskId = (afs_uint32) param;
+    afs_uint32 taskId = (intptr_t) param;
     afs_int32 code = 0;
     afs_int32 i;
     struct butm_tapeInfo tapeInfo;
@@ -1028,6 +1023,7 @@ restoreDbFromTape(void *param)
     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);
@@ -1104,16 +1100,16 @@ restoreDbFromTape(void *param)
     LeaveDeviceQueue(deviceLatch);
     setStatus(taskId, TASK_DONE);
 
-    return (void *)(code);
+    return (void *)(intptr_t)(code);
 }
 
 /* KeepAlive
- * 
- *      While dumping the database, keeps the connection alive.  
+ *
+ *      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 
+ *      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 *
@@ -1125,6 +1121,7 @@ KeepAlive(void *unused)
 
     extern struct udbHandleS udbHandle;
 
+    afs_pthread_setname_self("Keep-alive");
     while (1) {
 #ifdef AFS_PTHREAD_ENV
        sleep(5);
@@ -1147,10 +1144,10 @@ KeepAlive(void *unused)
  *     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;
@@ -1198,28 +1195,25 @@ restoreDbHeader(tapeInfo, rstTapeInfoPtr, nextHeader)
  *     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 =
@@ -1348,20 +1342,16 @@ restoreDbDump(tapeInfo, rstTapeInfoPtr, nextHeader)
  */
 
 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;
     int tlock = 0;
 
-    ctPtr = (udbClientTextP) malloc(sizeof(*ctPtr));
+    ctPtr = calloc(1, sizeof(*ctPtr));
     if (!ctPtr)
        ERROR_EXIT(TC_NOMEMORY);
 
-    memset(ctPtr, 0, sizeof(*ctPtr));
     ctPtr->textType = textType;
 
     /* lock the text in the database */
@@ -1405,10 +1395,10 @@ saveTextFile(taskId, textType, fileName)
  *     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;
@@ -1422,7 +1412,7 @@ restoreText(tapeInfo, rstTapeInfoPtr, nextHeader)
     udbClientTextP ctPtr = 0;
     afs_int32 textType;
 
-    ctPtr = (udbClientTextP) malloc(sizeof(*ctPtr));
+    ctPtr = malloc(sizeof(*ctPtr));
     if (!ctPtr)
        ERROR_EXIT(TC_NOMEMORY);
 
@@ -1449,11 +1439,7 @@ restoreText(tapeInfo, rstTapeInfoPtr, nextHeader)
 
     /* 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);
@@ -1462,7 +1448,7 @@ restoreText(tapeInfo, rstTapeInfoPtr, nextHeader)
 
     /* allocate buffer for text */
     readBlockSize = BUTM_BLKSIZE;
-    readBuffer = (char *)malloc(readBlockSize);
+    readBuffer = malloc(readBlockSize);
     if (!readBuffer)
        ERROR_EXIT(TC_NOMEMORY);
 
@@ -1526,7 +1512,7 @@ static char *tapeReadBufferPtr = 0;       /* position in buffer */
 
 /* 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.
@@ -1536,15 +1522,14 @@ static char *tapeReadBufferPtr = 0;     /* position in buffer */
  *     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;
 
@@ -1552,7 +1537,7 @@ getTapeData(tapeInfoPtr, rstTapeInfoPtr, buffer, requestedBytes)
        ERROR_EXIT(TC_ABORTEDBYREQUEST);
 
     if (!tapeReadBuffer) {
-       tapeReadBuffer = (char *)malloc(BUTM_BLOCKSIZE);
+       tapeReadBuffer = malloc(BUTM_BLOCKSIZE);
        if (!tapeReadBuffer)
            ERROR_EXIT(TC_NOMEMORY);
     }