]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
service: when starting a service make a copy of the watchdog timeout and use that 10508/head
authorLennart Poettering <lennart@poettering.net>
Wed, 24 Oct 2018 17:04:41 +0000 (19:04 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 26 Oct 2018 11:00:04 +0000 (13:00 +0200)
When we start a service process we pass the selected watchdog timeout to
it with the $WATCHDOG_USEC environment variable. If the unit file is
reconfigured later, we need to make sure to continue to honour the
original timeout, i.e. watch $WATCHDOG_USEC was set to, otherwise we'll
expect the ping at a different time as the service process is sending it
to us.

Hence, whenever we start a unit, save the watchdog timeout, and stick to
that for everything we do.

Fixes: #9467
src/core/service.c
src/core/service.h

index 2e8ef7d1ab518e4ddd95741016131d2a3a73e32e..2a36cc03f3dd84db2ff31e2b6481bdb64b4b3535 100644 (file)
@@ -107,6 +107,8 @@ static void service_init(Unit *u) {
 
         s->exec_context.keyring_mode = MANAGER_IS_SYSTEM(u->manager) ?
                 EXEC_KEYRING_PRIVATE : EXEC_KEYRING_INHERIT;
+
+        s->watchdog_original_usec = USEC_INFINITY;
 }
 
 static void service_unwatch_control_pid(Service *s) {
@@ -2352,8 +2354,9 @@ static int service_start(Unit *u) {
 
         s->notify_state = NOTIFY_UNKNOWN;
 
+        s->watchdog_original_usec = s->watchdog_usec;
         s->watchdog_override_enable = false;
-        s->watchdog_override_usec = 0;
+        s->watchdog_override_usec = USEC_INFINITY;
 
         exec_command_reset_status_list_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
         exec_status_reset(&s->main_exec_status);
@@ -2588,6 +2591,9 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
         if (s->watchdog_override_enable)
                 (void) serialize_item_format(f, "watchdog-override-usec", USEC_FMT, s->watchdog_override_usec);
 
+        if (s->watchdog_original_usec != USEC_INFINITY)
+                (void) serialize_item_format(f, "watchdog-original-usec", USEC_FMT, s->watchdog_original_usec);
+
         return 0;
 }
 
@@ -2896,6 +2902,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
                 else
                         s->watchdog_override_enable = true;
 
+        } else if (streq(key, "watchdog-original-usec")) {
+                if (deserialize_usec(value, &s->watchdog_original_usec) < 0)
+                        log_unit_debug(u, "Failed to parse watchdog_original_usec value: %s", value);
+
         } else if (STR_IN_SET(key, "main-command", "control-command")) {
                 r = service_deserialize_exec_command(u, key, value);
                 if (r < 0)
index 1206e3cddae1d98b39c64ef041778c3f1d72ebca..9c4340c70e3edda7932e8d64a54c2136630e0617 100644 (file)
@@ -99,8 +99,9 @@ struct Service {
         usec_t runtime_max_usec;
 
         dual_timestamp watchdog_timestamp;
-        usec_t watchdog_usec;
-        usec_t watchdog_override_usec;
+        usec_t watchdog_usec;            /* the requested watchdog timeout in the unit file */
+        usec_t watchdog_original_usec;   /* the watchdog timeout that was in effect when the unit was started, i.e. the timeout the forked off processes currently see */
+        usec_t watchdog_override_usec;   /* the watchdog timeout requested by the service itself through sd_notify() */
         bool watchdog_override_enable;
         sd_event_source *watchdog_event_source;