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; }
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; }
static int sdproc(struct bnode *abnode, void *arock) { bnode_Hold(abnode); bnode_SetStat(abnode, BSTAT_SHUTDOWN); bnode_Release(abnode); return 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 */ }
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; }
afs_int32 bnode_Create(char *atype, char *ainstance, struct bnode ** abp, char *ap1, char *ap2, char *ap3, char *ap4, char *ap5, char *notifier, int fileGoal, int rewritefile) { struct bnode_type *type; struct bnode *tb; char *notifierpath = NULL; struct stat tstat; if (bnode_FindInstance(ainstance)) return BZEXISTS; type = FindType(atype); if (!type) return BZBADTYPE; if (notifier && strcmp(notifier, NONOTIFIER)) { /* construct local path from canonical (wire-format) path */ if (ConstructLocalBinPath(notifier, ¬ifierpath)) { bozo_Log("BNODE-Create: Notifier program path invalid '%s'\n", notifier); return BZNOCREATE; } if (stat(notifierpath, &tstat)) { bozo_Log("BNODE-Create: Notifier program '%s' not found\n", notifierpath); free(notifierpath); return BZNOCREATE; } } tb = (*type->ops->create) (ainstance, ap1, ap2, ap3, ap4, ap5); if (!tb) { free(notifierpath); return BZNOCREATE; } tb->notifier = notifierpath; *abp = tb; tb->type = type; /* The fs_create above calls bnode_InitBnode() which always sets the ** fileGoal to BSTAT_NORMAL .... overwrite it with whatever is passed into ** this function as a parameter... */ tb->fileGoal = fileGoal; bnode_SetStat(tb, tb->goal); /* nudge it once */ if (rewritefile != 0) WriteBozoFile(0); return 0; }
/* called to SIGKILL a process if it doesn't terminate normally * or to retry start after an error stop. */ static int ez_timeout(struct bnode *bn) { struct ezbnode *abnode = (struct ezbnode *)bn; if (abnode->waitingForShutdown) { /* send kill and turn off timer */ bnode_StopProc(abnode->proc, SIGKILL); abnode->killSent = 1; bnode_SetTimeout((struct bnode *)abnode, 0); } else if (!abnode->running && abnode->b.flags & BNODE_ERRORSTOP) { /* was stopped for too many errors, retrying */ /* reset error count after running for a bit */ bnode_SetTimeout(bn, ERROR_RESET_TIME); bnode_SetStat(bn, BSTAT_NORMAL); } else { bnode_SetTimeout(bn, 0); /* one shot timer */ bnode_ResetErrorCount(bn); } return 0; }
afs_int32 SBOZO_CreateBnode(struct rx_call *acall, char *atype, char *ainstance, char *ap1, char *ap2, char *ap3, char *ap4, char *ap5, char *notifier) { struct bnode *tb; afs_int32 code; char caller[MAXKTCNAMELEN]; if (!afsconf_SuperUser(bozo_confdir, acall, caller)) { code = BZACCESS; goto fail; } if (bozo_isrestricted) { const char *salvpath = AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH; /* for DAFS, 'bos salvage' will pass "salvageserver -client" instead */ const char *salsrvpath = AFSDIR_CANONICAL_SERVER_SALSRV_FILEPATH " -client "; /* still allow 'bos salvage' to work */ if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp") || strcmp(ap2, "now") || (strncmp(ap1, salvpath, strlen(salvpath)) && strncmp(ap1, salsrvpath, strlen(salsrvpath)))) { code = BZACCESS; goto fail; } } code = bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier, BSTAT_NORMAL, 1); if (!code) bnode_SetStat(tb, BSTAT_NORMAL); fail: osi_auditU(acall, BOS_CreateBnodeEvent, code, AUD_END); return code; }
int ReadBozoFile(char *aname) { FILE *tfile; char tbuffer[BOZO_BSSIZE]; char *tp; char *instp, *typep, *notifier, *notp; afs_int32 code; afs_int32 ktmask, ktday, kthour, ktmin, ktsec; afs_int32 i, goal; struct bnode *tb; char *parms[MAXPARMS]; char *thisparms[MAXPARMS]; int rmode; /* rename BozoInit to BosServer for the user */ if (!aname) { /* if BozoInit exists and BosConfig doesn't, try a rename */ if (access(AFSDIR_SERVER_BOZINIT_FILEPATH, 0) == 0 && access(AFSDIR_SERVER_BOZCONF_FILEPATH, 0) != 0) { code = rk_rename(AFSDIR_SERVER_BOZINIT_FILEPATH, AFSDIR_SERVER_BOZCONF_FILEPATH); if (code < 0) perror("bosconfig rename"); } if (access(AFSDIR_SERVER_BOZCONFNEW_FILEPATH, 0) == 0) { code = rk_rename(AFSDIR_SERVER_BOZCONFNEW_FILEPATH, AFSDIR_SERVER_BOZCONF_FILEPATH); if (code < 0) perror("bosconfig rename"); } } /* don't do server restarts by default */ bozo_nextRestartKT.mask = KTIME_NEVER; bozo_nextRestartKT.hour = 0; bozo_nextRestartKT.min = 0; bozo_nextRestartKT.day = 0; /* restart processes at 5am if their binaries have changed */ bozo_nextDayKT.mask = KTIME_HOUR | KTIME_MIN; bozo_nextDayKT.hour = 5; bozo_nextDayKT.min = 0; for (code = 0; code < MAXPARMS; code++) parms[code] = NULL; if (!aname) aname = (char *)bozo_fileName; tfile = fopen(aname, "r"); if (!tfile) return 0; /* -1 */ instp = malloc(BOZO_BSSIZE); typep = malloc(BOZO_BSSIZE); notp = malloc(BOZO_BSSIZE); while (1) { /* ok, read lines giving parms and such from the file */ tp = fgets(tbuffer, sizeof(tbuffer), tfile); if (tp == (char *)0) break; /* all done */ if (strncmp(tbuffer, "restarttime", 11) == 0) { code = sscanf(tbuffer, "restarttime %d %d %d %d %d", &ktmask, &ktday, &kthour, &ktmin, &ktsec); if (code != 5) { code = -1; goto fail; } /* otherwise we've read in the proper ktime structure; now assign * it and continue processing */ bozo_nextRestartKT.mask = ktmask; bozo_nextRestartKT.day = ktday; bozo_nextRestartKT.hour = kthour; bozo_nextRestartKT.min = ktmin; bozo_nextRestartKT.sec = ktsec; continue; } if (strncmp(tbuffer, "checkbintime", 12) == 0) { code = sscanf(tbuffer, "checkbintime %d %d %d %d %d", &ktmask, &ktday, &kthour, &ktmin, &ktsec); if (code != 5) { code = -1; goto fail; } /* otherwise we've read in the proper ktime structure; now assign * it and continue processing */ bozo_nextDayKT.mask = ktmask; /* time to restart the system */ bozo_nextDayKT.day = ktday; bozo_nextDayKT.hour = kthour; bozo_nextDayKT.min = ktmin; bozo_nextDayKT.sec = ktsec; continue; } if (strncmp(tbuffer, "restrictmode", 12) == 0) { code = sscanf(tbuffer, "restrictmode %d", &rmode); if (code != 1) { code = -1; goto fail; } if (rmode != 0 && rmode != 1) { code = -1; goto fail; } bozo_isrestricted = rmode; continue; } if (strncmp("bnode", tbuffer, 5) != 0) { code = -1; goto fail; } notifier = notp; code = sscanf(tbuffer, "bnode %s %s %d %s", typep, instp, &goal, notifier); if (code < 3) { code = -1; goto fail; } else if (code == 3) notifier = NULL; memset(thisparms, 0, sizeof(thisparms)); for (i = 0; i < MAXPARMS; i++) { /* now read the parms, until we see an "end" line */ tp = fgets(tbuffer, sizeof(tbuffer), tfile); if (!tp) { code = -1; goto fail; } StripLine(tbuffer); if (!strncmp(tbuffer, "end", 3)) break; if (strncmp(tbuffer, "parm ", 5)) { code = -1; goto fail; /* no "parm " either */ } if (!parms[i]) /* make sure there's space */ parms[i] = malloc(BOZO_BSSIZE); strcpy(parms[i], tbuffer + 5); /* remember the parameter for later */ thisparms[i] = parms[i]; } /* ok, we have the type and parms, now create the object */ code = bnode_Create(typep, instp, &tb, thisparms[0], thisparms[1], thisparms[2], thisparms[3], thisparms[4], notifier, goal ? BSTAT_NORMAL : BSTAT_SHUTDOWN, 0); if (code) goto fail; /* bnode created in 'temporarily shutdown' state; * check to see if we are supposed to run this guy, * and if so, start the process up */ if (goal) { bnode_SetStat(tb, BSTAT_NORMAL); /* set goal, taking effect immediately */ } else { bnode_SetStat(tb, BSTAT_SHUTDOWN); } } /* all done */ code = 0; fail: if (instp) free(instp); if (typep) free(typep); for (i = 0; i < MAXPARMS; i++) if (parms[i]) free(parms[i]); if (tfile) fclose(tfile); return code; }