From 4b58153dd22172d817055d2a09a0cdf3f4bd9db3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 30 Aug 2016 23:18:46 +0200 Subject: core: add "invocation ID" concept to service manager This adds a new invocation ID concept to the service manager. The invocation ID identifies each runtime cycle of a unit uniquely. A new randomized 128bit ID is generated each time a unit moves from and inactive to an activating or active state. The primary usecase for this concept is to connect the runtime data PID 1 maintains about a service with the offline data the journal stores about it. Previously we'd use the unit name plus start/stop times, which however is highly racy since the journal will generally process log data after the service already ended. The "invocation ID" kinda matches the "boot ID" concept of the Linux kernel, except that it applies to an individual unit instead of the whole system. The invocation ID is passed to the activated processes as environment variable. It is additionally stored as extended attribute on the cgroup of the unit. The latter is used by journald to automatically retrieve it for each log logged message and attach it to the log entry. The environment variable is very easily accessible, even for unprivileged services. OTOH the extended attribute is only accessible to privileged processes (this is because cgroupfs only supports the "trusted." xattr namespace, not "user."). The environment variable may be altered by services, the extended attribute may not be, hence is the better choice for the journal. Note that reading the invocation ID off the extended attribute from journald is racy, similar to the way reading the unit name for a logging process is. This patch adds APIs to read the invocation ID to sd-id128: sd_id128_get_invocation() may be used in a similar fashion to sd_id128_get_boot(). PID1's own logging is updated to always include the invocation ID when it logs information about a unit. A new bus call GetUnitByInvocationID() is added that allows retrieving a bus path to a unit by its invocation ID. The bus path is built using the invocation ID, thus providing a path for referring to a unit that is valid only for the current runtime cycleof it. Outlook for the future: should the kernel eventually allow passing of cgroup information along AF_UNIX/SOCK_DGRAM messages via a unique cgroup id, then we can alter the invocation ID to be generated as hash from that rather than entirely randomly. This way we can derive the invocation race-freely from the messages. --- man/sd_id128_get_machine.xml | 34 ++++++++++++++++++++++------------ man/systemd.exec.xml | 10 ++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) (limited to 'man') diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml index 2ad1f8f728..9a86c24aed 100644 --- a/man/sd_id128_get_machine.xml +++ b/man/sd_id128_get_machine.xml @@ -45,6 +45,7 @@ sd_id128_get_machine sd_id128_get_boot + sd_id128_get_invocation Retrieve 128-bit IDs @@ -62,6 +63,11 @@ sd_id128_t *ret + + int sd_id128_get_invocation + sd_id128_t *ret + + @@ -83,11 +89,15 @@ for more information. This function also internally caches the returned ID to make this call a cheap operation. - Note that sd_id128_get_boot() always - returns a UUID v4 compatible ID. - sd_id128_get_machine() will also return a - UUID v4-compatible ID on new installations but might not on older. - It is possible to convert the machine ID into a UUID v4-compatible + sd_id128_get_invocation() returns the invocation ID of the currently executed + service. In its current implementation, this reads and parses the $INVOCATION_ID environment + variable that the service manager sets when activating a service, see + systemd.exec5 for details. The + ID is cached internally. In future a different mechanism to determine the invocation ID may be added. + + Note that sd_id128_get_boot() and sd_id128_get_invocation() always + return UUID v4 compatible IDs. sd_id128_get_machine() will also return a UUID v4-compatible + ID on new installations but might not on older. It is possible to convert the machine ID into a UUID v4-compatible one. For more information, see machine-id5. @@ -107,11 +117,10 @@ Notes - The sd_id128_get_machine() and - sd_id128_get_boot() interfaces are available - as a shared library, which can be compiled and linked to with the - libsystemd pkg-config1 - file. + The sd_id128_get_machine(), sd_id128_get_boot() and + sd_id128_get_invocation() interfaces are available as a shared library, which can be compiled + and linked to with the libsystemd pkg-config1 file. @@ -121,8 +130,9 @@ systemd1, sd-id1283, machine-id5, - random4, - sd_id128_randomize3 + systemd.exec5, + sd_id128_randomize3, + random4 diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 5e6787338d..c73ccaa493 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1513,6 +1513,16 @@ + + $INVOCATION_ID + + Contains a randomized, unique 128bit ID identifying each runtime cycle of the unit, formatted + as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into + an activating or active state, and may be used to identify this specific runtime cycle, in particular in data + stored offline, such as the journal. The same ID is passed to all processes run as part of the + unit. + + $XDG_RUNTIME_DIR -- cgit v1.2.1