[systemd-devel] [PATCH] systemd: introduced new timeout types

Michal Sekletar msekleta at redhat.com
Tue Aug 7 05:41:48 PDT 2012


Makes possible to specify separate timeout for start and stop of
the service.
---
 man/systemd.service.xml               | 25 ++++++++++++++++++++++++-
 src/core/dbus-service.c               |  4 +++-
 src/core/load-fragment-gperf.gperf.m4 |  4 +++-
 src/core/load-fragment.c              | 12 +++++++++---
 src/core/service.c                    | 31 +++++++++++++++++--------------
 src/core/service.h                    |  5 +++--
 6 files changed, 59 insertions(+), 22 deletions(-)

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index f43201d..95adfe1 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -483,10 +483,33 @@
                                 logic. Defaults to
                                 90s, except when <varname>Type=oneshot</varname> is
                                 used in which case the timeout
-                                is disabled by default.</para></listitem>
+                                is disabled by default.
+                                Note that using this option will override all previously
+                                defined timeouts(<varname>TimeoutSec=</varname>,
+                                <varname>TimeoutStartSec=</varname>,
+                                <varname> TimeoutStopSec=</varname>)
+                                </para></listitem>
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>TimeoutStartSec=</varname></term>
+                                <listitem><para>Configures the
+                                time to wait for service to start-up. This
+                                setting will override setting from
+                                <varname>TimeoutSec=</varname>
+                                </para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><varname>TimeoutStopSec=</varname></term>
+                                <listitem><para>Configures the time to
+                                wait for service to stop. Note that
+                                this setting will override setting
+                                from <varname>TimeoutSec=</varname>
+                                </para></listitem>
+                         </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>WatchdogSec=</varname></term>
                                 <listitem><para>Configures the
                                 watchdog timeout for a service. This
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index c0fac16..129e131 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -115,7 +115,9 @@ static const BusProperty bus_service_properties[] = {
         { "PIDFile",                bus_property_append_string,       "s", offsetof(Service, pid_file),               true },
         { "NotifyAccess",           bus_service_append_notify_access, "s", offsetof(Service, notify_access)                },
         { "RestartUSec",            bus_property_append_usec,         "t", offsetof(Service, restart_usec)                 },
-        { "TimeoutUSec",            bus_property_append_usec,         "t", offsetof(Service, timeout_usec)                 },
+        { "TimeoutUSec",            bus_property_append_usec,         "t", offsetof(Service, timeout_start_usec)           },
+        { "TimeoutStartUSec",       bus_property_append_usec,         "t", offsetof(Service, timeout_start_usec)           },
+        { "TimeoutStopUSec",        bus_property_append_usec,         "t", offsetof(Service, timeout_stop_usec)            },
         { "WatchdogUSec",           bus_property_append_usec,         "t", offsetof(Service, watchdog_usec)                },
         { "WatchdogTimestamp",      bus_property_append_usec,         "t", offsetof(Service, watchdog_timestamp.realtime)  },
         { "WatchdogTimestampMonotonic",bus_property_append_usec,      "t", offsetof(Service, watchdog_timestamp.monotonic) },
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 2b1cfa0..e738213 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -145,7 +145,9 @@ Service.ExecReload,              config_parse_exec,                  SERVICE_EXE
 Service.ExecStop,                config_parse_exec,                  SERVICE_EXEC_STOP,             offsetof(Service, exec_command)
 Service.ExecStopPost,            config_parse_exec,                  SERVICE_EXEC_STOP_POST,        offsetof(Service, exec_command)
 Service.RestartSec,              config_parse_usec,                  0,                             offsetof(Service, restart_usec)
-Service.TimeoutSec,              config_parse_service_timeout,       0,                             offsetof(Service, timeout_usec)
+Service.TimeoutSec,              config_parse_service_timeout,       0,                             offsetof(Service, timeout_start_usec)
+Service.TimeoutStartSec,         config_parse_service_timeout,       0,                             offsetof(Service, timeout_start_usec)
+Service.TimeoutStopSec,          config_parse_service_timeout,       0,                             offsetof(Service, timeout_stop_usec)
 Service.WatchdogSec,             config_parse_usec,                  0,                             offsetof(Service, watchdog_usec)
 Service.StartLimitInterval,      config_parse_usec,                  0,                             offsetof(Service, start_limit.interval)
 Service.StartLimitBurst,         config_parse_unsigned,              0,                             offsetof(Service, start_limit.burst)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index bbd82b9..1068130 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -1376,10 +1376,16 @@ int config_parse_service_timeout(
 
         r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata);
 
-        if (!r)
-                s->timeout_defined = true;
+        if (r)
+                return r;
 
-        return r;
+        if (streq(lvalue, "TimeoutSec")) {
+                s->start_timeout_defined = true;
+                s->timeout_stop_usec = s->timeout_start_usec;
+        } else if (streq(lvalue, "TimeoutStartSec"))
+                s->start_timeout_defined = true;
+
+        return 0;
 }
 
 int config_parse_unit_env_file(
diff --git a/src/core/service.c b/src/core/service.c
index 1c127bd..bb331b6 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -134,7 +134,8 @@ static void service_init(Unit *u) {
         assert(u);
         assert(u->load_state == UNIT_STUB);
 
-        s->timeout_usec = DEFAULT_TIMEOUT_USEC;
+        s->timeout_start_usec = DEFAULT_TIMEOUT_USEC;
+        s->timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
         s->restart_usec = DEFAULT_RESTART_USEC;
         s->type = _SERVICE_TYPE_INVALID;
 
@@ -914,9 +915,13 @@ static int service_load_sysv_path(Service *s, const char *path) {
                 UNIT(s)->default_dependencies = false;
 
                 /* Don't timeout special services during boot (like fsck) */
-                s->timeout_usec = 0;
-        } else
-                s->timeout_usec = DEFAULT_SYSV_TIMEOUT_USEC;
+                s->timeout_start_usec = 0;
+                s->timeout_stop_usec = 0;
+        } else {
+                s->timeout_start_usec = DEFAULT_SYSV_TIMEOUT_USEC;
+                s->timeout_stop_usec = DEFAULT_SYSV_TIMEOUT_USEC;
+        }
+
 
         /* Special setting for all SysV services */
         s->type = SERVICE_FORKING;
@@ -1241,9 +1246,8 @@ static int service_load(Unit *u) {
                 if (s->type == _SERVICE_TYPE_INVALID)
                         s->type = s->bus_name ? SERVICE_DBUS : SERVICE_SIMPLE;
 
-                /* Oneshot services have disabled timeout by default */
-                if (s->type == SERVICE_ONESHOT && !s->timeout_defined)
-                        s->timeout_usec = 0;
+                if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined)
+                        s->timeout_start_usec = 0;
 
                 service_fix_output(s);
 
@@ -1603,11 +1607,10 @@ static int service_coldplug(Unit *u) {
                     s->deserialized_state == SERVICE_FINAL_SIGTERM ||
                     s->deserialized_state == SERVICE_FINAL_SIGKILL ||
                     s->deserialized_state == SERVICE_AUTO_RESTART) {
-
-                        if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_usec > 0) {
+                        if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_start_usec > 0) {
                                 usec_t k;
 
-                                k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_usec;
+                                k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_start_usec;
 
                                 if ((r = unit_watch_timer(UNIT(s), k, &s->timer_watch)) < 0)
                                         return r;
@@ -1753,8 +1756,8 @@ static int service_spawn(
                 }
         }
 
-        if (timeout && s->timeout_usec) {
-                if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
+        if (timeout && s->timeout_start_usec) {
+                if ((r = unit_watch_timer(UNIT(s), s->timeout_start_usec, &s->timer_watch)) < 0)
                         goto fail;
         } else
                 unit_unwatch_timer(UNIT(s), &s->timer_watch);
@@ -2011,8 +2014,8 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
         }
 
         if (wait_for_exit) {
-                if (s->timeout_usec > 0)
-                        if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
+                if (s->timeout_stop_usec > 0)
+                        if ((r = unit_watch_timer(UNIT(s), s->timeout_stop_usec, &s->timer_watch)) < 0)
                                 goto fail;
 
                 service_set_state(s, state);
diff --git a/src/core/service.h b/src/core/service.h
index cc63347..c78de79 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -120,7 +120,8 @@ struct Service {
         char *pid_file;
 
         usec_t restart_usec;
-        usec_t timeout_usec;
+        usec_t timeout_start_usec;
+        usec_t timeout_stop_usec;
 
         dual_timestamp watchdog_timestamp;
         usec_t watchdog_usec;
@@ -166,7 +167,7 @@ struct Service {
         bool bus_name_good:1;
         bool forbid_restart:1;
         bool got_socket_fd:1;
-        bool timeout_defined:1;
+        bool start_timeout_defined:1;
 #ifdef HAVE_SYSV_COMPAT
         bool is_sysv:1;
         bool sysv_has_lsb:1;
-- 
1.7.11.2



More information about the systemd-devel mailing list