summaryrefslogtreecommitdiff
path: root/meta-phosphor/recipes-core/systemd
diff options
context:
space:
mode:
Diffstat (limited to 'meta-phosphor/recipes-core/systemd')
-rw-r--r--meta-phosphor/recipes-core/systemd/systemd/0001-conf-parse-make-config_parse_many-optionally-save-st.patch379
-rw-r--r--meta-phosphor/recipes-core/systemd/systemd/0001-journal-network-timesync-fix-segfault-on-32bit-timev.patch66
-rw-r--r--meta-phosphor/recipes-core/systemd/systemd/0001-socket-util-introduce-CMSG_SPACE_TIMEVAL-TIMESPEC-ma.patch89
-rw-r--r--meta-phosphor/recipes-core/systemd/systemd_249.3.bbappend13
4 files changed, 383 insertions, 164 deletions
diff --git a/meta-phosphor/recipes-core/systemd/systemd/0001-conf-parse-make-config_parse_many-optionally-save-st.patch b/meta-phosphor/recipes-core/systemd/systemd/0001-conf-parse-make-config_parse_many-optionally-save-st.patch
new file mode 100644
index 000000000..fedb42d9b
--- /dev/null
+++ b/meta-phosphor/recipes-core/systemd/systemd/0001-conf-parse-make-config_parse_many-optionally-save-st.patch
@@ -0,0 +1,379 @@
+From 819333d81964fd110565d35a33993b831ba60725 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Mon, 25 Oct 2021 11:13:27 +0900
+Subject: [PATCH] conf-parse: make config_parse_many() optionally save 'struct
+ stat' for each file
+
+Fixes #21113.
+---
+ src/core/load-dropin.c | 18 +++---
+ src/network/networkd-network.c | 38 +++++++++---
+ src/network/networkd-network.h | 2 +-
+ src/shared/conf-parser.c | 103 +++++++++++++++++++++++++--------
+ src/shared/conf-parser.h | 8 ++-
+ 5 files changed, 127 insertions(+), 42 deletions(-)
+
+diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
+index 3bb48564cc..080a63bc7e 100644
+--- a/src/core/load-dropin.c
++++ b/src/core/load-dropin.c
+@@ -113,14 +113,16 @@ int unit_load_dropin(Unit *u) {
+ }
+
+ u->dropin_mtime = 0;
+- STRV_FOREACH(f, u->dropin_paths)
+- (void) config_parse(
+- u->id, *f, NULL,
+- UNIT_VTABLE(u)->sections,
+- config_item_perf_lookup, load_fragment_gperf_lookup,
+- 0,
+- u,
+- &u->dropin_mtime);
++ STRV_FOREACH(f, u->dropin_paths) {
++ struct stat st;
++
++ r = config_parse(u->id, *f, NULL,
++ UNIT_VTABLE(u)->sections,
++ config_item_perf_lookup, load_fragment_gperf_lookup,
++ 0, u, &st);
++ if (r > 0)
++ u->dropin_mtime = MAX(u->dropin_mtime, timespec_load(&st.st_mtim));
++ }
+
+ return 0;
+ }
+diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
+index 850b4f449e..32d76e29e4 100644
+--- a/src/network/networkd-network.c
++++ b/src/network/networkd-network.c
+@@ -480,7 +480,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
+ config_item_perf_lookup, network_network_gperf_lookup,
+ CONFIG_PARSE_WARN,
+ network,
+- &network->timestamp);
++ &network->stats_by_path);
+ if (r < 0)
+ return r;
+
+@@ -527,6 +527,28 @@ int network_load(Manager *manager, OrderedHashmap **networks) {
+ return 0;
+ }
+
++static bool stats_by_path_equal(Hashmap *a, Hashmap *b) {
++ struct stat *st_a, *st_b;
++ const char *path;
++
++ assert(a);
++ assert(b);
++
++ if (hashmap_size(a) != hashmap_size(b))
++ return false;
++
++ HASHMAP_FOREACH_KEY(st_a, path, a) {
++ st_b = hashmap_get(b, path);
++ if (!st_b)
++ return false;
++
++ if (!stat_inode_unmodified(st_a, st_b))
++ return false;
++ }
++
++ return true;
++}
++
+ int network_reload(Manager *manager) {
+ OrderedHashmap *new_networks = NULL;
+ Network *n, *old;
+@@ -540,14 +562,15 @@ int network_reload(Manager *manager) {
+
+ ORDERED_HASHMAP_FOREACH(n, new_networks) {
+ r = network_get_by_name(manager, n->name, &old);
+- if (r < 0)
+- continue; /* The .network file is new. */
+-
+- if (n->timestamp != old->timestamp)
+- continue; /* The .network file is modified. */
++ if (r < 0) {
++ log_debug("Found new .network file: %s", n->filename);
++ continue;
++ }
+
+- if (!streq(n->filename, old->filename))
++ if (!stats_by_path_equal(n->stats_by_path, old->stats_by_path)) {
++ log_debug("Found updated .network file: %s", n->filename);
+ continue;
++ }
+
+ r = ordered_hashmap_replace(new_networks, old->name, old);
+ if (r < 0)
+@@ -573,6 +596,7 @@ static Network *network_free(Network *network) {
+ return NULL;
+
+ free(network->filename);
++ hashmap_free(network->stats_by_path);
+
+ net_match_clear(&network->match);
+ condition_free_list(network->conditions);
+diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
+index b39063fe8a..c8d24a415f 100644
+--- a/src/network/networkd-network.h
++++ b/src/network/networkd-network.h
+@@ -72,7 +72,7 @@ struct Network {
+
+ char *name;
+ char *filename;
+- usec_t timestamp;
++ Hashmap *stats_by_path;
+ char *description;
+
+ /* [Match] section */
+diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
+index d0ac1b2660..9a367d757f 100644
+--- a/src/shared/conf-parser.c
++++ b/src/shared/conf-parser.c
+@@ -264,21 +264,18 @@ int config_parse(
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+- usec_t *latest_mtime) {
++ struct stat *ret_stat) {
+
+ _cleanup_free_ char *section = NULL, *continuation = NULL;
+ _cleanup_fclose_ FILE *ours = NULL;
+ unsigned line = 0, section_line = 0;
+ bool section_ignored = false, bom_seen = false;
++ struct stat st;
+ int r, fd;
+- usec_t mtime;
+
+ assert(filename);
+ assert(lookup);
+
+- /* latest_mtime is an input-output parameter: it will be updated if the mtime of the file we're
+- * looking at is later than the current *latest_mtime value. */
+-
+ if (!f) {
+ f = ours = fopen(filename, "re");
+ if (!f) {
+@@ -287,22 +284,28 @@ int config_parse(
+ if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT)
+ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
+ "Failed to open configuration file '%s': %m", filename);
+- return errno == ENOENT ? 0 : -errno;
++
++ if (errno == ENOENT) {
++ if (ret_stat)
++ *ret_stat = (struct stat) {};
++
++ return 0;
++ }
++
++ return -errno;
+ }
+ }
+
+ fd = fileno(f);
+ if (fd >= 0) { /* stream might not have an fd, let's be careful hence */
+- struct stat st;
+
+ if (fstat(fd, &st) < 0)
+ return log_full_errno(FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_ERR : LOG_DEBUG, errno,
+ "Failed to fstat(%s): %m", filename);
+
+ (void) stat_warn_permissions(filename, &st);
+- mtime = timespec_load(&st.st_mtim);
+ } else
+- mtime = 0;
++ st = (struct stat) {};
+
+ for (;;) {
+ _cleanup_free_ char *buf = NULL;
+@@ -422,12 +425,43 @@ int config_parse(
+ }
+ }
+
+- if (latest_mtime)
+- *latest_mtime = MAX(*latest_mtime, mtime);
++ if (ret_stat)
++ *ret_stat = st;
+
+ return 1;
+ }
+
++static int hashmap_put_stats_by_path(Hashmap **stats_by_path, const char *path, const struct stat *st) {
++ _cleanup_free_ struct stat *st_copy = NULL;
++ _cleanup_free_ char *path_copy = NULL;
++ int r;
++
++ assert(stats_by_path);
++ assert(path);
++ assert(st);
++
++ r = hashmap_ensure_allocated(stats_by_path, &path_hash_ops_free_free);
++ if (r < 0)
++ return r;
++
++ st_copy = newdup(struct stat, st, 1);
++ if (!st_copy)
++ return -ENOMEM;
++
++ path_copy = strdup(path);
++ if (!path)
++ return -ENOMEM;
++
++ r = hashmap_put(*stats_by_path, path_copy, st_copy);
++ if (r < 0)
++ return r;
++
++ assert(r > 0);
++ TAKE_PTR(path_copy);
++ TAKE_PTR(st_copy);
++ return 0;
++}
++
+ static int config_parse_many_files(
+ const char* const* conf_files,
+ char **files,
+@@ -436,30 +470,53 @@ static int config_parse_many_files(
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+- usec_t *ret_mtime) {
++ Hashmap **ret_stats_by_path) {
+
+- usec_t mtime = 0;
++ _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
++ struct stat st;
+ char **fn;
+ int r;
+
++ if (ret_stats_by_path) {
++ stats_by_path = hashmap_new(&path_hash_ops_free_free);
++ if (!stats_by_path)
++ return -ENOMEM;
++ }
++
+ /* First read the first found main config file. */
+ STRV_FOREACH(fn, (char**) conf_files) {
+- r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &mtime);
++ r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &st);
+ if (r < 0)
+ return r;
+- if (r > 0)
+- break;
++ if (r == 0)
++ continue;
++
++ if (ret_stats_by_path) {
++ r = hashmap_put_stats_by_path(&stats_by_path, *fn, &st);
++ if (r < 0)
++ return r;
++ }
++
++ break;
+ }
+
+ /* Then read all the drop-ins. */
+ STRV_FOREACH(fn, files) {
+- r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &mtime);
++ r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &st);
+ if (r < 0)
+ return r;
++ if (r == 0)
++ continue;
++
++ if (ret_stats_by_path) {
++ r = hashmap_put_stats_by_path(&stats_by_path, *fn, &st);
++ if (r < 0)
++ return r;
++ }
+ }
+
+- if (ret_mtime)
+- *ret_mtime = mtime;
++ if (ret_stats_by_path)
++ *ret_stats_by_path = TAKE_PTR(stats_by_path);
+
+ return 0;
+ }
+@@ -473,7 +530,7 @@ int config_parse_many_nulstr(
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+- usec_t *ret_mtime) {
++ Hashmap **ret_stats_by_path) {
+
+ _cleanup_strv_free_ char **files = NULL;
+ int r;
+@@ -484,7 +541,7 @@ int config_parse_many_nulstr(
+
+ return config_parse_many_files(STRV_MAKE_CONST(conf_file),
+ files, sections, lookup, table, flags, userdata,
+- ret_mtime);
++ ret_stats_by_path);
+ }
+
+ /* Parse each config file in the directories specified as strv. */
+@@ -497,7 +554,7 @@ int config_parse_many(
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+- usec_t *ret_mtime) {
++ Hashmap **ret_stats_by_path) {
+
+ _cleanup_strv_free_ char **dropin_dirs = NULL;
+ _cleanup_strv_free_ char **files = NULL;
+@@ -513,7 +570,7 @@ int config_parse_many(
+ if (r < 0)
+ return r;
+
+- return config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_mtime);
++ return config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
+ }
+
+ #define DEFINE_PARSER(type, vartype, conv_func) \
+diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
+index c3a138274d..f893a53aa0 100644
+--- a/src/shared/conf-parser.h
++++ b/src/shared/conf-parser.h
+@@ -6,8 +6,10 @@
+ #include <stddef.h>
+ #include <stdio.h>
+ #include <syslog.h>
++#include <sys/stat.h>
+
+ #include "alloc-util.h"
++#include "hashmap.h"
+ #include "log.h"
+ #include "macro.h"
+ #include "time-util.h"
+@@ -89,7 +91,7 @@ int config_parse(
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+- usec_t *latest_mtime); /* input/output, possibly NULL */
++ struct stat *ret_stat); /* possibly NULL */
+
+ int config_parse_many_nulstr(
+ const char *conf_file, /* possibly NULL */
+@@ -99,7 +101,7 @@ int config_parse_many_nulstr(
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+- usec_t *ret_mtime); /* possibly NULL */
++ Hashmap **ret_stats_by_path); /* possibly NULL */
+
+ int config_parse_many(
+ const char* const* conf_files, /* possibly empty */
+@@ -110,7 +112,7 @@ int config_parse_many(
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+- usec_t *ret_mtime); /* possibly NULL */
++ Hashmap **ret_stats_by_path); /* possibly NULL */
+
+ CONFIG_PARSER_PROTOTYPE(config_parse_int);
+ CONFIG_PARSER_PROTOTYPE(config_parse_unsigned);
+--
+2.33.0.1079.g6e70778dc9-goog
+
diff --git a/meta-phosphor/recipes-core/systemd/systemd/0001-journal-network-timesync-fix-segfault-on-32bit-timev.patch b/meta-phosphor/recipes-core/systemd/systemd/0001-journal-network-timesync-fix-segfault-on-32bit-timev.patch
deleted file mode 100644
index c3af62e15..000000000
--- a/meta-phosphor/recipes-core/systemd/systemd/0001-journal-network-timesync-fix-segfault-on-32bit-timev.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 83676e4278cecb44316e6ae88e1365e6fcfdd4ff Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Wed, 15 Sep 2021 23:29:11 +0900
-Subject: [PATCH] journal,network,timesync: fix segfault on 32bit
- timeval/timespec systems
-
-Fixes #20741.
----
- src/journal/journald-server.c | 7 +++++--
- src/libsystemd-network/icmp6-util.c | 3 ++-
- src/timesync/timesyncd-manager.c | 3 ++-
- 3 files changed, 9 insertions(+), 4 deletions(-)
-
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index abd52f7c14..2d1d9e66d7 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -1275,11 +1275,14 @@ int server_process_datagram(
- /* We use NAME_MAX space for the SELinux label here. The kernel currently enforces no limit, but
- * according to suggestions from the SELinux people this will change and it will probably be
- * identical to NAME_MAX. For now we use that, but this should be updated one day when the final
-- * limit is known. */
-+ * limit is known.
-+ *
-+ * Here, we need to explicitly initialize the buffer with zero, as glibc has a bug in
-+ * __convert_scm_timestamps(), which assumes the buffer is initialized. See #20741. */
- CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE_TIMEVAL +
- CMSG_SPACE(sizeof(int)) + /* fd */
-- CMSG_SPACE(NAME_MAX) /* selinux label */) control;
-+ CMSG_SPACE(NAME_MAX) /* selinux label */) control = {};
-
- union sockaddr_union sa = {};
-
-diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c
-index 823be0f275..3832bbd920 100644
---- a/src/libsystemd-network/icmp6-util.c
-+++ b/src/libsystemd-network/icmp6-util.c
-@@ -148,8 +148,9 @@ int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
- int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
- triple_timestamp *ret_timestamp) {
-
-+ /* This needs to be initialized with zero. See #20741. */
- CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
-- CMSG_SPACE_TIMEVAL) control;
-+ CMSG_SPACE_TIMEVAL) control = {};
- struct iovec iov = {};
- union sockaddr_union sa = {};
- struct msghdr msg = {
-diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
-index 648e804105..e37db1c570 100644
---- a/src/timesync/timesyncd-manager.c
-+++ b/src/timesync/timesyncd-manager.c
-@@ -412,7 +412,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
- .iov_base = &ntpmsg,
- .iov_len = sizeof(ntpmsg),
- };
-- CMSG_BUFFER_TYPE(CMSG_SPACE_TIMESPEC) control;
-+ /* This needs to be initialized with zero. See #20741. */
-+ CMSG_BUFFER_TYPE(CMSG_SPACE_TIMESPEC) control = {};
- union sockaddr_union server_addr;
- struct msghdr msghdr = {
- .msg_iov = &iov,
---
-2.33.0.309.g3052b89438-goog
-
diff --git a/meta-phosphor/recipes-core/systemd/systemd/0001-socket-util-introduce-CMSG_SPACE_TIMEVAL-TIMESPEC-ma.patch b/meta-phosphor/recipes-core/systemd/systemd/0001-socket-util-introduce-CMSG_SPACE_TIMEVAL-TIMESPEC-ma.patch
deleted file mode 100644
index 3e376ed3a..000000000
--- a/meta-phosphor/recipes-core/systemd/systemd/0001-socket-util-introduce-CMSG_SPACE_TIMEVAL-TIMESPEC-ma.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
-index f92e425fd6..09e606614c 100644
---- a/src/basic/socket-util.h
-+++ b/src/basic/socket-util.h
-@@ -277,6 +277,28 @@ static inline int getsockopt_int(int fd, int level, int optname, int *ret) {
- int socket_bind_to_ifname(int fd, const char *ifname);
- int socket_bind_to_ifindex(int fd, int ifindex);
-
-+/* Define a 64bit version of timeval/timespec in any case, even on 32bit userspace. */
-+struct timeval_large {
-+ uint64_t tvl_sec, tvl_usec;
-+};
-+struct timespec_large {
-+ uint64_t tvl_sec, tvl_nsec;
-+};
-+
-+/* glibc duplicates timespec/timeval on certain 32bit archs, once in 32bit and once in 64bit.
-+ * See __convert_scm_timestamps() in glibc source code. Hence, we need additional buffer space for them
-+ * to prevent from recvmsg_safe() returning -EXFULL. */
-+#define CMSG_SPACE_TIMEVAL \
-+ ((sizeof(struct timeval) == sizeof(struct timeval_large)) ? \
-+ CMSG_SPACE(sizeof(struct timeval)) : \
-+ CMSG_SPACE(sizeof(struct timeval)) + \
-+ CMSG_SPACE(sizeof(struct timeval_large)))
-+#define CMSG_SPACE_TIMESPEC \
-+ ((sizeof(struct timespec) == sizeof(struct timespec_large)) ? \
-+ CMSG_SPACE(sizeof(struct timespec)) : \
-+ CMSG_SPACE(sizeof(struct timespec)) + \
-+ CMSG_SPACE(sizeof(struct timespec_large)))
-+
- ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
-
- int socket_get_family(int fd, int *ret);
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index a0695ec519..abd52f7c14 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -1277,7 +1277,7 @@ int server_process_datagram(
- * identical to NAME_MAX. For now we use that, but this should be updated one day when the final
- * limit is known. */
- CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
-- CMSG_SPACE(sizeof(struct timeval)) +
-+ CMSG_SPACE_TIMEVAL +
- CMSG_SPACE(sizeof(int)) + /* fd */
- CMSG_SPACE(NAME_MAX) /* selinux label */) control;
-
-diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c
-index 67c6b55d84..823be0f275 100644
---- a/src/libsystemd-network/icmp6-util.c
-+++ b/src/libsystemd-network/icmp6-util.c
-@@ -149,7 +149,7 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
- triple_timestamp *ret_timestamp) {
-
- CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
-- CMSG_SPACE(sizeof(struct timeval))) control;
-+ CMSG_SPACE_TIMEVAL) control;
- struct iovec iov = {};
- union sockaddr_union sa = {};
- struct msghdr msg = {
-@@ -186,7 +186,6 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
-
- /* namelen == 0 only happens when running the test-suite over a socketpair */
-
-- assert(!(msg.msg_flags & MSG_CTRUNC));
- assert(!(msg.msg_flags & MSG_TRUNC));
-
- CMSG_FOREACH(cmsg, &msg) {
-diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
-index 9d874cfc8a..648e804105 100644
---- a/src/timesync/timesyncd-manager.c
-+++ b/src/timesync/timesyncd-manager.c
-@@ -412,7 +412,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
- .iov_base = &ntpmsg,
- .iov_len = sizeof(ntpmsg),
- };
-- CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct timespec))) control;
-+ CMSG_BUFFER_TYPE(CMSG_SPACE_TIMESPEC) control;
- union sockaddr_union server_addr;
- struct msghdr msghdr = {
- .msg_iov = &iov,
-@@ -467,6 +467,8 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
-
- switch (cmsg->cmsg_type) {
- case SCM_TIMESTAMPNS:
-+ assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct timespec)));
-+
- recv_time = (struct timespec *) CMSG_DATA(cmsg);
- break;
- }
diff --git a/meta-phosphor/recipes-core/systemd/systemd_249.3.bbappend b/meta-phosphor/recipes-core/systemd/systemd_249.3.bbappend
index 1a58ca139..41bdcf908 100644
--- a/meta-phosphor/recipes-core/systemd/systemd_249.3.bbappend
+++ b/meta-phosphor/recipes-core/systemd/systemd_249.3.bbappend
@@ -1,10 +1,5 @@
-# Backport a fix that is only in main, otherwise all received RAs will fail
-# to be parsed.
-SRC_URI += "file://0001-socket-util-introduce-CMSG_SPACE_TIMEVAL-TIMESPEC-ma.patch"
+# Pin to v249.5 to fix systemd-networkd issues.
+SRCREV = "00b0393e65252bf631670604f58b844780b08c50"
-# Pin to v249.4 to fix systemd-networkd segfaults.
-SRCREV = "4d8fd88b9641fce81272f60f556543f713175403"
-
-# Additional unsubmitted PR #20752 required to fix additional systemd-networkd
-# segfaults.
-SRC_URI += "file://0001-journal-network-timesync-fix-segfault-on-32bit-timev.patch"
+# Fix https://github.com/systemd/systemd/issues/21113
+SRC_URI += "file://0001-conf-parse-make-config_parse_many-optionally-save-st.patch"