systemd: fix some issues in systemd v252.4
After PR-60270, systemd update to v252.4.
In this version, there are some problems that will affect gBMC.
refs:
https://github.com/systemd/systemd/commit/2cbb171d20a07ec0a25296f167b0385de102d74e
https://github.com/systemd/systemd/commit/782418a166e46a5862562479217e3ff98f81feb7
Google-Bug-Id: 267573639
Google-Bug-Id: 273819300
Google-Bug-Id: 273818953
Change-Id: I4f708c26e4265ccc82deb8f3a5706fe007adf4bf
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/recipes-core/systemd/systemd/0001-busctl-fix-introspecting-DBus-properties.patch b/recipes-core/systemd/systemd/0001-busctl-fix-introspecting-DBus-properties.patch
new file mode 100644
index 0000000..8c06589
--- /dev/null
+++ b/recipes-core/systemd/systemd/0001-busctl-fix-introspecting-DBus-properties.patch
@@ -0,0 +1,69 @@
+From 2cbb171d20a07ec0a25296f167b0385de102d74e Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Fri, 13 Jan 2023 14:12:31 +0900
+Subject: [PATCH] busctl: fix introspecting DBus properties
+
+Follow-up for f2f7785d7a47ffa48ac929648794e1288509ddd8.
+
+Fixes #26033.
+
+Patch Tracking Bug: b/273819300
+Upstream info / review:
+https://github.com/systemd/systemd/commit/2cbb171d20a07ec0a25296f167b0385de102d74e
+Upstream-Status: Accepted
+Justification: bugfix busctrl introspect
+---
+ src/busctl/busctl.c | 21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c
+index 32c6ed7cac..2b5552889b 100644
+--- a/src/busctl/busctl.c
++++ b/src/busctl/busctl.c
+@@ -1022,10 +1022,11 @@ static int introspect(int argc, char **argv, void *userdata) {
+
+ for (;;) {
+ Member *z;
+- _cleanup_free_ char *buf = NULL;
++ _cleanup_free_ char *buf = NULL, *signature = NULL;
+ _cleanup_fclose_ FILE *mf = NULL;
+ size_t sz = 0;
+- const char *name;
++ const char *name, *contents;
++ char type;
+
+ r = sd_bus_message_enter_container(reply, 'e', "sv");
+ if (r < 0)
+@@ -1042,6 +1043,21 @@ static int introspect(int argc, char **argv, void *userdata) {
+ if (r < 0)
+ return bus_log_parse_error(r);
+
++ r = sd_bus_message_peek_type(reply, &type, &contents);
++ if (r <= 0)
++ return bus_log_parse_error(r == 0 ? EINVAL : r);
++
++ if (type == SD_BUS_TYPE_STRUCT_BEGIN)
++ signature = strjoin(CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END));
++ else if (type == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
++ signature = strjoin(CHAR_TO_STR(SD_BUS_TYPE_DICT_ENTRY_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_DICT_ENTRY_END));
++ else if (contents)
++ signature = strjoin(CHAR_TO_STR(type), contents);
++ else
++ signature = strdup(CHAR_TO_STR(type));
++ if (!signature)
++ return log_oom();
++
+ mf = open_memstream_unlocked(&buf, &sz);
+ if (!mf)
+ return log_oom();
+@@ -1055,6 +1071,7 @@ static int introspect(int argc, char **argv, void *userdata) {
+ z = set_get(members, &((Member) {
+ .type = "property",
+ .interface = m->interface,
++ .signature = signature,
+ .name = (char*) name }));
+ if (z)
+ free_and_replace(z->value, buf);
+--
+2.25.1
+
diff --git a/recipes-core/systemd/systemd/0001-shutdown-move-busy-mounts-to-not-block-parent-mounts.patch b/recipes-core/systemd/systemd/0001-shutdown-move-busy-mounts-to-not-block-parent-mounts.patch
new file mode 100644
index 0000000..5227bb0
--- /dev/null
+++ b/recipes-core/systemd/systemd/0001-shutdown-move-busy-mounts-to-not-block-parent-mounts.patch
@@ -0,0 +1,205 @@
+From 204bf0ffe18c66c5b78224cd6ab53960cbb4e98f Mon Sep 17 00:00:00 2001
+From: Harvey Wu <Harvey.Wu@quantatw.com>
+Date: Tue, 31 Jan 2023 10:48:52 +0800
+Subject: [PATCH] shutdown: move busy mounts to not block parent mounts
+
+copy from: https://github.com/systemd/systemd/commit/782418a166e46a5862562479217e3ff98f81feb7
+
+Patch Tracking Bug: b/273818953
+Upstream info / review:
+https://github.com/systemd/systemd/commit/782418a166e46a5862562479217e3ff98f81feb7
+Upstream-Status: Accepted
+Justification: bugfix busctl introspect
+---
+ src/shared/libmount-util.h | 19 +++++++++++
+ src/shutdown/shutdown.c | 5 +++
+ src/shutdown/umount.c | 68 ++++++++++++++++++++++++++++++++++++--
+ src/shutdown/umount.h | 5 +--
+ 4 files changed, 93 insertions(+), 4 deletions(-)
+
+diff --git a/src/shared/libmount-util.h b/src/shared/libmount-util.h
+index cf19c56ed1..c407159d8d 100644
+--- a/src/shared/libmount-util.h
++++ b/src/shared/libmount-util.h
+@@ -45,3 +45,22 @@ static inline int libmount_parse(
+ *ret_iter = TAKE_PTR(iter);
+ return 0;
+ }
++
++static inline int libmount_is_leaf(
++ struct libmnt_table *table,
++ struct libmnt_fs *fs) {
++ int r;
++
++ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter_children = NULL;
++ iter_children = mnt_new_iter(MNT_ITER_FORWARD);
++ if (!iter_children)
++ return log_oom();
++
++ /* We care only whether it exists, it is unused */
++ _unused_ struct libmnt_fs *child;
++ r = mnt_table_next_child_fs(table, iter_children, fs, &child);
++ if (r < 0)
++ return r;
++
++ return r == 1;
++}
+diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c
+index dcee0f9006..309107ec35 100644
+--- a/src/shutdown/shutdown.c
++++ b/src/shutdown/shutdown.c
+@@ -399,6 +399,11 @@ int main(int argc, char *argv[]) {
+ /* Lock us into memory */
+ (void) mlockall(MCL_CURRENT|MCL_FUTURE);
+
++ /* We need to make mounts private so that we can MS_MOVE in unmount_all(). Kernel does not allow
++ * MS_MOVE when parent mountpoints have shared propagation. */
++ if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
++ log_warning_errno(errno, "Failed to make mounts private, ignoring: %m");
++
+ /* Synchronize everything that is not written to disk yet at this point already. This is a good idea so that
+ * slow IO is processed here already and the final process killing spree is not impacted by processes
+ * desperately trying to sync IO to disk within their timeout. Do not remove this sync, data corruption will
+diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
+index e650b82170..8b4b379802 100644
+--- a/src/shutdown/umount.c
++++ b/src/shutdown/umount.c
+@@ -23,6 +23,7 @@
+
+ #include "alloc-util.h"
+ #include "blockdev-util.h"
++#include "chase-symlinks.h"
+ #include "def.h"
+ #include "device-util.h"
+ #include "dirent-util.h"
+@@ -32,13 +33,16 @@
+ #include "fs-util.h"
+ #include "fstab-util.h"
+ #include "libmount-util.h"
++#include "mkdir.h"
+ #include "mount-setup.h"
+ #include "mount-util.h"
+ #include "mountpoint-util.h"
+ #include "parse-util.h"
+ #include "path-util.h"
+ #include "process-util.h"
++#include "random-util.h"
+ #include "signal-util.h"
++#include "stat-util.h"
+ #include "string-util.h"
+ #include "strv.h"
+ #include "sync-util.h"
+@@ -156,6 +160,11 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
+ if (!m)
+ return log_oom();
+
++ r = libmount_is_leaf(table, fs);
++ if (r < 0)
++ return log_error_errno(r, "Failed to get children mounts for %s from %s: %m", path, mountinfo ?: "/proc/self/mountinfo");
++ bool leaf = r;
++
+ *m = (MountPoint) {
+ .remount_options = remount_options,
+ .remount_flags = remount_flags,
+@@ -164,6 +173,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
+ /* Unmount sysfs/procfs/… lazily, since syncing doesn't matter there, and it's OK if
+ * something keeps an fd open to it. */
+ .umount_lazily = is_api_vfs,
++ .leaf = leaf,
+ };
+
+ m->path = strdup(path);
+@@ -682,7 +692,8 @@ static int umount_with_timeout(MountPoint *m, bool last_try) {
+ /* This includes remounting readonly, which changes the kernel mount options. Therefore the list passed to
+ * this function is invalidated, and should not be reused. */
+ static int mount_points_list_umount(MountPoint **head, bool *changed, bool last_try) {
+- int n_failed = 0;
++ int n_failed = 0, r;
++ _cleanup_free_ char *resolved_mounts_path = NULL;
+
+ assert(head);
+ assert(changed);
+@@ -717,10 +728,63 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool last_
+ continue;
+
+ /* Trying to umount */
+- if (umount_with_timeout(m, last_try) < 0)
++ r = umount_with_timeout(m, last_try);
++ if (r < 0)
+ n_failed++;
+ else
+ *changed = true;
++
++ /* If a mount is busy, we move it to not keep parent mount points busy.
++ * If a mount point is not a leaf, moving it would invalidate our mount table.
++ * More moving will occur in next iteration with a fresh mount table.
++ */
++ if (r != -EBUSY || !m->leaf)
++ continue;
++
++ _cleanup_free_ char *dirname = NULL;
++
++ r = path_extract_directory(m->path, &dirname);
++ if (r < 0) {
++ n_failed++;
++ log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Cannot find directory for %s: %m", m->path);
++ continue;
++ }
++
++ /* We need to canonicalize /run/shutdown/mounts. We cannot compare inodes, since /run
++ * might be bind mounted somewhere we want to unmount. And we need to move all mounts in
++ * /run/shutdown/mounts from there.
++ */
++ if (!resolved_mounts_path)
++ (void) chase_symlinks("/run/shutdown/mounts", NULL, 0, &resolved_mounts_path, NULL);
++ if (!path_equal(dirname, resolved_mounts_path)) {
++ char newpath[STRLEN("/run/shutdown/mounts/") + 16 + 1];
++
++ xsprintf(newpath, "/run/shutdown/mounts/%016" PRIx64, random_u64());
++
++ /* on error of is_dir, assume directory */
++ if (is_dir(m->path, true) != 0) {
++ r = mkdir_p(newpath, 0000);
++ if (r < 0) {
++ log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not create directory %s: %m", newpath);
++ continue;
++ }
++ } else {
++ r = touch_file(newpath, /* parents= */ true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0700);
++ if (r < 0) {
++ log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not create file %s: %m", newpath);
++ continue;
++ }
++ }
++
++ log_info("Moving mount %s to %s.", m->path, newpath);
++
++ r = RET_NERRNO(mount(m->path, newpath, NULL, MS_MOVE, NULL));
++ if (r < 0) {
++ n_failed++;
++ log_full_errno(last_try ? LOG_ERR : LOG_INFO, r, "Could not move %s to %s: %m", m->path, newpath);
++ } else
++ *changed = true;
++ }
+ }
+
+ return n_failed;
+diff --git a/src/shutdown/umount.h b/src/shutdown/umount.h
+index a4154c9099..a742ac0af5 100644
+--- a/src/shutdown/umount.h
++++ b/src/shutdown/umount.h
+@@ -18,8 +18,9 @@ typedef struct MountPoint {
+ char *path;
+ char *remount_options;
+ unsigned long remount_flags;
+- bool try_remount_ro:1;
+- bool umount_lazily:1;
++ bool try_remount_ro;
++ bool umount_lazily;
++ bool leaf;
+ dev_t devnum;
+ LIST_FIELDS(struct MountPoint, mount_point);
+ } MountPoint;
+--
+2.25.1
+
diff --git a/recipes-core/systemd/systemd_%.bbappend b/recipes-core/systemd/systemd_%.bbappend
index 44051a2..e9ae742 100644
--- a/recipes-core/systemd/systemd_%.bbappend
+++ b/recipes-core/systemd/systemd_%.bbappend
@@ -1,2 +1,6 @@
FILESEXTRAPATHS:prepend:gbmc := "${THISDIR}/systemd:"
-SRC_URI:append:gbmc = " file://0001-radv-Hardcode-shorter-RA-interval.patch"
+SRC_URI:append:gbmc = " \
+ file://0001-radv-Hardcode-shorter-RA-interval.patch \
+ file://0001-busctl-fix-introspecting-DBus-properties.patch \
+ file://0001-shutdown-move-busy-mounts-to-not-block-parent-mounts.patch \
+"