Allow specifying service start timeout in service description.
authorDavin McCall <davmac@davmac.org>
Mon, 8 Jan 2018 11:05:00 +0000 (11:05 +0000)
committerDavin McCall <davmac@davmac.org>
Mon, 8 Jan 2018 11:05:00 +0000 (11:05 +0000)
Default is 60 seconds.

README
TODO
doc/manpages/dinit.8
src/load_service.cc
src/service.h

diff --git a/README b/README
index 603e3d45ef5fc71c8d37eb596366f7d70260f565..9d3fbd1f6481e44c84d40e29c04096235c881165 100644 (file)
--- 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 e6302728488828c7f7f73ea40f76ff5bc86dca1c..8356d7e71fcd000a47b32b5286c4f235943f77db 100644 (file)
--- 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:
 ----------
index a9f4c42a2260b05344235285c6702e6a8b2b8df4..4a477a86cf5030c73631fd7e865e14cfa69c1b7f 100644 (file)
@@ -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
index d1d827d8157964f171ddf94e8379f694d9b228a7..dd77937ecf9cd0c714faf8812907b1d5e6b4850d 100644 (file)
@@ -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;
                 }
index 72875018209395d395c7a04aa8e37a6ed587425e..c2934f4375e0958d6ebcb50af9b8263885fe4385 100644 (file)
@@ -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;