service instance: Improve handling of watchdog config changes
authorTim Nordell <tnordell@airgain.com>
Wed, 15 Oct 2025 20:52:04 +0000 (15:52 -0500)
committerDaniel Golle <daniel@makrotopia.org>
Mon, 9 Feb 2026 11:31:44 +0000 (11:31 +0000)
When the ubus call "ubus call service watchdog" is used, it's expected
that the service might change its watchdog values during runtime when
it pets the watchdog.  The instance restarting behavior was setup though
to restart the instance if these changed.  This causes any service which
adjusts its watchdog to be restarted via "/etc/init.d/SERVICENAME start"
which is probably not what was intended.

Introduce a new variable, self_managed, if the service adjusted these
values at runtime so that a "start" doesn't cause the entire service to
restart.

Signed-off-by: Tim Nordell <tnordell@airgain.com>
service/instance.c
service/instance.h
service/service.c

index fcffd3d2c795fa184a11be395a7cd41b0aa27abe..2b8bba0233bfc8bc16c09d51575ef550ead7dfd5 100644 (file)
@@ -1040,10 +1040,10 @@ instance_config_changed(struct service_instance *in, struct service_instance *in
        if (in->jail.flags != in_new->jail.flags)
                return true;
 
-       if (in->watchdog.mode != in_new->watchdog.mode)
+       if (!in->watchdog.self_managed && in->watchdog.mode != in_new->watchdog.mode)
                return true;
 
-       if (in->watchdog.freq != in_new->watchdog.freq)
+       if (!in->watchdog.self_managed && in->watchdog.freq != in_new->watchdog.freq)
                return true;
 
        return false;
@@ -1517,9 +1517,11 @@ instance_config_move(struct service_instance *in, struct service_instance *in_sr
        in->respawn_timeout = in_src->respawn_timeout;
        in->reload_signal = in_src->reload_signal;
        in->term_timeout = in_src->term_timeout;
-       in->watchdog.mode = in_src->watchdog.mode;
-       in->watchdog.freq = in_src->watchdog.freq;
-       // Note: in->watchdog.timeout is in a linked list; do not copy
+       if (!in->watchdog.self_managed) {
+               // Note: in->watchdog.timeout is in a linked list; do not copy
+               in->watchdog.mode = in_src->watchdog.mode;
+               in->watchdog.freq = in_src->watchdog.freq;
+       }
        in->name = in_src->name;
        in->nice = in_src->nice;
        in->trace = in_src->trace;
index 32fae194a3c8854837ceaaa5ad4d51c719f2e18c..d5a10e27699f516896d3f435fba17cafd1f69159 100644 (file)
@@ -55,6 +55,7 @@ typedef enum instance_watchdog {
 } instance_watchdog_mode_t;
 
 struct watchdog {
+       bool self_managed;
        instance_watchdog_mode_t mode;
        uint32_t freq;
        struct uloop_timeout timeout;
index 831f075a33f0f3387cde258ad6e36b8125bafcaf..7f1f4082a47c82a99a7f52ca9de494aa4fc51b17 100644 (file)
@@ -1059,6 +1059,11 @@ service_handle_watchdog(struct ubus_context *ctx, struct ubus_object *obj,
 
        ubus_send_reply(ctx, req, b.head);
 
+       // If the service adjusts the mode or timeout, mark it as self managed
+       // so that it doesn't get restarted with a new /etc/init.d/SERVICE start
+       if (tb[SERVICE_WATCHDOG_MODE] || tb[SERVICE_WATCHDOG_TIMEOUT])
+               in->watchdog.self_managed = true;
+
        return UBUS_STATUS_OK;
 }