From: Davin McCall Date: Tue, 27 Jun 2017 16:29:11 +0000 (+0100) Subject: service descriptions: Implement the stop-timeout setting. X-Git-Tag: v0.06~34 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=d9c8b9b42d246ab926f12c853bb67cae2f74b594;p=oweals%2Fdinit.git service descriptions: Implement the stop-timeout setting. --- diff --git a/README b/README index e78d2f9..89925c4 100644 --- a/README +++ b/README @@ -181,6 +181,13 @@ restart-limit-count = NNN restart over the interval specified by restart-limit-interval (default of 10 seconds). Specify a value of 0 to disable the restart limit. +stop-timeout = XXX.YYYY + Specifies the time in seconds allowed for the service to stop. If the + service takes longer than this, its process group is sent a SIGKILL signal + which should cause it to terminate immediately. The timeout period begins + only when all dependent services have already stopped. The default stop + timeout is 10 seconds. + pid-file = (path to file) For "bgprocess" type services only; specifies the path of the file where daemon will write its process ID before detaching. diff --git a/doc/manpages/dinit.8 b/doc/manpages/dinit.8 index fff23ea..e54a46a 100644 --- a/doc/manpages/dinit.8 +++ b/doc/manpages/dinit.8 @@ -146,6 +146,13 @@ Specifies the maximum number of times that a service can automatically restart over the interval specified by \fBrestart-limit-interval\fR. Specify a value of 0 to disable the restart limit. .TP +\fBstop-timeout\fR = \fIXXX.YYY\fR +Specifies the time in seconds allowed for the service to stop. If the +service takes longer than this, its process group is sent a SIGKILL signal +which should cause it to terminate immediately. The timeout period begins +only when all dependent services have already stopped. The default +timeout is 10 seconds. Specify a value of 0 to allow unlimited stop time. +.TP \fBpid-file\fR = \fIpath-to-file\fR For \fBbgprocess\fR type services only; specifies the path of the file where daemon will write its process ID before detaching. Dinit will read the diff --git a/src/load_service.cc b/src/load_service.cc index b1f1227..9a6b1d2 100644 --- a/src/load_service.cc +++ b/src/load_service.cc @@ -402,6 +402,7 @@ service_record * dirload_service_set::load_service(const char * name) timespec restart_interval = { .tv_sec = 10, .tv_nsec = 0 }; int max_restarts = 3; timespec restart_delay = { .tv_sec = 0, .tv_nsec = 200000000 }; + timespec stop_timeout = { .tv_sec = 10, .tv_nsec = 0 }; string line; ifstream service_file; @@ -562,6 +563,10 @@ service_record * dirload_service_set::load_service(const char * name) string limit_str = read_setting_value(i, end, nullptr); max_restarts = parse_unum_param(limit_str, name, std::numeric_limits::max()); } + else if (setting == "stop-timeout") { + string stoptimeout_str = read_setting_value(i, end, nullptr); + parse_timespec(stoptimeout_str, name, "stop-timeout", stop_timeout); + } else { throw service_description_exc(name, "Unknown setting: " + setting); } @@ -586,6 +591,7 @@ service_record * dirload_service_set::load_service(const char * name) command_offsets, std::move(depends_on), depends_soft); rvalps->set_restart_interval(restart_interval, max_restarts); rvalps->set_restart_delay(restart_delay); + rvalps->set_stop_timeout(stop_timeout); rval = rvalps; } else if (service_type == service_type::BGPROCESS) { @@ -594,12 +600,15 @@ service_record * dirload_service_set::load_service(const char * name) rvalps->set_pid_file(std::move(pid_file)); rvalps->set_restart_interval(restart_interval, max_restarts); rvalps->set_restart_delay(restart_delay); + rvalps->set_stop_timeout(stop_timeout); rval = rvalps; } else if (service_type == service_type::SCRIPTED) { - rval = new scripted_service(this, string(name), std::move(command), + auto rvalps = new scripted_service(this, string(name), std::move(command), command_offsets, std::move(depends_on), depends_soft); - rval->setStopCommand(stop_command, stop_command_offsets); + rvalps->setStopCommand(stop_command, stop_command_offsets); + rvalps->set_stop_timeout(stop_timeout); + rval = rvalps; } else { rval = new service_record(this, string(name), service_type, diff --git a/src/service.h b/src/service.h index 3075bb2..b76b1bb 100644 --- a/src/service.h +++ b/src/service.h @@ -585,8 +585,8 @@ class service_record class base_process_service; -// A timer for process restarting. Used to ensure a minimum delay between -// process restarts. +// A timer for process restarting. Used to ensure a minimum delay between process restarts (and +// also for timing service stop before the SIGKILL hammer is used). class process_restart_timer : public eventloop_t::timer_impl { public: @@ -672,6 +672,11 @@ class base_process_service : public service_record { restart_delay = delay; } + + void set_stop_timeout(timespec timeout) noexcept + { + stop_timeout = timeout; + } }; class process_service : public base_process_service