modernize-bozo-20020821
[openafs.git] / src / bozo / fsbnodeops.c
index 6fd3bf7..74676ad 100644 (file)
@@ -1,9 +1,17 @@
 /*
- * (C) COPYRIGHT IBM CORPORATION 1988, 1988
- * LICENSED MATERIALS - PROPERTY OF IBM
+ * 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 <sys/types.h>
 #include <lwp.h>
 #include <errno.h>
 #include <fcntl.h>
 #else
 #include <sys/file.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#include <stdlib.h>
+
 #endif /* AFS_NT40_ENV */
 #include <sys/stat.h>
 #include <afs/procmgmt.h>  /* signal(), kill(), wait(), etc. */
@@ -26,6 +44,7 @@ static int fs_timeout(), fs_getstat(), fs_setstat(), fs_delete();
 static int fs_procexit(), fs_getstring(), fs_getparm(), fs_restartp();
 static int fs_hascore();
 struct bnode *fs_create();
+struct bnode *fsmr_create();
 
 static SetNeedsClock();
 static NudgeProcs();
@@ -76,20 +95,26 @@ struct fsbnode {
     char *filecmd;                 /* command to start primary file server */
     char *volcmd;                  /* command to start secondary vol server */
     char *salcmd;                  /* command to start salvager */
+    char *scancmd;                  /* command to start scanner (MR-AFS) */
     struct bnode_proc *fileProc;    /* process for file server */
     struct bnode_proc *volProc;            /* process for vol server */
     struct bnode_proc *salProc;            /* process for salvager */
-    afs_int32 lastFileStart;               /* last start for file */
-    afs_int32 lastVolStart;                /* last start for vol */
+    struct bnode_proc *scanProc;    /* process for scanner (MR-AFS) */
+    afs_int32 lastFileStart;        /* last start for file */
+    afs_int32 lastVolStart;         /* last start for vol */
+    afs_int32 lastScanStart;        /* last start for scanner (MR-AFS) */
     char fileRunning;              /* file process is running */
     char volRunning;               /* volser is running */
     char salRunning;               /* salvager is running */
+    char scanRunning;               /* scanner is running (MR_AFS) */
     char fileSDW;                  /* file shutdown wait */
     char volSDW;                   /* vol shutdown wait */
     char salSDW;                   /* waiting for the salvager to shutdown */
+    char scanSDW;                   /* scanner shutdown wait (MR_AFS) */
     char fileKillSent;             /* kill signal has been sent */
     char volKillSent;
     char salKillSent;
+    char scanKillSent;              /* kill signal has been sent (MR_AFS) */
     char needsSalvage;             /* salvage before running */
     char needsClock;               /* do we need clock ticks */
 };
