bozo: avoid canceling the sigkill timer for hung processes
[openafs.git] / src / bozo / fsbnodeops.c
index 14a233a..e93a6d7 100644 (file)
@@ -21,6 +21,7 @@
 #include "bnode.h"
 #include "bosprototypes.h"
 
+extern char *DoPidFiles;
 static int emergency = 0;
 
 /* if this file exists, then we have to salvage the file system */
@@ -95,6 +96,7 @@ static int fs_delete(struct bnode *abnode);
 static int fs_timeout(struct bnode *abnode);
 static int fs_getstat(struct bnode *abnode, afs_int32 * astatus);
 static int fs_setstat(struct bnode *abnode, afs_int32 astatus);
+static int fs_procstarted(struct bnode *abnode, struct bnode_proc *aproc);
 static int fs_procexit(struct bnode *abnode, struct bnode_proc *aproc);
 static int fs_getstring(struct bnode *abnode, char *abuffer, afs_int32 alen);
 static int fs_getparm(struct bnode *abnode, afs_int32 aindex,
@@ -124,6 +126,7 @@ struct bnode_ops fsbnode_ops = {
     fs_getparm,
     fs_restartp,
     fs_hascore,
+    fs_procstarted,
 };
 
 /* demand attach fs bnode ops */
@@ -138,6 +141,7 @@ struct bnode_ops dafsbnode_ops = {
     dafs_getparm,
     fs_restartp,
     fs_hascore,
+    fs_procstarted,
 };
 
 /* Quick inline function to safely convert a fsbnode to a bnode without
@@ -287,7 +291,7 @@ SetSalFlag(struct fsbnode *abnode, int aflag)
     if (abnode->salsrvcmd == NULL) {
        abnode->needsSalvage = aflag;
        strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
-                  SALFILE, abnode->b.name, NULL);
+                  SALFILE, abnode->b.name, (char *)NULL);
        if (aflag) {
            fd = open(tbuffer, O_CREAT | O_TRUNC | O_RDWR, 0666);
            close(fd);
@@ -309,7 +313,7 @@ RestoreSalFlag(struct fsbnode *abnode)
        abnode->needsSalvage = 0;
     } else {
        strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
-                  SALFILE, abnode->b.name, NULL);
+                  SALFILE, abnode->b.name, (char *)NULL);
        if (access(tbuffer, 0) == 0) {
            /* file exists, so need to salvage */
            abnode->needsSalvage = 1;
@@ -320,15 +324,6 @@ RestoreSalFlag(struct fsbnode *abnode)
     return 0;
 }
 
-char *
-copystr(char *a)
-{
-    char *b;
-    b = (char *)malloc(strlen(a) + 1);
-    strcpy(b, a);
-    return b;
-}
-
 static int
 fs_delete(struct bnode *bn)
 {
@@ -435,12 +430,11 @@ fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
        }
     }
 
-    te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
+    te = calloc(1, sizeof(struct fsbnode));
     if (te == NULL) {
        bailout = 1;
        goto done;
     }
-    memset(te, 0, sizeof(struct fsbnode));
     te->filecmd = fileCmdpath;
     te->volcmd = volCmdpath;
     te->salsrvcmd = NULL;
@@ -454,7 +448,7 @@ fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd,
        goto done;
     }
     bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
-               /* ask for timeout activations every 10 seconds */
+               /* ask for timeout activations every 20 seconds */
     RestoreSalFlag(te);                /* restore needsSalvage flag based on file's existence */
     SetNeedsClock(te);         /* compute needsClock field */
 
@@ -564,12 +558,11 @@ dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
        }
     }
 
-    te = (struct fsbnode *)malloc(sizeof(struct fsbnode));
+    te = calloc(1, sizeof(struct fsbnode));
     if (te == NULL) {
        bailout = 1;
        goto done;
     }
-    memset(te, 0, sizeof(struct fsbnode));
     te->filecmd = fileCmdpath;
     te->volcmd = volCmdpath;
     te->salsrvcmd = salsrvCmdpath;
@@ -583,7 +576,7 @@ dafs_create(char *ainstance, char *afilecmd, char *avolcmd,
        goto done;
     }
     bnode_SetTimeout(fsbnode2bnode(te), POLLTIME);
