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; }
/* 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; }
/* 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; }