diff options
author | Luca Boccassi <bluca@debian.org> | 2023-03-22 22:44:31 +0000 |
---|---|---|
committer | Luca Boccassi <bluca@debian.org> | 2023-03-28 10:36:01 +0100 |
commit | 8c8331fc5075c2d82b13fb121b2571a12d1c54a0 (patch) | |
tree | b3cbb20899ca244d673b171001012b0dc4ccab99 | |
parent | 62b7c23f79bcbcbc141c90c3a0931fa46a1652a2 (diff) | |
download | systemd-8c8331fc5075c2d82b13fb121b2571a12d1c54a0.tar.gz |
portable: include base and extension images in log fields
When a portable service uses extensions, we use the 'main' image name
(the one where the unit was found in) as PORTABLE=. It is useful to
also list all the images actually used at runtime, as they might
contain libraries and so on.
Use PORTABLE_ROOT= for the image/directory that is used as RootImage=
or RootDirectory=, and PORTABLE_EXTENSION= for the image/directory that
is used as ExtensionImages= or ExtensionDirectories=.
Note that these new fields are only added if extensions are used,
there's no change for single-DDI portables.
Example with a base and two extensions, with the unit coming from the
first extension:
[Service]
RootImage=/home/bluca/git/systemd/base.raw
Environment=PORTABLE=app0.raw
BindReadOnlyPaths=/etc/os-release:/run/host/os-release
LogExtraFields=PORTABLE=app0.raw
LogExtraFields=PORTABLE_ROOT=base.raw
ExtensionImages=/home/bluca/git/systemd/app0.raw
LogExtraFields=PORTABLE_EXTENSION=app0.raw
ExtensionImages=/home/bluca/git/systemd/app1.raw
LogExtraFields=PORTABLE_EXTENSION=app1.raw
-rw-r--r-- | docs/PORTABLE_SERVICES.md | 21 | ||||
-rw-r--r-- | src/portable/portable.c | 30 |
2 files changed, 47 insertions, 4 deletions
diff --git a/docs/PORTABLE_SERVICES.md b/docs/PORTABLE_SERVICES.md index b12e7754e7..7936eebccb 100644 --- a/docs/PORTABLE_SERVICES.md +++ b/docs/PORTABLE_SERVICES.md @@ -335,6 +335,27 @@ service data may be placed on the host file system. Use `StateDirectory=` in the unit files to enable such behaviour and add a local data directory to the services copied onto the host. +## Logging + +Several fields are autotmatically added to log messages generated by a portable +service (or about a portable service, e.g.: start/stop logs from systemd). +The `PORTABLE=` field will refer to the name of the portable image where the unit +was loaded from. In case extensions are used, additionally there will be a +`PORTABLE_ROOT=` field, referring to the name of image used as the base layer +(i.e.: `RootImage=` or `RootDirectory=`), and one `PORTABLE_EXTENSION=` field per +each extension image used. + +For example, a portable service `app0` using two extensions `app0.raw` and +`app1.raw`, and a base layer `base.raw`, will create log entries with the +following fields: + +``` +PORTABLE=app0.raw +PORTABLE_ROOT=base.raw +PORTABLE_EXTENSION=app0.raw +PORTABLE_EXTENSION=app1.raw +``` + ## Links [`portablectl(1)`](https://www.freedesktop.org/software/systemd/man/portablectl.html)<br> diff --git a/src/portable/portable.c b/src/portable/portable.c index 2b06e61f75..d19253debb 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -994,19 +994,41 @@ static int install_chroot_dropin( "LogExtraFields=PORTABLE=", base_name, "\n")) return -ENOMEM; + if (!ordered_hashmap_isempty(extension_images)) { + _cleanup_free_ char *root_base_name = NULL; + + r = path_extract_filename(image_path, &root_base_name); + if (r < 0) + return log_debug_errno(r, "Failed to extract basename from '%s': %m", image_path); + + if (!strextend(&text, "LogExtraFields=PORTABLE_ROOT=", root_base_name, "\n")) + return -ENOMEM; + } + if (m->image_path && !path_equal(m->image_path, image_path)) - ORDERED_HASHMAP_FOREACH(ext, extension_images) + ORDERED_HASHMAP_FOREACH(ext, extension_images) { + _cleanup_free_ char *extension_base_name = NULL; + + r = path_extract_filename(ext->path, &extension_base_name); + if (r < 0) + return log_debug_errno(r, "Failed to extract basename from '%s': %m", ext->path); + if (!strextend(&text, + "\n", extension_setting_from_image(ext->type), ext->path, /* With --force tell PID1 to avoid enforcing that the image <name> and * extension-release.<name> have to match. */ !IN_SET(type, IMAGE_DIRECTORY, IMAGE_SUBVOLUME) && FLAGS_SET(flags, PORTABLE_FORCE_SYSEXT) ? - ":x-systemd.relax-extension-release-check" : - "", - "\n")) + ":x-systemd.relax-extension-release-check\n" : + "\n", + /* In PORTABLE= we list the 'main' image name for this unit + * (the image where the unit was extracted from), but we are + * stacking multiple images, so list those too. */ + "LogExtraFields=PORTABLE_EXTENSION=", extension_base_name, "\n")) return -ENOMEM; + } } r = write_string_file(dropin, text, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); |