@@ -100,8 +125,8 @@ struct fsbnode {
  * there may not be an active process for a bnode that dumped core at the
  * time the query is done.
  */
-static int fs_hascore(abnode)
-register struct ezbnode *abnode; {
+static int fs_hascore(register struct ezbnode *abnode)
+{
     char tbuffer[256];
 
     /* see if file server has a core file */
@@ -116,12 +141,16 @@ register struct ezbnode *abnode; {
     bnode_CoreName(abnode, "salv", tbuffer);
     if (access(tbuffer, 0) == 0) return 1;
 
+    /* see if scanner left a core file (MR-AFS) */
+    bnode_CoreName(abnode, "scan", tbuffer);
+    if (access(tbuffer, 0) == 0) return 1;
+
     /* no one left a core file */
     return 0;
 }
 
-static int fs_restartp (abnode)
-register struct fsbnode *abnode; {
+static int fs_restartp (register struct fsbnode *abnode)
+{
     struct bnode_token *tt;
     register afs_int32 code;
     struct stat tstat;
@@ -151,15 +180,30 @@ register struct fsbnode *abnode; {
     if (tstat.st_ctime > abnode->lastVolStart) code = 1;
     else code = 0;
     bnode_FreeTokens(tt);
+    if (code) return code;
+
+    if (abnode->scancmd) {                     /* Only in MR-AFS */
+        /* now do same for scancmd (MR-AFS) */
+        code = bnode_ParseLine(abnode->scancmd, &tt);
+        if (code) return 0;
+        if (!tt) return 0;
+        code = stat(tt->key, &tstat);
+        if (code) {
+            bnode_FreeTokens(tt);
+            return 0;
+       }
+        if (tstat.st_ctime > abnode->lastScanStart) code = 1;
+        else code = 0;
+        bnode_FreeTokens(tt); 
+    }
 
     return code;
 }
 
 /* set needsSalvage flag, creating file SALVAGE.<instancename> if
     we need to salvage the file system (so we can tell over panic reboots */
-static SetSalFlag(abnode, aflag)
-register struct fsbnode *abnode;
-register int aflag; {
+static int SetSalFlag(register struct fsbnode *abnode, register int aflag)
+{
     char tbuffer[AFSDIR_PATH_MAX];
     int fd;
 
@@ -177,8 +221,7 @@ register int aflag; {
 }
 
 /* set the needsSalvage flag according to the existence of the salvage file */
-static RestoreSalFlag(abnode)
-register struct fsbnode *abnode; {
+static int RestoreSalFlag(register struct fsbnode *abnode) {
     char tbuffer[AFSDIR_PATH_MAX];
 
     strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/", SALFILE, 
@@ -193,19 +236,19 @@ register struct fsbnode *abnode; {
     return 0;
 }
 
-char *copystr(a)
-register char *a; {
+char *copystr(register char *a) 
+{
     register char *b;
     b = (char *) malloc(strlen(a)+1);
     strcpy(b, a);
     return b;
 }
 
-static int fs_delete(abnode)
-struct fsbnode *abnode; {
+static int fs_delete(struct fsbnode *abnode) {
     free(abnode->filecmd);
     free(abnode->volcmd);
     free(abnode->salcmd);
+    if (abnode->scancmd) free(abnode->scancmd);
     free(abnode);
     return 0;
 }
@@ -225,15 +268,12 @@ static void AppendExecutableExtension(char *cmd)
 #endif /* AFS_NT40_ENV */
 
 
-struct bnode *fs_create(ainstance, afilecmd, avolcmd, asalcmd)
-char *ainstance;
-char *afilecmd;
-char *avolcmd;
-char *asalcmd; {
+struct bnode *fs_create(char *ainstance, char *afilecmd, char *avolcmd, char *asalcmd, char *ascancmd)
+{
     struct stat tstat;
     register struct fsbnode *te;
     char cmdname[AFSDIR_PATH_MAX];
-    char *fileCmdpath, *volCmdpath, *salCmdpath;
+    char *fileCmdpath, *volCmdpath, *salCmdpath, *scanCmdpath;
     int bailout = 0;
 
     fileCmdpath = volCmdpath = salCmdpath = NULL;
@@ -252,6 +292,13 @@ char *asalcmd; {
        bailout = 1;
     }
 
+    if (ascancmd && strlen(ascancmd)) {
+       if (ConstructLocalBinPath(ascancmd, &scanCmdpath)) {
+            bozo_Log("BNODE: command path invalid '%s'\n", ascancmd);
+            bailout = 1;
+       }
+    }
+
     if (!bailout) {
        sscanf(fileCmdpath, "%s", cmdname);
 #ifdef AFS_NT40_ENV
@@ -279,19 +326,38 @@ char *asalcmd; {
            bozo_Log("BNODE: salvager binary '%s' not found\n", cmdname);
            bailout = 1;
        }
+
+        if (ascancmd && strlen(ascancmd)) {
+           sscanf(scanCmdpath, "%s", cmdname);
+#ifdef AFS_NT40_ENV
+           AppendExecutableExtension(cmdname);
+#endif
+           if (stat(cmdname, &tstat)) {
+               bozo_Log("BNODE: scanner binary '%s' not found\n", cmdname);
+               bailout = 1;
+           }
+       }
     }
 
     if (bailout) {
        free(fileCmdpath); free(volCmdpath); free(salCmdpath);
-       return (struct bnode *)0;
+       return NULL;
     }
 
     te = (struct fsbnode *) malloc(sizeof(struct fsbnode));
-    bzero(te, sizeof(struct fsbnode));
+    memset(te, 0, sizeof(struct fsbnode));
     te->filecmd = fileCmdpath;
     te->volcmd = volCmdpath;
     te->salcmd = salCmdpath;
-    bnode_InitBnode(te, &fsbnode_ops, ainstance);
+    if (ascancmd && strlen(ascancmd))
+       te->scancmd = scanCmdpath;
+    else 
+       te->scancmd = NULL;
+    if (bnode_InitBnode(te, &fsbnode_ops, ainstance) != 0) {
+       free(te);
+       free(fileCmdpath); free(volCmdpath); free(salCmdpath);
+       return NULL;
+    }
     bnode_SetTimeout(te, POLLTIME);    /* ask for timeout activations every 10 seconds */
     RestoreSalFlag(te);                /* restore needsSalvage flag based on file's existence */
     SetNeedsClock(te);         /* compute needsClock field */
@@ -299,8 +365,7 @@ char *asalcmd; {
 }
 
 /* called to SIGKILL a process if it doesn't terminate normally */
-static int fs_timeout(abnode)
-struct fsbnode *abnode; {
+static int fs_timeout(struct fsbnode *abnode) {
     register afs_int32 now;
 
     now = FT_ApproxTime();
@@ -329,32 +394,40 @@ struct fsbnode *abnode; {
                     FSSDTIME);
        }
     }
+    if (abnode->scanSDW) {
+        if (!abnode->scanKillSent && now - abnode->timeSDStarted > SDTIME) {
+            bnode_StopProc(abnode->scanProc, SIGKILL);
+            abnode->scanKillSent = 1;
+            bozo_Log("bos shutdown: scanner failed to shutdown within %d seconds\n",
+                     SDTIME);
+        }
+    }
     SetNeedsClock(abnode);
+    return 0;
 }
 
-static int fs_getstat(abnode, astatus)
-struct fsbnode *abnode;
-afs_int32 *astatus; {
+static int fs_getstat(struct fsbnode *abnode, afs_int32 *astatus) 
+{
     register afs_int32 temp;
-    if (abnode->volSDW || abnode->fileSDW || abnode->salSDW) temp = BSTAT_SHUTTINGDOWN;
+    if (abnode->volSDW || abnode->fileSDW || abnode->salSDW || abnode->scanSDW)
+       temp = BSTAT_SHUTTINGDOWN;
     else if (abnode->salRunning) temp = BSTAT_NORMAL;
-    else if (abnode->volRunning && abnode->fileRunning) temp = BSTAT_NORMAL;
-    else if (!abnode->salRunning && !abnode->volRunning && !abnode->fileRunning)
-       temp = BSTAT_SHUTDOWN;
+    else if (abnode->volRunning && abnode->fileRunning && (!abnode->scancmd || 
+       abnode->scanRunning)) temp = BSTAT_NORMAL;
+    else if (!abnode->salRunning && !abnode->volRunning && !abnode->fileRunning
+        && !abnode->scanRunning) temp = BSTAT_SHUTDOWN;
     else temp = BSTAT_STARTINGUP;
     *astatus = temp;
     return 0;
 }
 
-static int fs_setstat(abnode, astatus)
-register struct fsbnode *abnode;
-afs_int32 astatus; {
+static int fs_setstat(register struct fsbnode *abnode, afs_int32 astatus)
+{
     return NudgeProcs(abnode);
 }
 
-static int fs_procexit(abnode, aproc)
-struct fsbnode *abnode;
-struct bnode_proc *aproc; {
+static int fs_procexit(struct fsbnode *abnode, struct bnode_proc *aproc) 
+{
     /* process has exited */
 
     if (aproc == abnode->volProc) {
@@ -386,17 +459,25 @@ struct bnode_proc *aproc; {
        abnode->salSDW = 0;
        abnode->salKillSent = 0;
     }
+    else if (aproc == abnode->scanProc) {
+        abnode->scanProc = 0;
+        abnode->scanRunning = 0;
+        abnode->scanSDW = 0;
+        abnode->scanKillSent = 0;
+    }
 
     /* now restart anyone who needs to restart */
     return NudgeProcs(abnode);
 }
 
 /* make sure we're periodically checking the state if we need to */
-static SetNeedsClock(ab)
-register struct fsbnode *ab; {
-    if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning)
+static int SetNeedsClock(register struct fsbnode *ab)
+{
+    if (ab->b.goal == 1 && ab->fileRunning && ab->volRunning
+       && (!ab->scancmd || ab->scanRunning))
        ab->needsClock = 0; /* running normally */
-    else if (ab->b.goal == 0 && !ab->fileRunning && !ab->volRunning && !ab->salRunning)
+    else if (ab->b.goal == 0 && !ab->fileRunning && !ab->volRunning 
+            && !ab->salRunning && !ab->scanRunning)
        ab->needsClock = 0; /* halted normally */
     else ab->needsClock        = 1;    /* other */
     if (ab->needsClock && !bnode_PendingTimeout(ab))
@@ -404,8 +485,8 @@ register struct fsbnode *ab; {
     if (!ab->needsClock) bnode_SetTimeout(ab, 0);
 }
 
-static NudgeProcs(abnode)
-register struct fsbnode *abnode; {
+static int NudgeProcs(register struct fsbnode *abnode)
+{
     struct bnode_proc *tp;   /* not register */
     register afs_int32 code;
     afs_int32 now;
@@ -433,6 +514,16 @@ register struct fsbnode *abnode; {
                    abnode->volRunning = 1;
                }
            }
+           if (abnode->scancmd) {
+               if (!abnode->scanRunning) {
+                   abnode->lastScanStart = FT_ApproxTime();
+                   code = bnode_NewProc(abnode, abnode->scancmd, "scanner", &tp);
+                   if (code == 0) {
+                       abnode->scanProc = tp;
+                       abnode->scanRunning = 1;
+                   }
+               }
+           }    
        }
        else {  /* file is not running */
            /* see how to start */
@@ -455,6 +546,15 @@ register struct fsbnode *abnode; {
                        abnode->volRunning = 1;
                    }
                }
+               if (abnode->scancmd && !abnode->scanRunning) {
+                    abnode->lastScanStart = FT_ApproxTime();
+                    code = bnode_NewProc(abnode, abnode->scancmd, "scanner",
+                                         &tp);
+                    if (code == 0) {
+                        abnode->scanProc = tp;
+                        abnode->scanRunning = 1;
+                    }
+                }
            }
            else {  /* needs to be salvaged */
                /* make sure file server and volser are gone */
@@ -468,7 +568,13 @@ register struct fsbnode *abnode; {
                    if (!abnode->fileSDW) abnode->timeSDStarted = now;
                    abnode->fileSDW = 1;
                }
-               if (abnode->volRunning || abnode->fileRunning) return 0;
+                if (abnode->scanRunning) {
+                    bnode_StopProc(abnode->scanProc, SIGTERM);
+                    if (!abnode->scanSDW) abnode->timeSDStarted = now;
+                    abnode->scanSDW = 1;
+                }
+               if (abnode->volRunning || abnode->fileRunning 
+                   || abnode->scanRunning) return 0;
                /* otherwise, it is safe to start salvager */
                if (!abnode->salRunning) {
                    code = bnode_NewProc(abnode, abnode->salcmd, "salv", &tp);
@@ -497,20 +603,34 @@ register struct fsbnode *abnode; {
            abnode->volSDW = 1;
            abnode->timeSDStarted = now;
        }
+        if (abnode->scanRunning && !abnode->scanSDW) {
+            bnode_StopProc(abnode->scanProc, SIGTERM);
+            abnode->scanSDW = 1;
+            abnode->timeSDStarted = now;
+        }
     }
     SetNeedsClock(abnode);
     return 0;
 }
 
-static int fs_getstring(abnode, abuffer, alen)
-struct fsbnode *abnode;
-char *abuffer;
-afs_int32 alen;{
+static int fs_getstring(struct fsbnode *abnode, char *abuffer, afs_int32 alen)
+{
     if (alen < 40) return -1;
     if (abnode->b.goal == 1) {
        if (abnode->fileRunning) {
            if (abnode->fileSDW) strcpy(abuffer, "file server shutting down");
-           else if (!abnode->volRunning) strcpy(abuffer, "file server up; volser down");
+           else if (abnode->scancmd) {
+                if (!abnode->volRunning && !abnode->scanRunning)
+                    strcpy(abuffer, "file server up; volser and scanner down");
+               else if (abnode->volRunning && !abnode->scanRunning)
+                    strcpy(abuffer, "file server up; volser up; scanner down");
+               else if (!abnode->volRunning && abnode->scanRunning)
+                    strcpy(abuffer, "file server up; volser down; scanner up");
+
+               else strcpy(abuffer, "file server running");
+           } 
+           else if (!abnode->volRunning) 
+               strcpy(abuffer, "file server up; volser down");
            else strcpy(abuffer, "file server running");
        }
        else if (abnode->salRunning) {
@@ -520,7 +640,7 @@ afs_int32 alen;{
     }
     else {
        /* shutting down */
-       if (abnode->fileRunning || abnode->volRunning) {
+       if (abnode->fileRunning || abnode->volRunning || abnode->scanRunning) {
            strcpy(abuffer, "file server shutting down");
        }
        else if (abnode->salRunning)
@@ -530,17 +650,17 @@ afs_int32 alen;{
     return 0;
 }
 
-static fs_getparm(abnode, aindex, abuffer, alen)
-struct fsbnode *abnode;
-afs_int32 aindex;
-char *abuffer;
-afs_int32  alen; {
+static int fs_getparm(struct fsbnode *abnode, afs_int32 aindex, char *abuffer,
+                 afs_int32 alen)
+{
     if (aindex == 0)
        strcpy(abuffer, abnode->filecmd);
     else if (aindex == 1)
        strcpy(abuffer, abnode->volcmd);
     else if (aindex == 2)
        strcpy(abuffer, abnode->salcmd);
+    else if (aindex == 3 && abnode->scancmd)
+       strcpy(abuffer, abnode->scancmd);
     else
        return BZDOM;
     return 0;