Example #1
0
/* wait for all bnodes to stabilize */
int
bnode_WaitAll(void)
{
    struct bnode *tb;
    afs_int32 code;
    afs_int32 stat;

  retry:
    for (tb = allBnodes; tb; tb = tb->next) {
	bnode_Hold(tb);
	code = BOP_GETSTAT(tb, &stat);
	if (code) {
	    bnode_Release(tb);
	    return code;
	}
	if (stat != tb->goal) {
	    tb->flags |= BNODE_WAIT;
	    LWP_WaitProcess(tb);
	    bnode_Release(tb);
	    goto retry;
	}
	bnode_Release(tb);
    }
    return 0;
}
Example #2
0
/* wait until bnode status is correct */
int
bnode_WaitStatus(struct bnode *abnode, int astatus)
{
    afs_int32 code;
    afs_int32 stat;

    bnode_Hold(abnode);
    while (1) {
	/* get the status */
	code = BOP_GETSTAT(abnode, &stat);
	if (code)
	    return code;

	/* otherwise, check if we're done */
	if (stat == astatus) {
	    bnode_Release(abnode);
	    return 0;		/* done */
	}
	if (astatus != abnode->goal) {
	    bnode_Release(abnode);
	    return -1;		/* no longer our goal, don't keep waiting */
	}
	/* otherwise, block */
	abnode->flags |= BNODE_WAIT;
	LWP_WaitProcess(abnode);
    }
}
Example #3
0
afs_int32
SBOZO_GetStatus(struct rx_call *acall, char *ainstance, afs_int32 *astat,
		char **astatDescr)
{
    struct bnode *tb;
    afs_int32 code;

    tb = bnode_FindInstance(ainstance);
    if (!tb) {
	code = BZNOENT;
	goto fail;
    }

    bnode_Hold(tb);
    code = bnode_GetStat(tb, astat);
    if (code) {
	bnode_Release(tb);
	goto fail;
    }

    *astatDescr = malloc(BOZO_BSSIZE);
    code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
    bnode_Release(tb);
    if (code)
	(*astatDescr)[0] = 0;	/* null string means no further info */
    return 0;

  fail:
    *astatDescr = malloc(1);
    **astatDescr = 0;
    return code;
}
Example #4
0
int
bnode_Delete(struct bnode *abnode)
{
    afs_int32 code;
    struct bnode **lb, *ub;
    afs_int32 temp;

    if (abnode->refCount != 0) {
	abnode->flags |= BNODE_DELETE;
	return 0;
    }

    /* make sure the bnode is idle before zapping */
    bnode_Hold(abnode);
    code = BOP_GETSTAT(abnode, &temp);
    bnode_Release(abnode);
    if (code)
	return code;
    if (temp != BSTAT_SHUTDOWN)
	return BZBUSY;

    /* all clear to zap */
    for (lb = &allBnodes, ub = *lb; ub; lb = &ub->next, ub = *lb) {
	if (ub == abnode) {
	    /* unthread it from the list */
	    *lb = ub->next;
	    break;
	}
    }
    free(abnode->name);		/* do this first, since bnode fields may be bad after BOP_DELETE */
    code = BOP_DELETE(abnode);	/* don't play games like holding over this one */
    WriteBozoFile(0);
    return code;
}
Example #5
0
afs_int32
SBOZO_Restart(struct rx_call *acall, char *ainstance)
{
    struct bnode *tb;
    afs_int32 code;
    char caller[MAXKTCNAMELEN];

    if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
	code = BZACCESS;
	goto fail;
    }
    if (DoLogging)
	bozo_Log("%s is executing Restart '%s'\n", caller, ainstance);

    tb = bnode_FindInstance(ainstance);
    if (!tb) {
	code = BZNOENT;
	goto fail;
    }

    bnode_Hold(tb);
    bnode_SetStat(tb, BSTAT_SHUTDOWN);
    code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN);	/* this can fail */
    bnode_ResetErrorCount(tb);
    bnode_SetStat(tb, BSTAT_NORMAL);
    bnode_Release(tb);

  fail:
    osi_auditU(acall, BOS_RestartEvent, code, AUD_STR, ainstance, AUD_END);
    return code;
}
Example #6
0
afs_int32
SBOZO_GetInstanceParm(struct rx_call *acall,
		      char *ainstance,
		      afs_int32 anum,
		      char **aparm)
{
    struct bnode *tb;
    char *tp;
    afs_int32 code;

    tp = malloc(BOZO_BSSIZE);
    *aparm = tp;
    *tp = 0;			/* null-terminate string in error case */
    tb = bnode_FindInstance(ainstance);
    if (!tb)
	return BZNOENT;
    bnode_Hold(tb);
    if (anum == 999) {
	if (tb->notifier) {
	    memcpy(tp, tb->notifier, strlen(tb->notifier) + 1);
	    code = 0;
	} else
	    code = BZNOENT;	/* XXXXX */
    } else
	code = bnode_GetParm(tb, anum, tp, BOZO_BSSIZE);
    bnode_Release(tb);

    /* Not Currently Audited */
    return code;
}
Example #7
0
afs_int32
SBOZO_SetStatus(struct rx_call *acall, char *ainstance, afs_int32 astatus)
{
    struct bnode *tb;
    afs_int32 code;
    char caller[MAXKTCNAMELEN];

    if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
	code = BZACCESS;
	goto fail;
    }
    if (DoLogging)
	bozo_Log("%s is executing SetStatus '%s' (status = %d)\n", caller,
		 ainstance, astatus);

    tb = bnode_FindInstance(ainstance);
    if (!tb) {
	code = BZNOENT;
	goto fail;
    }
    bnode_Hold(tb);
    bnode_SetFileGoal(tb, astatus);
    code = bnode_SetStat(tb, astatus);
    bnode_Release(tb);

  fail:
    osi_auditU(acall, BOS_SetStatusEvent, code, AUD_STR, ainstance, AUD_END);
    return code;
}
Example #8
0
static int
sdproc(struct bnode *abnode, void *arock)
{
    bnode_Hold(abnode);
    bnode_SetStat(abnode, BSTAT_SHUTDOWN);
    bnode_Release(abnode);
    return 0;
}
Example #9
0
static int
swproc(struct bnode *abnode, void *arock)
{
    if (abnode->goal == BSTAT_NORMAL)
	return 0;		/* this one's not shutting down */
    /* otherwise, we are shutting down */
    bnode_Hold(abnode);
    bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
    bnode_Release(abnode);
    return 0;			/* don't stop apply function early, no matter what */
}
Example #10
0
static int
stproc(struct bnode *abnode, void *arock)
{
    if (abnode->fileGoal == BSTAT_SHUTDOWN)
	return 0;		/* don't do these guys */

    bnode_Hold(abnode);
    bnode_SetStat(abnode, BSTAT_NORMAL);
    bnode_Release(abnode);
    return 0;
}
Example #11
0
static int
bdrestart(struct bnode *abnode, void *arock)
{
    afs_int32 code;

    if (abnode->fileGoal != BSTAT_NORMAL || abnode->goal != BSTAT_NORMAL)
	return 0;		/* don't restart stopped bnodes */
    bnode_Hold(abnode);
    code = bnode_RestartP(abnode);
    if (code) {
	/* restart the dude */
	bnode_SetStat(abnode, BSTAT_SHUTDOWN);
	bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
	bnode_SetStat(abnode, BSTAT_NORMAL);
    }
    bnode_Release(abnode);
    return 0;			/* keep trying all bnodes */
}
Example #12
0
/* bnode lwp executes this code repeatedly */
static void *
bproc(void *unused)
{
    afs_int32 code;
    struct bnode *tb;
    afs_int32 temp;
    struct bnode_proc *tp;
    struct bnode *nb;
    int options;		/* must not be register */
    struct timeval tv;
    int setAny;
    int status;

    while (1) {
	/* first figure out how long to sleep for */
	temp = 0x7fffffff;	/* afs_int32 time; maxint doesn't work in select */
	setAny = 0;
	for (tb = allBnodes; tb; tb = tb->next) {
	    if (tb->flags & BNODE_NEEDTIMEOUT) {
		if (tb->nextTimeout < temp) {
		    setAny = 1;
		    temp = tb->nextTimeout;
		}
	    }
	}
	/* now temp has the time at which we should wakeup next */

	/* sleep */
	if (setAny)
	    temp -= FT_ApproxTime();	/* how many seconds until next event */
	else
	    temp = 999999;
	if (temp > 0) {
	    tv.tv_sec = temp;
	    tv.tv_usec = 0;
	    code = IOMGR_Select(0, 0, 0, 0, &tv);
	} else
	    code = 0;		/* fake timeout code */

	/* figure out why we woke up; child exit or timeouts */
	FT_GetTimeOfDay(&tv, 0);	/* must do the real gettimeofday once and a while */
	temp = tv.tv_sec;

	/* check all bnodes to see which ones need timeout events */
	for (tb = allBnodes; tb; tb = nb) {
	    if ((tb->flags & BNODE_NEEDTIMEOUT) && temp > tb->nextTimeout) {
		bnode_Hold(tb);
		BOP_TIMEOUT(tb);
		bnode_Check(tb);
		if (tb->flags & BNODE_NEEDTIMEOUT) {	/* check again, BOP_TIMEOUT could change */
		    tb->nextTimeout = FT_ApproxTime() + tb->period;
		}
		nb = tb->next;
		bnode_Release(tb);	/* delete may occur here */
	    } else
		nb = tb->next;
	}

	if (code < 0) {
	    /* signalled, probably by incoming signal */
	    while (1) {
		options = WNOHANG;
		bnode_waiting = options | 0x800000;
		code = waitpid((pid_t) - 1, &status, options);
		bnode_waiting = 0;
		if (code == 0 || code == -1)
		    break;	/* all done */
		/* otherwise code has a process id, which we now search for */
		for (tp = allProcs; tp; tp = tp->next)
		    if (tp->pid == code)
			break;
		if (tp) {
		    /* found the pid */
		    tb = tp->bnode;
		    bnode_Hold(tb);

		    /* count restarts in last 10 seconds */
		    if (temp > tb->rsTime + 30) {
			/* it's been 10 seconds we've been counting */
			tb->rsTime = temp;
			tb->rsCount = 0;
		    }

		    if (WIFSIGNALED(status) == 0) {
			/* exited, not signalled */
			tp->lastExit = WEXITSTATUS(status);
			tp->lastSignal = 0;
			if (tp->lastExit) {
			    tb->errorCode = tp->lastExit;
			    tb->lastErrorExit = FT_ApproxTime();
			    RememberProcName(tp);
			    tb->errorSignal = 0;
			}
			if (tp->coreName)
			    bozo_Log("%s:%s exited with code %d\n", tb->name,
				     tp->coreName, tp->lastExit);
			else
			    bozo_Log("%s exited with code %d\n", tb->name,
				     tp->lastExit);
		    } else {
			/* Signal occurred, perhaps spurious due to shutdown request.
			 * If due to a shutdown request, don't overwrite last error
			 * information.
			 */
			tp->lastSignal = WTERMSIG(status);
			tp->lastExit = 0;
			if (tp->lastSignal != SIGQUIT
			    && tp->lastSignal != SIGTERM
			    && tp->lastSignal != SIGKILL) {
			    tb->errorSignal = tp->lastSignal;
			    tb->lastErrorExit = FT_ApproxTime();
			    RememberProcName(tp);
			}
			if (tp->coreName)
			    bozo_Log("%s:%s exited on signal %d%s\n",
				     tb->name, tp->coreName, tp->lastSignal,
				     WCOREDUMP(status) ? " (core dumped)" :
				     "");
			else
			    bozo_Log("%s exited on signal %d%s\n", tb->name,
				     tp->lastSignal,
				     WCOREDUMP(status) ? " (core dumped)" :
				     "");
			SaveCore(tb, tp);
		    }
		    tb->lastAnyExit = FT_ApproxTime();

		    if (tb->notifier) {
			bozo_Log("BNODE: Notifier %s will be called\n",
				 tb->notifier);
			hdl_notifier(tp);
		    }
		    BOP_PROCEXIT(tb, tp);

		    bnode_Check(tb);
		    if (tb->rsCount++ > 10) {
			/* 10 in 10 seconds */
			tb->flags |= BNODE_ERRORSTOP;
			bnode_SetGoal(tb, BSTAT_SHUTDOWN);
			bozo_Log
			    ("BNODE '%s' repeatedly failed to start, perhaps missing executable.\n",
			     tb->name);
		    }
		    bnode_Release(tb);	/* bnode delete can happen here */
		    DeleteProc(tp);
		} else
		    bnode_stats.weirdPids++;
	    }
	}
    }
    return NULL;
}