From 28e014fed0373d971b45248a9f7ee31b01c0c1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 11 Jul 2023 23:43:46 +0200 Subject: [PATCH 1/4] sysusers: reduce duplication in param list definition --- src/sysusers/sysusers.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index cfa4823df7..8acda4ef25 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -867,13 +867,13 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **ret_tmpfile static int write_files(void) { _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL; _cleanup_(unlink_and_freep) char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL; - const char *passwd_path, *shadow_path, *group_path, *gshadow_path; int r; - passwd_path = prefix_roota(arg_root, "/etc/passwd"); - shadow_path = prefix_roota(arg_root, "/etc/shadow"); - group_path = prefix_roota(arg_root, "/etc/group"); - gshadow_path = prefix_roota(arg_root, "/etc/gshadow"); + const char + *passwd_path = prefix_roota(arg_root, "/etc/passwd"), + *shadow_path = prefix_roota(arg_root, "/etc/shadow"), + *group_path = prefix_roota(arg_root, "/etc/group"), + *gshadow_path = prefix_roota(arg_root, "/etc/gshadow"); r = write_temporary_group(group_path, &group, &group_tmp); if (r < 0) From 0134afe30d55716b57417245ce9dff9aea5f20f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 12 Jul 2023 00:03:47 +0200 Subject: [PATCH 2/4] TODO: put journal-related stuff together --- TODO | 134 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/TODO b/TODO index 04cab2e151..c3bb3d73a2 100644 --- a/TODO +++ b/TODO @@ -258,10 +258,6 @@ Features: both so that suid executables can only be placed there. Do this already in the initrd. If /usr/ is not split out create a bind mount automatically. -* rework journalctl -M to be based on a machined method that generates a mount - fd of the relevant journal dirs in the container with uidmapping applied to - allow the host to read it, while making everything read-only. - * fix our various hwdb lookup keys to end with ":" again. The original idea was that hwdb patterns can match arbitrary fields with expressions like "*:foobar:*", to wildcard match both the start and the end of the string. @@ -282,10 +278,6 @@ Features: * remove tomoyo support, it's obsolete and unmaintained apparently -* journald: add varlink service that allows subscribing to certain log events, - for example matching by message ID, or log level returns a list of journal - cursors as they happen. - * In .socket units, add ConnectStream=, ConnectDatagram=, ConnectSequentialPacket= that create a socket, and then *connect to* rather than listen on some socket. Then, add a new setting WriteData= that takes some @@ -315,20 +307,6 @@ Features: * SIGRTMIN+18 and memory pressure handling should still be added to: hostnamed, localed, oomd, timedated. -* journald: also collect CLOCK_BOOTTIME timestamps per log entry. Then, derive - "corrected" CLOCK_REALTIME information on display from that and the timestamp - info of the newest entry of the specific boot (as identified by the boot - ID). This way, if a system comes up without a valid clock but acquires a - better clock later, we can "fix" older entry timestamps on display, by - calculating backwards. We cannot use CLOCK_MONOTONIC for this, since it does - not account for suspend phases. This would then also enable us to correct the - kmsg timestamping we consume (where we erroneously assume the clock was in - CLOCK_MONOTONIC, but it actually is CLOCK_BOOTTIME as per kernel). - -* sd-journal puts a limit on parallel journal files to view at once. journald - should probably honour that same limit (JOURNAL_FILES_MAX) when vacuuming to - ensure we never generate more files than we can actually view. - * in order to make binding to PCR 4 realistic: - generate one keypair "U" and store it in a tpm2 nvindex. - Generate another keypair "P" and store it in a second tpm2 nvindex. @@ -396,18 +374,6 @@ Features: * homed: if for some reason the partition ended up being much smaller than whole disk, recover from that, and grow it again. -* in journald, write out a recognizable log record whenever the system clock is - changed ("stepped"), and in timesyncd whenever we acquire an NTP fix - ("slewing"). Then, in journalctl for each boot time we come across, find - these records, and use the structured info they include to display - "corrected" wallclock time, as calculated from the monotonic timestamp in the - log record, adjusted by the delta declared in the structured log record. - -* in journald: whenever we start a new journal file because the boot ID - changed, let's generate a recognizable log record containing info about old - and new ID. Then, when displaying log stream in journalctl look for these - records, to be able to order them. - * timesyncd: when saving/restoring clock try to take boot time into account. Specifically, along with the saved clock, store the current boot ID. When starting, check if the boot id matches. If so, don't do anything (we are on @@ -524,10 +490,6 @@ Features: - If run on every boot, should it use the sysupdate config from the host on subsequent boots? -* hook up journald with TPMs? measure new journal records to the TPM in regular - intervals, validate the journal against current TPM state with that. (taking - inspiration from IMA log) - * provide an API (probably IPC) to apps to encrypt/decrypt credentials. usecase: allow bluez bluetooth daemon to pass pairings to initrd that way, without shelling out to our tools. @@ -783,11 +745,6 @@ Features: and that determines from which overlayfs layer it originates, which image, and with what it was signed. -* journald: generate recognizable log events whenever we shutdown journald - cleanly, and when we migrate run → var. This way tools can verify that a - previous boot terminated cleanly, because either of these two messages must - be safely written to disk, then. - * systemd-creds: extend encryption logic to support asymmetric encryption/authentication. Idea: add new verb "systemd-creds public-key" which generates a priv/pub key pair on the TPM2 and stores the priv key @@ -1038,17 +995,6 @@ Features: uses RootDirectory= or RootImage=. (Might also over-mount /sys/class/dmi/id/*{uuid,serial} with /dev/null). -* journalctl/timesyncd: whenever timesyncd acquires a synchronization from NTP, - create a structured log entry that contains boot ID, monotonic clock and - realtime clock (I mean, this requires no special work, as these three fields - are implicit). Then in journalctl when attempting to display the realtime - timestamp of a log entry, first search for the closest later log entry - of this kinda that has a matching boot id, and convert the monotonic clock - timestamp of the entry to the realtime clock using this info. This way we can - retroactively correct the wallclock timestamps, in particular for systems - without RTC, i.e. where initially wallclock timestamps carry rubbish, until - an NTP sync is acquired. - * kernel-install: - add --all switch for rerunning kernel-install for all installed kernels @@ -1216,12 +1162,6 @@ Features: * systemd-sysext: optionally, run it in initrd already, before transitioning into host, to open up possibility for services shipped like that. -* maybe add a tool that displays most recent journal logs as QR code to scan - off screen and run it automatically on boot failures, emergency logs and - such. Use DRM APIs directly, see - https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset.c for an example - for doing that. - * introduce /dev/disk/root/* symlinks that allow referencing partitions on the disk the rootfs is on in a reasonably secure way. (or maybe: add /dev/gpt-auto-{home,srv,boot,…} similar in style to /dev/gpt-auto-root as we @@ -1461,13 +1401,8 @@ Features: * Move RestrictAddressFamily= to the new cgroup create socket -* maybe implicitly attach monotonic+realtime timestamps to outgoing messages in - log.c and sd-journal-send - * optionally: turn on cgroup delegation for per-session scope units -* introduce per-unit (i.e. per-slice, per-service) journal log size limits. - * sd-boot: optionally, show boot menu when previous default boot item has non-zero "tries done" count @@ -2084,8 +2019,70 @@ Features: time-based policy, so that the verification key can remain on host and ve validated via TPM. -* build short web pages out of each catalog entry, build them along with man - pages, and include hyperlinks to them in the journal output +* rework journalctl -M to be based on a machined method that generates a mount + fd of the relevant journal dirs in the container with uidmapping applied to + allow the host to read it, while making everything read-only. + +* journald: add varlink service that allows subscribing to certain log events, + for example matching by message ID, or log level returns a list of journal + cursors as they happen. + +* journald: also collect CLOCK_BOOTTIME timestamps per log entry. Then, derive + "corrected" CLOCK_REALTIME information on display from that and the timestamp + info of the newest entry of the specific boot (as identified by the boot + ID). This way, if a system comes up without a valid clock but acquires a + better clock later, we can "fix" older entry timestamps on display, by + calculating backwards. We cannot use CLOCK_MONOTONIC for this, since it does + not account for suspend phases. This would then also enable us to correct the + kmsg timestamping we consume (where we erroneously assume the clock was in + CLOCK_MONOTONIC, but it actually is CLOCK_BOOTTIME as per kernel). + +* in journald, write out a recognizable log record whenever the system clock is + changed ("stepped"), and in timesyncd whenever we acquire an NTP fix + ("slewing"). Then, in journalctl for each boot time we come across, find + these records, and use the structured info they include to display + "corrected" wallclock time, as calculted from the monotonic timestamp in the + log record, adjusted by the delta declared in the structured log record. + +* in journald: whenever we start a new journal file because the boot ID + changed, let's generate a recognizable log record containing info about old + and new ID. Then, when displaying log stream in journalctl look for these + records, to be able to order them. + +* journald: generate recognizable log events whenever we shutdown journald + cleanly, and when we migrate run → var. This way tools can verify that a + previous boot terminated cleanly, because either of these two messages must + be safely written to disk, then. + +* hook up journald with TPMs? measure new journal records to the TPM in regular + intervals, validate the journal against current TPM state with that. (taking + inspiration from IMA log) + +* sd-journal puts a limit on parallel journal files to view at once. journald + should probably honour that same limit (JOURNAL_FILES_MAX) when vacuuming to + ensure we never generate more files than we can actually view. + +* maybe add a tool that displays most recent journal logs as QR code to scan + off screen and run it automatically on boot failures, emergency logs and + such. Use DRM APIs directly, see + https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset.c for an example + for doing that. + +* maybe implicitly attach monotonic+realtime timestamps to outgoing messages in + log.c and sd-journal-send + +* journalctl/timesyncd: whenever timesyncd acquires a synchronization from NTP, + create a structured log entry that contains boot ID, monotonic clock and + realtime clock (I mean, this requires no special work, as these three fields + are implicit). Then in journalctl when attempting to display the realtime + timestamp of a log entry, first search for the closest later log entry + of this kinda that has a matching boot id, and convert the monotonic clock + timestamp of the entry to the realtime clock using this info. This way we can + retroactively correct the wallclock timestamps, in particular for systems + without RTC, i.e. where initially wallclock timestamps carry rubbish, until + an NTP sync is acquired. + +* introduce per-unit (i.e. per-slice, per-service) journal log size limits. * journald: do journal file writing out-of-process, with one writer process per client UID, so that synthetic hash table collisions can slow down a specific @@ -2112,6 +2109,9 @@ Features: being silently skipped. journalctl --update-catalog must warn about this, and we should also have a unit test to check that all our message are OK.) +* build short web pages out of each catalog entry, build them along with man + pages, and include hyperlinks to them in the journal output + * homed: - when user tries to log into record signed by unrecognized key, automatically add key to our chain after polkit auth - rollback when resize fails mid-operation From 9194c1e69727bc87c750e6ec2b2a74996b6f1d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 15 Jul 2023 15:05:43 +0200 Subject: [PATCH 3/4] sd-device, basic: align backslashes and drop unnecessary parens Follow-up for a1af83728f49c0b7487368d54cab90c8c87ac3f6 and 25077313747218f977e72bcd26af19ff477e3a7f. --- src/basic/terminal-util.h | 18 ++++----- src/libsystemd/sd-device/device-util.h | 54 +++++++++++++------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 7a9b0fde7c..945deb5c66 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -185,20 +185,20 @@ static inline const char *ansi_underline(void) { return underline_enabled() ? ANSI_UNDERLINE : ANSI_NORMAL; } -#define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME) \ - static inline const char *ansi_##name(void) { \ - return underline_enabled() ? ANSI_##NAME##_UNDERLINE : \ - colors_enabled() ? ANSI_##NAME : ""; \ +#define DEFINE_ANSI_FUNC_UNDERLINE(name, NAME) \ + static inline const char *ansi_##name(void) { \ + return underline_enabled() ? ANSI_##NAME##_UNDERLINE : \ + colors_enabled() ? ANSI_##NAME : ""; \ } -#define DEFINE_ANSI_FUNC_UNDERLINE_256(name, NAME, FALLBACK) \ - static inline const char *ansi_##name(void) { \ - switch (get_color_mode()) { \ - case COLOR_OFF: return ""; \ +#define DEFINE_ANSI_FUNC_UNDERLINE_256(name, NAME, FALLBACK) \ + static inline const char *ansi_##name(void) { \ + switch (get_color_mode()) { \ + case COLOR_OFF: return ""; \ case COLOR_16: return underline_enabled() ? ANSI_##FALLBACK##_UNDERLINE : ANSI_##FALLBACK; \ default : return underline_enabled() ? ANSI_##NAME##_UNDERLINE: ANSI_##NAME; \ - } \ + } \ } DEFINE_ANSI_FUNC(normal, NORMAL); diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h index 0316a60033..ceb37496dd 100644 --- a/src/libsystemd/sd-device/device-util.h +++ b/src/libsystemd/sd-device/device-util.h @@ -13,33 +13,33 @@ #define device_unref_and_replace(a, b) \ unref_and_replace_full(a, b, sd_device_ref, sd_device_unref) -#define FOREACH_DEVICE_PROPERTY(device, key, value) \ - for (const char *value, *key = sd_device_get_property_first(device, &(value)); \ - key; \ - key = sd_device_get_property_next(device, &(value))) +#define FOREACH_DEVICE_PROPERTY(device, key, value) \ + for (const char *value, *key = sd_device_get_property_first(device, &value); \ + key; \ + key = sd_device_get_property_next(device, &value)) -#define FOREACH_DEVICE_TAG(device, tag) \ - for (const char *tag = sd_device_get_tag_first(device); \ - tag; \ +#define FOREACH_DEVICE_TAG(device, tag) \ + for (const char *tag = sd_device_get_tag_first(device); \ + tag; \ tag = sd_device_get_tag_next(device)) -#define FOREACH_DEVICE_CURRENT_TAG(device, tag) \ +#define FOREACH_DEVICE_CURRENT_TAG(device, tag) \ for (const char *tag = sd_device_get_current_tag_first(device); \ - tag; \ + tag; \ tag = sd_device_get_current_tag_next(device)) -#define FOREACH_DEVICE_SYSATTR(device, attr) \ - for (const char *attr = sd_device_get_sysattr_first(device); \ - attr; \ +#define FOREACH_DEVICE_SYSATTR(device, attr) \ + for (const char *attr = sd_device_get_sysattr_first(device); \ + attr; \ attr = sd_device_get_sysattr_next(device)) -#define FOREACH_DEVICE_DEVLINK(device, devlink) \ +#define FOREACH_DEVICE_DEVLINK(device, devlink) \ for (const char *devlink = sd_device_get_devlink_first(device); \ - devlink; \ + devlink; \ devlink = sd_device_get_devlink_next(device)) #define _FOREACH_DEVICE_CHILD(device, child, suffix_ptr) \ - for (sd_device *child = sd_device_get_child_first(device, suffix_ptr); \ + for (sd_device *child = sd_device_get_child_first(device, suffix_ptr); \ child; \ child = sd_device_get_child_next(device, suffix_ptr)) @@ -49,14 +49,14 @@ #define FOREACH_DEVICE_CHILD_WITH_SUFFIX(device, child, suffix) \ _FOREACH_DEVICE_CHILD(device, child, &suffix) -#define FOREACH_DEVICE(enumerator, device) \ +#define FOREACH_DEVICE(enumerator, device) \ for (sd_device *device = sd_device_enumerator_get_device_first(enumerator); \ - device; \ + device; \ device = sd_device_enumerator_get_device_next(enumerator)) -#define FOREACH_SUBSYSTEM(enumerator, device) \ +#define FOREACH_SUBSYSTEM(enumerator, device) \ for (sd_device *device = sd_device_enumerator_get_subsystem_first(enumerator); \ - device; \ + device; \ device = sd_device_enumerator_get_subsystem_next(enumerator)) #define log_device_full_errno_zerook(device, level, error, ...) \ @@ -81,17 +81,17 @@ #define log_device_full(device, level, ...) (void) log_device_full_errno_zerook(device, level, 0, __VA_ARGS__) -#define log_device_debug(device, ...) log_device_full(device, LOG_DEBUG, __VA_ARGS__) -#define log_device_info(device, ...) log_device_full(device, LOG_INFO, __VA_ARGS__) -#define log_device_notice(device, ...) log_device_full(device, LOG_NOTICE, __VA_ARGS__) +#define log_device_debug(device, ...) log_device_full(device, LOG_DEBUG, __VA_ARGS__) +#define log_device_info(device, ...) log_device_full(device, LOG_INFO, __VA_ARGS__) +#define log_device_notice(device, ...) log_device_full(device, LOG_NOTICE, __VA_ARGS__) #define log_device_warning(device, ...) log_device_full(device, LOG_WARNING, __VA_ARGS__) -#define log_device_error(device, ...) log_device_full(device, LOG_ERR, __VA_ARGS__) +#define log_device_error(device, ...) log_device_full(device, LOG_ERR, __VA_ARGS__) -#define log_device_debug_errno(device, error, ...) log_device_full_errno(device, LOG_DEBUG, error, __VA_ARGS__) -#define log_device_info_errno(device, error, ...) log_device_full_errno(device, LOG_INFO, error, __VA_ARGS__) -#define log_device_notice_errno(device, error, ...) log_device_full_errno(device, LOG_NOTICE, error, __VA_ARGS__) +#define log_device_debug_errno(device, error, ...) log_device_full_errno(device, LOG_DEBUG, error, __VA_ARGS__) +#define log_device_info_errno(device, error, ...) log_device_full_errno(device, LOG_INFO, error, __VA_ARGS__) +#define log_device_notice_errno(device, error, ...) log_device_full_errno(device, LOG_NOTICE, error, __VA_ARGS__) #define log_device_warning_errno(device, error, ...) log_device_full_errno(device, LOG_WARNING, error, __VA_ARGS__) -#define log_device_error_errno(device, error, ...) log_device_full_errno(device, LOG_ERR, error, __VA_ARGS__) +#define log_device_error_errno(device, error, ...) log_device_full_errno(device, LOG_ERR, error, __VA_ARGS__) int devname_from_devnum(mode_t mode, dev_t devnum, char **ret); static inline int devname_from_stat_rdev(const struct stat *st, char **ret) { From 497cee30821d5f50d84fc9d3a062fba0333e5268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 17 Jul 2023 14:57:36 +0200 Subject: [PATCH 4/4] network: warning message fixlet "Address 1.2.3.4" works as a proper noun, so the article is not appropriate. --- src/network/networkd-address.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 21d08c8f37..c487d82a5c 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1741,7 +1741,7 @@ int config_parse_address( r = in_addr_prefix_from_string_auto(rvalue, &f, &buffer, &prefixlen); if (r >= 0) log_syntax(unit, LOG_WARNING, filename, line, r, - "An address '%s' is specified without prefix length. Assuming the prefix length is %u." + "Address '%s' is specified without prefix length. Assuming the prefix length is %u." "Please specify the prefix length explicitly.", rvalue, prefixlen); } if (r < 0) {