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 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel