/* * This is an in-fix recursive function called before s is started to * stop every service that depends on s, in reverse order *or* after s * was started to start again every service that depends on s. The * action parametere controls if this function should start or stop * the procceses that depends on s. * @param s A Service_T object * @param action An action to do on the dependant services */ static void do_depend(Service_T s, const char *action) { Service_T child; ASSERT(s); for(child= servicelist; child; child= child->next) { if(child->dependantlist) { Dependant_T d; for(d= child->dependantlist; d; d= d->next) { if(IS(d->dependant, s->name)) { if(IS(action, "start")) do_start(child); else if(IS(action, "monitor")) do_monitor(child); do_depend(child, action); if(IS(action, "stop")) do_stop(child); else if(IS(action, "unmonitor")) do_unmonitor(child); break; } } } } }
/* * This is an in-fix recursive function called before s is started to * stop every service that depends on s, in reverse order *or* after s * was started to start again every service that depends on s. The * action parametere controls if this function should start or stop * the procceses that depends on s. * @param s A Service_T object * @param action An action to do on the dependant services */ static void do_depend(Service_T s, int action) { Service_T child; ASSERT(s); for (child = servicelist; child; child = child->next) { if (child->dependantlist) { Dependant_T d; for (d = child->dependantlist; d; d = d->next) { if (IS(d->dependant, s->name)) { if (action == ACTION_START) do_start(child); else if (action == ACTION_MONITOR) do_monitor(child); do_depend(child, action); if (action == ACTION_STOP) do_stop(child); else if (action == ACTION_UNMONITOR) do_unmonitor(child); break; } } } } }
/** * Check to see if we should try to start/stop service * @param P A service name as stated in the config file * @param action A string describing the action to execute * @return TRUE if the service was handled successfully otherwise FALSE */ void check_service(const char *P, const char *action) { Service_T s= NULL; ASSERT(P); ASSERT(action); if(NULL==(s= get_service(P))) { log("%s: Cannot %s program '%s' -- not found in %s\n", prog, action, P, Run.controlfile); return; } if(IS(action, "start")) { if(s->type==TYPE_PROCESS && is_process_running(s)) { DEBUG("%s: Process already running -- process %s\n", prog, P); monitor_set(s); return; } if(s->type==TYPE_PROCESS && !s->start) { DEBUG("%s: Start method not defined -- process %s\n", prog, P); monitor_set(s); return; } do_depend(s, "stop"); do_start(s); do_depend(s, "start"); } else if(IS(action, "stop")) { if(s->type==TYPE_PROCESS && !s->stop) { DEBUG("%s: Stop method not defined -- process %s\n", prog, P); monitor_unset(s); return; } do_depend(s, "stop"); do_stop(s); } else if(IS(action, "restart")) { if(s->type==TYPE_PROCESS && (!s->start || !s->stop)) { DEBUG("%s: Start or stop method not defined -- process %s\n", prog, P); monitor_set(s); return; } else { log("Trying to restart '%s'\n", s->name); } do_depend(s, "stop"); if(do_stop(s)) { /* Only start if stop succeeded */ do_start(s); do_depend(s, "start"); } } else if(IS(action, "monitor")) { /* We only enable monitoring of this service and all prerequisite * services. Chain of services which depends on this service keep * its state */ do_monitor(s); } else if(IS(action, "unmonitor")) { /* We disable monitoring of this service and all services which * depends on it */ do_depend(s, "unmonitor"); do_unmonitor(s); } }
/** * Check to see if we should try to start/stop service * @param S A service name as stated in the config file * @param A An action id describing the action to execute * @return FALSE for error, otherwise TRUE */ int control_service(const char *S, int A) { Service_T s = NULL; ASSERT(S); if (! (s = Util_getService(S))) { LogError("%s: service '%s' -- doesn't exist\n", prog, S); return FALSE; } switch(A) { case ACTION_START: if (s->type == TYPE_PROCESS) { if (Util_isProcessRunning(s)) { DEBUG("%s: Process already running -- process %s\n", prog, S); Util_monitorSet(s); return TRUE; } if (!s->start) { LogError("%s: Start method not defined -- process %s\n", prog, S); Util_monitorSet(s); return FALSE; } } do_depend(s, ACTION_STOP); do_start(s); do_depend(s, ACTION_START); break; case ACTION_STOP: if (s->type == TYPE_PROCESS && !s->stop) { LogError("%s: Stop method not defined -- process %s\n", prog, S); Util_monitorUnset(s); return FALSE; } /* soft unmonitor and stop: */ do_depend(s, ACTION_STOP); do_stop(s); /* hard unmonitor - will reset all counters and flags: */ do_depend(s, ACTION_UNMONITOR); do_unmonitor(s); break; case ACTION_RESTART: if (s->type == TYPE_PROCESS && (!s->start || !s->stop)) { LogError("%s: Start or stop method not defined -- process %s\n", prog, S); Util_monitorSet(s); return FALSE; } LogInfo("'%s' trying to restart\n", s->name); do_depend(s, ACTION_STOP); if (do_stop(s)) { /* Only start if stop succeeded */ do_start(s); do_depend(s, ACTION_START); } else { /* enable monitoring of this service again to allow the restart retry * in the next cycle up to timeout limit */ Util_monitorSet(s); } break; case ACTION_MONITOR: /* We only enable monitoring of this service and all prerequisite * services. Chain of services which depends on this service keep * its state */ do_monitor(s); break; case ACTION_UNMONITOR: /* We disable monitoring of this service and all services which * depends on it */ do_depend(s, ACTION_UNMONITOR); do_unmonitor(s); break; default: LogError("%s: service '%s' -- invalid action %s\n", prog, S, A); return FALSE; } return TRUE; }