From: Davin McCall Date: Mon, 8 Jan 2018 11:05:00 +0000 (+0000) Subject: Allow specifying service start timeout in service description. X-Git-Tag: v0.08~66 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=b3a7136643700b5cd581a4904edeb0f960641184;p=oweals%2Fdinit.git Allow specifying service start timeout in service description. Default is 60 seconds. --- diff --git a/README b/README index 603e3d4..9d3fbd1 100644 --- a/README +++ b/README @@ -182,13 +182,20 @@ 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 +stop-timeout = XXX.YYYY (or 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. +start-timeout = XXX.YYYY (or XXX,YYYY) + Specifies the time in seconds allowed for the service to start. IF the + service startup takes longer than this, its process group is sent a + SIGINT signal and transitions to the "stopping" state. if it fails to stop + within the period specified by the stop-timeout setting, it is sent a + SIGKILL signal. + 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/TODO b/TODO index e630272..8356d7e 100644 --- a/TODO +++ b/TODO @@ -2,10 +2,14 @@ * shutdown command presently hangs if terminal output blocked (scroll lock via ^S). Should use a buffer as dinit does, and pipe output from subcommands - via the buffer too. + via the buffer too - if the buffer becomes full, discard subcommand output + and continue to consume it. * Document utilities (particularly dinitctl) in the README +* scripted process interrupted start might still complete successfully. State will + be STOPPING (due to interruptiong), but stop script should still be run in this + case. For version 1.0: ---------------- @@ -20,6 +24,8 @@ For version 1.0: * Load services from several different directories, with an order of precedence, to allow for packaged service descriptions and user-modified service descriptions. +* on shutdown, after repeated intervals with no activity, display information + about services we are waiting on. For later: ---------- diff --git a/doc/manpages/dinit.8 b/doc/manpages/dinit.8 index a9f4c42..4a477a8 100644 --- a/doc/manpages/dinit.8 +++ b/doc/manpages/dinit.8 @@ -146,6 +146,15 @@ 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 +\fBstart-timeout\fR = \fIXXX.YYY\fR +Specifies the time in seconds allowed for the service to start. If the +service takes longer than this, its process group is sent a SIGINT signal +and enters the "stopping" state (this may be subject to a stop timeout, as +specified via \fBstop-timeout\fR, after which the process group will be +terminated via SIGKILL). The timeout period begins only when all dependencies +have been stopped. The default timeout is 60 seconds. Specify a value of 0 to +allow unlimited start time. +.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 diff --git a/src/load_service.cc b/src/load_service.cc index d1d827d..dd77937 100644 --- a/src/load_service.cc +++ b/src/load_service.cc @@ -407,6 +407,7 @@ service_record * dirload_service_set::load_service(const char * name) int max_restarts = 3; timespec restart_delay = { .tv_sec = 0, .tv_nsec = 200000000 }; timespec stop_timeout = { .tv_sec = 10, .tv_nsec = 0 }; + timespec start_timeout = { .tv_sec = 60, .tv_nsec = 0 }; string line; ifstream service_file; @@ -579,6 +580,10 @@ service_record * dirload_service_set::load_service(const char * name) string stoptimeout_str = read_setting_value(i, end, nullptr); parse_timespec(stoptimeout_str, name, "stop-timeout", stop_timeout); } + else if (setting == "start-timeout") { + string starttimeout_str = read_setting_value(i, end, nullptr); + parse_timespec(starttimeout_str, name, "start-timeout", start_timeout); + } else { throw service_description_exc(name, "Unknown setting: " + setting); } @@ -604,6 +609,7 @@ service_record * dirload_service_set::load_service(const char * name) rvalps->set_restart_interval(restart_interval, max_restarts); rvalps->set_restart_delay(restart_delay); rvalps->set_stop_timeout(stop_timeout); + rvalps->set_start_timeout(start_timeout); rvalps->set_start_interruptible(start_is_interruptible); rval = rvalps; } @@ -614,6 +620,7 @@ service_record * dirload_service_set::load_service(const char * name) rvalps->set_restart_interval(restart_interval, max_restarts); rvalps->set_restart_delay(restart_delay); rvalps->set_stop_timeout(stop_timeout); + rvalps->set_start_timeout(start_timeout); rvalps->set_start_interruptible(start_is_interruptible); rval = rvalps; } @@ -622,6 +629,7 @@ service_record * dirload_service_set::load_service(const char * name) command_offsets, depends); rvalps->set_stop_command(stop_command, stop_command_offsets); rvalps->set_stop_timeout(stop_timeout); + rvalps->set_start_timeout(start_timeout); rvalps->set_start_interruptible(start_is_interruptible); rval = rvalps; } diff --git a/src/service.h b/src/service.h index 7287501..c2934f4 100644 --- a/src/service.h +++ b/src/service.h @@ -731,6 +731,11 @@ class base_process_service : public service_record stop_timeout = timeout; } + void set_start_timeout(timespec timeout) noexcept + { + start_timeout = timeout; + } + void set_start_interruptible(bool value) noexcept { start_is_interruptible = value;