From 23fbf7cf1d61b320fd1eb88f9b6f72b30f3129e2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 3 Aug 2026 01:20:48 +0900 Subject: [PATCH] sysctl-util: introduce sysctl_write_verify() This is useful when writing coredump pattern. But the logic itself is quite generic. Let's add the helper in our basic library. Preparation for later change. --- src/basic/sysctl-util.c | 37 +++++++++++++++++++++++++++++++++++++ src/basic/sysctl-util.h | 1 + 2 files changed, 38 insertions(+) diff --git a/src/basic/sysctl-util.c b/src/basic/sysctl-util.c index 7bec823f421..9834d0323ad 100644 --- a/src/basic/sysctl-util.c +++ b/src/basic/sysctl-util.c @@ -114,6 +114,43 @@ int sysctl_writef(const char *property, const char *format, ...) { return sysctl_write(property, v); } +int sysctl_write_verify(const char *property, const char *value) { + int r; + + assert(property); + assert(value); + + /* Some sysctl settings accept invalid values on write, but refuses on read. E.g. coredump pattern, + * be1e0283021ec73c2eb92839db9a471a068709d9 (v6.17) and 7d7c1fb85cba5627bbe741fb7539c709435e3848 + * (v6.16.8), which is fixed by a779e27f24aeb679969ddd1fdd7f636e22ddbc1e (v6.18) and + * 304aa560385720baf3660fe8500f6dd425b63ea9 (v6.17.5). Let's first save the original value, and + * restore to the saved value if the new value is refused. */ + + _cleanup_free_ char *original = NULL; + r = sysctl_read(property, &original); + if (r >= 0 && streq(original, value)) + return 0; /* Already set. */ + + r = sysctl_write(property, value); + if (r >= 0) { + _cleanup_free_ char *current = NULL; + r = sysctl_read(property, ¤t); + if (r >= 0) { + if (streq(current, value)) + return 0; /* Yay! */ + + /* At least for coredump pattern, this does not happen, but let's handle this as the + * same as we wrote something invalid. */ + r = -EINVAL; + } + } + + if (original) + (void) sysctl_write(property, original); + + return r; +} + static const char* af_to_sysctl_dir(int af) { if (af == AF_MPLS) return "mpls"; diff --git a/src/basic/sysctl-util.h b/src/basic/sysctl-util.h index a65c40b43f9..1e706c839cf 100644 --- a/src/basic/sysctl-util.h +++ b/src/basic/sysctl-util.h @@ -12,6 +12,7 @@ int sysctl_writef(const char *property, const char *format, ...) _printf_(2, 3); static inline int sysctl_write(const char *property, const char *value) { return sysctl_write_full(property, value, NULL); } +int sysctl_write_verify(const char *property, const char *value); int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret); int sysctl_read_ip_property_int(int af, const char *ifname, const char *property, int *ret);