From b2d6bb5b34c89f6db65273bd42ec54c97efa33d8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 12 Mar 2024 16:08:13 +0100 Subject: [PATCH] core: notify supervisor over targets we reach, as we reach them MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 21 +++++++++++++++++++++ src/core/manager.h | 1 + src/core/target.c | 2 ++ src/core/unit.c | 2 ++ src/core/unit.h | 3 +++ 5 files changed, 29 insertions(+) diff --git a/src/core/manager.c b/src/core/manager.c index 2ef8ad90daa..da510cd04ec 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -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); diff --git a/src/core/manager.h b/src/core/manager.h index 9f1a21b22db..4d82c4a6a0d 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -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); diff --git a/src/core/target.c b/src/core/target.c index 8f2a331f92b..3851f21442d 100644 --- a/src/core/target.c +++ b/src/core/target.c @@ -213,4 +213,6 @@ const UnitVTable target_vtable = { [JOB_DONE] = "Stopped target %s.", }, }, + + .notify_supervisor = true, }; diff --git a/src/core/unit.c b/src/core/unit.c index 2c6a0b3e572..c0f802a1375 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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); } diff --git a/src/core/unit.h b/src/core/unit.h index b1cc2c2d013..7134d362fe1 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -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; -- 2.47.3