From e7b35a8f150a64499d9974e40787e5f830e78585 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Fri, 24 Apr 2009 07:03:08 +0000 Subject: [PATCH] Allow rc to start (optionally stop) crashed services, #120 --- etc/rc.conf.in | 6 ++++++ src/rc/rc.c | 26 +++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/etc/rc.conf.in b/etc/rc.conf.in index 120eed71..fa28d866 100644 --- a/etc/rc.conf.in +++ b/etc/rc.conf.in @@ -57,6 +57,12 @@ rc_logger="NO" # This still allows the service itself to be stopped when called directly. #rc_nostop="network" +# rc will attempt to start crashed services by default. +# However, it will not stop them by default as that could bring down other +# critical services. +#rc_crashed_stop=NO +#rc_crashed_start=YES + ############################################################################## # MISC CONFIGURATION VARIABLES # There variables are shared between many init scripts diff --git a/src/rc/rc.c b/src/rc/rc.c index 9a08546a..83a3701b 100644 --- a/src/rc/rc.c +++ b/src/rc/rc.c @@ -571,12 +571,15 @@ do_stop_services(const char *newlevel, bool parallel) RC_STRINGLIST *deporder, *tmplist; RC_SERVICE state; RC_STRINGLIST *nostop; + bool crashed; if (!types_n) { types_n = rc_stringlist_new(); rc_stringlist_add(types_n, "needsme"); } + crashed = rc_conf_yesno("rc_crashed_stop"); + nostop = rc_stringlist_split(rc_conf_value("rc_nostop"), " "); TAILQ_FOREACH_REVERSE(service, stop_services, rc_stringlist, entries) { @@ -590,6 +593,12 @@ do_stop_services(const char *newlevel, bool parallel) continue; } + /* If the service has crashed, skip futher checks and just stop + it */ + if (crashed && + rc_service_daemons_crashed(service->value)) + goto stop; + /* If we're in the start list then don't bother stopping us */ svc1 = rc_stringlist_find(start_services, service->value); if (svc1) { @@ -628,6 +637,7 @@ do_stop_services(const char *newlevel, bool parallel) continue; } +stop: /* After all that we can finally stop the blighter! */ pid = service_stop(service->value); if (pid > 0) { @@ -649,15 +659,25 @@ do_start_services(bool parallel) pid_t pid; bool interactive = false; RC_SERVICE state; + bool crashed = false; if (!rc_yesno(getenv("EINFO_QUIET"))) interactive = exists(INTERACTIVE); + errno = 0; + crashed = rc_conf_yesno("rc_crashed_start"); + if (errno == ENOENT) + crashed = true; TAILQ_FOREACH(service, start_services, entries) { state = rc_service_state(service->value); - if (!(state & RC_SERVICE_STOPPED) || state & RC_SERVICE_FAILED) - continue; - + if (!(state & (RC_SERVICE_STOPPED | RC_SERVICE_FAILED))) { + if (crashed && + rc_service_daemons_crashed(service->value)) + rc_service_mark(service->value, + RC_SERVICE_STOPPED); + else + continue; + } if (!interactive) interactive = want_interactive();