-               /* ask for timeout activations every 10 seconds */
+               /* ask for timeout activations every 20 seconds */
     RestoreSalFlag(te);                /* restore needsSalvage flag based on file's existence */
     SetNeedsClock(te);         /* compute needsClock field */
 
@@ -662,6 +655,16 @@ fs_timeout(struct bnode *bn)
                 SDTIME);
        }
     }
+
+    if ((abnode->b.flags & BNODE_ERRORSTOP) && !abnode->salRunning
+       && !abnode->volRunning && !abnode->fileRunning && !abnode->scanRunning
+       && !abnode->salsrvRunning) {
+       bnode_SetStat(bn, BSTAT_NORMAL);
+    }
+    else {
+       bnode_ResetErrorCount(bn);
+    }
+
     SetNeedsClock(abnode);
     return 0;
 }
@@ -698,12 +701,27 @@ fs_setstat(struct bnode *abnode, afs_int32 astatus)
 }
 
 static int
+fs_procstarted(struct bnode *bn, struct bnode_proc *aproc)
+{
+    int code = 0;
+
+    if (DoPidFiles) {
+       code = bozo_CreatePidFile(bn->name, aproc->coreName, aproc->pid);
+    }
+    return code;
+}
+
+static int
 fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
 {
    struct fsbnode *abnode = (struct fsbnode *)bn;
 
     /* process has exited */
 
+    if (DoPidFiles) {
+       bozo_DeletePidFile(bn->name, aproc->coreName);
+    }
+
     if (aproc == abnode->volProc) {
        abnode->volProc = 0;
        abnode->volRunning = 0;
@@ -751,17 +769,38 @@ fs_procexit(struct bnode *bn, struct bnode_proc *aproc)
 static void
 SetNeedsClock(struct fsbnode *ab)
 {
-    if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
+    afs_int32 timeout = POLLTIME;
+
+    if ((ab->fileSDW && !ab->fileKillSent) || (ab->volSDW && !ab->volKillSent)
+       || (ab->scanSDW && !ab->scanKillSent) || (ab->salSDW && !ab->salKillSent)
+       || (ab->salsrvSDW && !ab->salsrvKillSent)) {
+       /* SIGQUIT sent, will send SIGKILL if process does not exit */
+       ab->needsClock = 1;
+    } else if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
        && (!ab->scancmd || ab->scanRunning)
-       && (!ab->salsrvcmd || ab->salsrvRunning))
-       ab->needsClock = 0;     /* running normally */
-    else if (ab->b.goal == 0 && !ab->fileRunning && !ab->volRunning
-            && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning)
-       ab->needsClock = 0;     /* halted normally */
-    else
+       && (!ab->salsrvcmd || ab->salsrvRunning)) {
+       if (ab->b.errorStopCount) {
+           /* reset error count after running for a bit */
+           ab->needsClock = 1;
+       } else {
+           ab->needsClock = 0; /* running normally */
+       }
+    } else if ((ab->b.goal == 0) && !ab->fileRunning && !ab->volRunning
+              && !ab->salRunning && !ab->scanRunning && !ab->salsrvRunning) {
+       if (ab->b.flags & BNODE_ERRORSTOP && ab->b.errorStopDelay) {
+           bozo_Log("%s will retry start in %d seconds\n", ab->b.name,
+                    ab->b.errorStopDelay);
+           ab->needsClock = 1; /* halted for errors, retry later */
+           timeout = ab->b.errorStopDelay;
+       } else {
+           ab->needsClock = 0; /* halted normally */
+       }
+    } else
        ab->needsClock = 1;     /* other */
-    if (ab->needsClock && !bnode_PendingTimeout(fsbnode2bnode(ab)))
-       bnode_SetTimeout(fsbnode2bnode(ab), POLLTIME);
+
+    if (ab->needsClock && (!bnode_PendingTimeout(fsbnode2bnode(ab))
+                          || ab->b.period != timeout))
+       bnode_SetTimeout(fsbnode2bnode(ab), timeout);
     if (!ab->needsClock)
        bnode_SetTimeout(fsbnode2bnode(ab), 0);
 }