static int ez_procexit(struct bnode *bn, struct bnode_proc *aproc) { struct ezbnode *abnode = (struct ezbnode *)bn; /* process has exited */ afs_int32 code = 0; if (DoPidFiles) { bozo_DeletePidFile(bn->name, NULL); } abnode->waitingForShutdown = 0; abnode->running = 0; abnode->killSent = 0; abnode->proc = NULL; bnode_SetTimeout((struct bnode *) abnode, 0); /* clear timer */ if (abnode->b.goal) code = ez_setstat((struct bnode *) abnode, BSTAT_NORMAL); else if (abnode->b.flags & BNODE_ERRORSTOP && abnode->b.errorStopDelay) { bozo_Log("%s will retry start in %d seconds\n", abnode->b.name, abnode->b.errorStopDelay); bnode_SetTimeout(bn, abnode->b.errorStopDelay); } return code; }
static int cron_setstat(register struct cronbnode *abnode, afs_int32 astatus) { if (abnode->waitingForShutdown) return BZBUSY; if (astatus == BSTAT_SHUTDOWN) { if (abnode->running) { /* start shutdown */ bnode_StopProc(abnode->proc, SIGTERM); abnode->waitingForShutdown = 1; bnode_SetTimeout(abnode, SDTIME); /* When shutdown is complete, bproc() calls BOP_PROCEXIT() * [cron_procexit()] which will tell bproc() to no longer * run this cron job. */ } else { /* Tell bproc() to no longer run this cron job */ bnode_SetTimeout(abnode, 0); } } else if (astatus == BSTAT_NORMAL) { /* start the cron job * Figure out when to run next and schedule it */ abnode->when = ktime_next(&abnode->whenToRun, 0); ScheduleCronBnode(abnode); } return 0; }
/* run at creation or after process exit. figures out if we're all done (if a one shot run) or when we should run again. Sleeps until we should run again. Note that the computation of when we should run again is made in procexit and/or create procs. This guy only schedules the sleep */ int ScheduleCronBnode(register struct cronbnode *abnode) { register afs_int32 code; register afs_int32 temp; struct bnode_proc *tp; /* If this proc is shutdown, tell bproc() to no longer run this job */ if (abnode->b.goal == BSTAT_SHUTDOWN) { bnode_SetTimeout(abnode, 0); return 0; } /* otherwise we're supposed to be running, figure out when */ if (abnode->when == 0) { /* one shot */ if (abnode->everRun) { /* once is enough */ bnode_Delete(abnode); return 0; } /* otherwise start it */ if (!abnode->running) { /* start up */ abnode->lastStart = FT_ApproxTime(); code = bnode_NewProc(abnode, abnode->command, NULL, &tp); if (code) { bozo_Log("cron bnode %s failed to start (code %d)\n", abnode->b.name, code); return code; } abnode->everRun = 1; abnode->running = 1; abnode->proc = tp; return 0; } } else { /* run periodically */ if (abnode->running) return 0; /* otherwise find out when to run it, and do it then */ temp = abnode->when - FT_ApproxTime(); if (temp < 1) temp = 1; /* temp is when to start dude */ bnode_SetTimeout(abnode, temp); } return 0; }
static int ez_setstat(struct bnode *bn, afs_int32 astatus) { struct ezbnode *abnode = (struct ezbnode *)bn; struct bnode_proc *tp; afs_int32 code; if (abnode->waitingForShutdown) return BZBUSY; if (astatus == BSTAT_NORMAL && !abnode->running) { /* start up */ abnode->lastStart = FT_ApproxTime(); code = bnode_NewProc((struct bnode *)abnode, abnode->command, NULL, &tp); if (code) return code; abnode->running = 1; abnode->proc = tp; return 0; } else if (astatus == BSTAT_SHUTDOWN && abnode->running) { /* start shutdown */ bnode_StopProc(abnode->proc, SIGTERM); abnode->waitingForShutdown = 1; bnode_SetTimeout((struct bnode *)abnode, SDTIME); return 0; } return 0; }
/* called to SIGKILL a process if it doesn't terminate normally. In cron, also start up a process if it is time and not already running */ static int cron_timeout(struct bnode *bn) { struct cronbnode *abnode = (struct cronbnode *)bn; register afs_int32 temp; register afs_int32 code; struct bnode_proc *tp; if (!abnode->running) { if (abnode->when == 0) return 0; /* spurious timeout activation */ /* not running, perhaps we should start it */ if (FT_ApproxTime() >= abnode->when) { abnode->lastStart = FT_ApproxTime(); bnode_SetTimeout((struct bnode *)abnode, 0); code = bnode_NewProc((struct bnode *)abnode, abnode->command, NULL, &tp); if (code) { bozo_Log("cron failed to start bnode %s (code %d)\n", abnode->b.name, code); return code; } abnode->everRun = 1; abnode->running = 1; abnode->proc = tp; } else { /* woke up too early, try again */ temp = abnode->when - FT_ApproxTime(); if (temp < 1) temp = 1; bnode_SetTimeout((struct bnode *)abnode, temp); } } else { if (!abnode->waitingForShutdown) return 0; /* spurious */ /* send kill and turn off timer */ bnode_StopProc(abnode->proc, SIGKILL); abnode->killSent = 1; bnode_SetTimeout((struct bnode *)abnode, 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; }