]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: notify supervisor over targets we reach, as we reach them
authorLennart Poettering <lennart@poettering.net>
Tue, 12 Mar 2024 15:08:13 +0000 (16:08 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 14 Mar 2024 16:23:10 +0000 (17:23 +0100)
Let's inform the the supervisor about various happenings of our service
manager, specifically the boot milestones we reach.

We so far have only a singular READY=1 message, to inform about bootup
completion. But sometimes it is interesting to have something for
finegrained, in particular something that indicates optional components
that have been activated.

Usecase for this: in a later PR I intend to introduce a generic
"ssh.target" that is supposed to be activated when SSH becomes available
on a host. A supervisor (i.e. a VMM/hypervisor/container mgr/…) can
watch for that, and know two things:

1. that SSH is generally available in the system
2. when it is available

In order to not flood the supervisor with events I only send these out
for target units. We could open this up later, in theory, but I think it
makes sense to tell people instead to define clear milestone target
units if they want a supervisor to be able to track system state.

src/core/manager.c
src/core/manager.h
src/core/target.c
src/core/unit.c
src/core/unit.h

index 2ef8ad90daabdb5141f227fd2be7fa040292f47d..da510cd04ecb138bb3eff4304ce53705767adfdb 100644 (file)
@@ -3424,6 +3424,27 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
                                "Failed to communicate with plymouth: %m");
 }
 
+void manager_send_unit_supervisor(Manager *m, Unit *u, bool active) {
+        assert(m);
+        assert(u);
+
+        /* Notify a "supervisor" process about our progress, i.e. a container manager, hypervisor, or
+         * surrounding service manager. */
+
+        if (MANAGER_IS_RELOADING(m))
+                return;
+
+        if (!UNIT_VTABLE(u)->notify_supervisor)
+                return;
+
+        if (in_initrd()) /* Only send these once we left the initrd */
+                return;
+
+        (void) sd_notifyf(/* unset_environment= */ false,
+                          active ? "X_SYSTEMD_UNIT_ACTIVE=%s" : "X_SYSTEMD_UNIT_INACTIVE=%s",
+                          u->id);
+}
+
 usec_t manager_get_watchdog(Manager *m, WatchdogType t) {
         assert(m);
 
index 9f1a21b22dbe82592f2ff77ceb77875f8fcc33e9..4d82c4a6a0daa7f91418057b61eca7ec0c118cd5 100644 (file)
@@ -575,6 +575,7 @@ void manager_reset_failed(Manager *m);
 
 void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success);
 void manager_send_unit_plymouth(Manager *m, Unit *u);
+void manager_send_unit_supervisor(Manager *m, Unit *u, bool active);
 
 bool manager_unit_inactive_or_pending(Manager *m, const char *name);
 
index 8f2a331f92b9df10cfb1867bb4efb78315df91c3..3851f21442dfe2578a62541ca13b037c47eba5b4 100644 (file)
@@ -213,4 +213,6 @@ const UnitVTable target_vtable = {
                         [JOB_DONE]       = "Stopped target %s.",
                 },
         },
+
+        .notify_supervisor = true,
 };
index 2c6a0b3e5727c0e5c3302881c113a9248e6d20ed..c0f802a137568db44c6e451c2967b654cfc2f007 100644 (file)
@@ -2678,12 +2678,14 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
 
                         unit_emit_audit_start(u);
                         manager_send_unit_plymouth(m, u);
+                        manager_send_unit_supervisor(m, u, /* active= */ true);
                 }
 
                 if (UNIT_IS_INACTIVE_OR_FAILED(ns) && !UNIT_IS_INACTIVE_OR_FAILED(os)) {
                         /* This unit just stopped/failed. */
 
                         unit_emit_audit_stop(u, ns);
+                        manager_send_unit_supervisor(m, u, /* active= */ false);
                         unit_log_resources(u);
                 }
 
index b1cc2c2d01311f12f91964751ac658e86788263e..7134d362fe11120bea2b4e0d8fbb353b5086c0a3 100644 (file)
@@ -731,6 +731,9 @@ typedef struct UnitVTable {
         /* If true, we'll notify plymouth about this unit */
         bool notify_plymouth;
 
+        /* If true, we'll notify a surrounding VMM/container manager about this unit becoming available */
+        bool notify_supervisor;
+
         /* The audit events to generate on start + stop (or 0 if none shall be generated) */
         int audit_start_message_type;
         int audit_stop_message_type;