diff options
author | Roy Marples <roy@marples.name> | 2009-04-24 07:03:08 +0000 |
---|---|---|
committer | Roy Marples <roy@marples.name> | 2009-04-24 07:03:08 +0000 |
commit | e7b35a8f150a64499d9974e40787e5f830e78585 (patch) | |
tree | b84052e9a6e1062798e2bce970ffe9ca4f970392 | |
parent | e643a7fdd5726644a5d195e91ba23e9687a4407d (diff) |
Allow rc to start (optionally stop) crashed services, #120
-rw-r--r-- | etc/rc.conf.in | 6 | ||||
-rw-r--r-- | 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(); |