/*
- * (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. */
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();
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 */
};
* 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 */
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;
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;
}
/* 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,
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;
}
#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;
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
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 */
}
/* 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();
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) {
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))
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;
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 */
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 */
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);
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) {
}
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)
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;