1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-31 05:47:30 +03:00

core: notify supervisor over targets we reach, as we reach them

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.
This commit is contained in:
Lennart Poettering 2024-03-12 16:08:13 +01:00
parent ad60cdd050
commit b2d6bb5b34
5 changed files with 29 additions and 0 deletions

View 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);

View 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);

View File

@ -213,4 +213,6 @@ const UnitVTable target_vtable = {
[JOB_DONE] = "Stopped target %s.",
},
},
.notify_supervisor = true,
};

View 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);
}

View 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;