/* * This is a function for disabling monitoring * @param s A Service_T object * @param flag A Custom flag */ static void do_unmonitor(Service_T s, int flag) { ASSERT(s); if (s->depend_visited) return; s->depend_visited = TRUE; Util_monitorUnset(s); }
/* * This function simply stops the service p. * @param s A Service_T object * @param flag TRUE if the monitoring should be disabled or FALSE if monitoring should continue (when stop is part of restart) * @return TRUE if the service was stopped otherwise FALSE */ static int do_stop(Service_T s, int flag) { int rv = TRUE; ASSERT(s); if (s->depend_visited) return rv; s->depend_visited = TRUE; if (s->stop) { if (s->type != TYPE_PROCESS || Util_isProcessRunning(s, FALSE)) { LogInfo("'%s' stop: %s\n", s->name, s->stop->arg[0]); spawn(s, s->stop, NULL); if (s->type == TYPE_PROCESS && (wait_process(s, Process_Stopped) != Process_Stopped)) // Only wait for process service types stop rv = FALSE; } } else { LogDebug("'%s' stop skipped -- method not defined\n", s->name); } if (flag) Util_monitorUnset(s); else Util_resetInfo(s); return rv; }
/** * 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; }