From: Daan De Meyer Date: Wed, 29 Nov 2023 13:15:00 +0000 (+0100) Subject: core: Use RateLimit struct to store ratelimits X-Git-Tag: v257-rc1~705^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14702b9c18b73130e98a9c0d65697adf54a1bcfc;p=thirdparty%2Fsystemd.git core: Use RateLimit struct to store ratelimits This makes it easier to serialize these ratelimits with JSON_BUILD_CALLBACK(). --- diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 264e2f0af64..2954f63422e 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -1111,8 +1111,8 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_ratelimit_interval_usec), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_ratelimit_burst), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_ratelimit.burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LogFilterPatterns", "a(bs)", property_get_log_filter_patterns, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LogNamespace", "s", NULL, offsetof(ExecContext, log_namespace), SD_BUS_VTABLE_PROPERTY_CONST), @@ -1730,10 +1730,10 @@ int bus_exec_context_set_transient_property( return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error); if (streq(name, "LogRateLimitIntervalUSec")) - return bus_set_transient_usec(u, name, &c->log_ratelimit_interval_usec, message, flags, error); + return bus_set_transient_usec(u, name, &c->log_ratelimit.interval, message, flags, error); if (streq(name, "LogRateLimitBurst")) - return bus_set_transient_unsigned(u, name, &c->log_ratelimit_burst, message, flags, error); + return bus_set_transient_unsigned(u, name, &c->log_ratelimit.burst, message, flags, error); if (streq(name, "LogFilterPatterns")) { /* Use _cleanup_free_, not _cleanup_strv_free_, as we don't want the content of the strv diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 3d2796f2c41..e88bb50c802 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -3112,11 +3112,11 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("DefaultTimeoutAbortUSec", "t", property_get_default_timeout_abort_usec, 0, 0), SD_BUS_PROPERTY("DefaultDeviceTimeoutUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.device_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.restart_usec), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), /* The following two items are obsolete alias */ - SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), - SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), - SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, defaults.start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), + SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, defaults.start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), + SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, defaults.start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultIOAccounting", "b", bus_property_get_bool, offsetof(Manager, defaults.io_accounting), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 2ab4961b2b0..545bef5af51 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -112,8 +112,8 @@ const sd_bus_vtable bus_socket_vtable[] = { SD_BUS_PROPERTY("SocketProtocol", "i", bus_property_get_int, offsetof(Socket, socket_protocol), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TriggerLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, trigger_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TriggerLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, trigger_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("PollLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, poll_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("PollLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, poll_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PollLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, poll_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PollLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, poll_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION), @@ -237,7 +237,7 @@ static int bus_socket_set_transient_property( return bus_set_transient_unsigned(u, name, &s->trigger_limit.burst, message, flags, error); if (streq(name, "PollLimitBurst")) - return bus_set_transient_unsigned(u, name, &s->poll_limit_burst, message, flags, error); + return bus_set_transient_unsigned(u, name, &s->poll_limit.burst, message, flags, error); if (streq(name, "SocketMode")) return bus_set_transient_mode_t(u, name, &s->socket_mode, message, flags, error); @@ -267,7 +267,7 @@ static int bus_socket_set_transient_property( return bus_set_transient_usec(u, name, &s->trigger_limit.interval, message, flags, error); if (streq(name, "PollLimitIntervalUSec")) - return bus_set_transient_usec(u, name, &s->poll_limit_interval, message, flags, error); + return bus_set_transient_usec(u, name, &s->poll_limit.interval, message, flags, error); if (streq(name, "SmackLabel")) return bus_set_transient_string(u, name, &s->smack, message, flags, error); diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c index 237d26044ed..38bd9695604 100644 --- a/src/core/execute-serialize.c +++ b/src/core/execute-serialize.c @@ -2174,14 +2174,14 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { if (r < 0) return r; - if (c->log_ratelimit_interval_usec > 0) { - r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit_interval_usec); + if (c->log_ratelimit.interval > 0) { + r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval); if (r < 0) return r; } - if (c->log_ratelimit_burst > 0) { - r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit_burst); + if (c->log_ratelimit.burst > 0) { + r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst); if (r < 0) return r; } @@ -3112,11 +3112,11 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { if (r < 0) return r; } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) { - r = deserialize_usec(val, &c->log_ratelimit_interval_usec); + r = deserialize_usec(val, &c->log_ratelimit.interval); if (r < 0) return r; } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) { - r = safe_atou(val, &c->log_ratelimit_burst); + r = safe_atou(val, &c->log_ratelimit.burst); if (r < 0) return r; } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) { diff --git a/src/core/execute.c b/src/core/execute.c index e1a94587a19..c2735fc998c 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -626,8 +626,7 @@ void exec_context_done(ExecContext *c) { c->log_filter_allowed_patterns = set_free_free(c->log_filter_allowed_patterns); c->log_filter_denied_patterns = set_free_free(c->log_filter_denied_patterns); - c->log_ratelimit_interval_usec = 0; - c->log_ratelimit_burst = 0; + c->log_ratelimit = (RateLimit) {}; c->stdin_data = mfree(c->stdin_data); c->stdin_data_size = 0; @@ -1216,13 +1215,13 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { fprintf(f, "%sLogLevelMax: %s\n", prefix, strna(t)); } - if (c->log_ratelimit_interval_usec > 0) + if (c->log_ratelimit.interval > 0) fprintf(f, "%sLogRateLimitIntervalSec: %s\n", - prefix, FORMAT_TIMESPAN(c->log_ratelimit_interval_usec, USEC_PER_SEC)); + prefix, FORMAT_TIMESPAN(c->log_ratelimit.interval, USEC_PER_SEC)); - if (c->log_ratelimit_burst > 0) - fprintf(f, "%sLogRateLimitBurst: %u\n", prefix, c->log_ratelimit_burst); + if (c->log_ratelimit.burst > 0) + fprintf(f, "%sLogRateLimitBurst: %u\n", prefix, c->log_ratelimit.burst); if (!set_isempty(c->log_filter_allowed_patterns) || !set_isempty(c->log_filter_denied_patterns)) { fprintf(f, "%sLogFilterPatterns:", prefix); diff --git a/src/core/execute.h b/src/core/execute.h index 22d72c8959f..15c7473a7ca 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -302,8 +302,7 @@ struct ExecContext { Set *log_filter_allowed_patterns; Set *log_filter_denied_patterns; - usec_t log_ratelimit_interval_usec; - unsigned log_ratelimit_burst; + RateLimit log_ratelimit; int log_level_max; diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in index 9a78e22fb52..7441d3c759b 100644 --- a/src/core/load-fragment-gperf.gperf.in +++ b/src/core/load-fragment-gperf.gperf.in @@ -54,8 +54,8 @@ {{type}}.SyslogLevel, config_parse_log_level, 0, offsetof({{type}}, exec_context.syslog_priority) {{type}}.SyslogLevelPrefix, config_parse_bool, 0, offsetof({{type}}, exec_context.syslog_level_prefix) {{type}}.LogLevelMax, config_parse_log_level, 0, offsetof({{type}}, exec_context.log_level_max) -{{type}}.LogRateLimitIntervalSec, config_parse_sec, 0, offsetof({{type}}, exec_context.log_ratelimit_interval_usec) -{{type}}.LogRateLimitBurst, config_parse_unsigned, 0, offsetof({{type}}, exec_context.log_ratelimit_burst) +{{type}}.LogRateLimitIntervalSec, config_parse_sec, 0, offsetof({{type}}, exec_context.log_ratelimit.interval) +{{type}}.LogRateLimitBurst, config_parse_unsigned, 0, offsetof({{type}}, exec_context.log_ratelimit.burst) {{type}}.LogExtraFields, config_parse_log_extra_fields, 0, offsetof({{type}}, exec_context) {{type}}.LogFilterPatterns, config_parse_log_filter_patterns, 0, offsetof({{type}}, exec_context) {{type}}.Capabilities, config_parse_warn_compat, DISABLED_LEGACY, offsetof({{type}}, exec_context) @@ -514,8 +514,8 @@ Socket.FileDescriptorName, config_parse_fdname, Socket.Service, config_parse_socket_service, 0, 0 Socket.TriggerLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, trigger_limit.interval) Socket.TriggerLimitBurst, config_parse_unsigned, 0, offsetof(Socket, trigger_limit.burst) -Socket.PollLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, poll_limit_interval) -Socket.PollLimitBurst, config_parse_unsigned, 0, offsetof(Socket, poll_limit_burst) +Socket.PollLimitIntervalSec, config_parse_sec, 0, offsetof(Socket, poll_limit.interval) +Socket.PollLimitBurst, config_parse_unsigned, 0, offsetof(Socket, poll_limit.burst) {% if ENABLE_SMACK %} Socket.SmackLabel, config_parse_unit_string_printf, 0, offsetof(Socket, smack) Socket.SmackLabelIPIn, config_parse_unit_string_printf, 0, offsetof(Socket, smack_ip_in) diff --git a/src/core/main.c b/src/core/main.c index 4c92d81c402..29723a9c664 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -783,9 +783,9 @@ static int parse_config_file(void) { { "Manager", "DefaultTimeoutAbortSec", config_parse_default_timeout_abort, 0, NULL }, { "Manager", "DefaultDeviceTimeoutSec", config_parse_sec, 0, &arg_defaults.device_timeout_usec }, { "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_defaults.restart_usec }, - { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_defaults.start_limit_interval}, /* obsolete alias */ - { "Manager", "DefaultStartLimitIntervalSec", config_parse_sec, 0, &arg_defaults.start_limit_interval}, - { "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_defaults.start_limit_burst }, + { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_defaults.start_limit.interval}, /* obsolete alias */ + { "Manager", "DefaultStartLimitIntervalSec", config_parse_sec, 0, &arg_defaults.start_limit.interval}, + { "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_defaults.start_limit.burst }, { "Manager", "DefaultEnvironment", config_parse_environ, arg_runtime_scope, &arg_default_environment }, { "Manager", "ManagerEnvironment", config_parse_environ, arg_runtime_scope, &arg_manager_environment }, { "Manager", "DefaultLimitCPU", config_parse_rlimit, RLIMIT_CPU, arg_defaults.rlimit }, diff --git a/src/core/manager.c b/src/core/manager.c index 39fbbfa4709..499ecec88e6 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -4342,8 +4342,7 @@ int manager_set_unit_defaults(Manager *m, const UnitDefaults *defaults) { m->defaults.timeout_abort_set = defaults->timeout_abort_set; m->defaults.device_timeout_usec = defaults->device_timeout_usec; - m->defaults.start_limit_interval = defaults->start_limit_interval; - m->defaults.start_limit_burst = defaults->start_limit_burst; + m->defaults.start_limit = defaults->start_limit; m->defaults.cpu_accounting = defaults->cpu_accounting; m->defaults.memory_accounting = defaults->memory_accounting; @@ -5104,8 +5103,7 @@ void unit_defaults_init(UnitDefaults *defaults, RuntimeScope scope) { .timeout_abort_usec = manager_default_timeout(scope), .timeout_abort_set = false, .device_timeout_usec = manager_default_timeout(scope), - .start_limit_interval = DEFAULT_START_LIMIT_INTERVAL, - .start_limit_burst = DEFAULT_START_LIMIT_BURST, + .start_limit = { DEFAULT_START_LIMIT_INTERVAL, DEFAULT_START_LIMIT_BURST }, /* On 4.15+ with unified hierarchy, CPU accounting is essentially free as it doesn't require the CPU * controller to be enabled, so the default is to enable it unless we got told otherwise. */ diff --git a/src/core/manager.h b/src/core/manager.h index 908a148196e..62e1346a859 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -162,8 +162,7 @@ typedef struct UnitDefaults { usec_t restart_usec, timeout_start_usec, timeout_stop_usec, timeout_abort_usec, device_timeout_usec; bool timeout_abort_set; - usec_t start_limit_interval; - unsigned start_limit_burst; + RateLimit start_limit; bool cpu_accounting; bool memory_accounting; diff --git a/src/core/socket.c b/src/core/socket.c index da9aa9a4a78..9cb188abc79 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -137,8 +137,7 @@ static void socket_init(Unit *u) { s->trigger_limit = RATELIMIT_OFF; - s->poll_limit_interval = USEC_INFINITY; - s->poll_limit_burst = UINT_MAX; + s->poll_limit = RATELIMIT_OFF; } static void socket_unwatch_control_pid(Socket *s) { @@ -322,10 +321,10 @@ static int socket_add_extras(Socket *s) { if (s->trigger_limit.burst == UINT_MAX) s->trigger_limit.burst = s->accept ? 200 : 20; - if (s->poll_limit_interval == USEC_INFINITY) - s->poll_limit_interval = 2 * USEC_PER_SEC; - if (s->poll_limit_burst == UINT_MAX) - s->poll_limit_burst = s->accept ? 150 : 15; + if (s->poll_limit.interval == USEC_INFINITY) + s->poll_limit.interval = 2 * USEC_PER_SEC; + if (s->poll_limit.burst == UINT_MAX) + s->poll_limit.burst = s->accept ? 150 : 15; if (have_non_accept_socket(s)) { @@ -797,8 +796,8 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { "%sPollLimitBurst: %u\n", prefix, FORMAT_TIMESPAN(s->trigger_limit.interval, USEC_PER_SEC), prefix, s->trigger_limit.burst, - prefix, FORMAT_TIMESPAN(s->poll_limit_interval, USEC_PER_SEC), - prefix, s->poll_limit_burst); + prefix, FORMAT_TIMESPAN(s->poll_limit.interval, USEC_PER_SEC), + prefix, s->poll_limit.burst); str = ip_protocol_to_name(s->socket_protocol); if (str) @@ -1783,7 +1782,7 @@ static int socket_watch_fds(Socket *s) { (void) sd_event_source_set_description(p->event_source, "socket-port-io"); } - r = sd_event_source_set_ratelimit(p->event_source, s->poll_limit_interval, s->poll_limit_burst); + r = sd_event_source_set_ratelimit(p->event_source, s->poll_limit.interval, s->poll_limit.burst); if (r < 0) log_unit_debug_errno(UNIT(s), r, "Failed to set poll limit on I/O event source, ignoring: %m"); } diff --git a/src/core/socket.h b/src/core/socket.h index 55afee6122e..d4b39d559d8 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -161,8 +161,7 @@ struct Socket { char *fdname; RateLimit trigger_limit; - usec_t poll_limit_interval; - unsigned poll_limit_burst; + RateLimit poll_limit; }; SocketPeer *socket_peer_ref(SocketPeer *p); diff --git a/src/core/unit.c b/src/core/unit.c index 2bdbcdf3667..6a452f888ad 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -120,10 +120,7 @@ Unit* unit_new(Manager *m, size_t size) { u->last_section_private = -1; - u->start_ratelimit = (const RateLimit) { - m->defaults.start_limit_interval, - m->defaults.start_limit_burst, - }; + u->start_ratelimit = m->defaults.start_limit; u->auto_start_stop_ratelimit = (const RateLimit) { .interval = 10 * USEC_PER_SEC, @@ -5693,12 +5690,12 @@ static int unit_export_log_ratelimit_interval(Unit *u, const ExecContext *c) { if (u->exported_log_ratelimit_interval) return 0; - if (c->log_ratelimit_interval_usec == 0) + if (c->log_ratelimit.interval == 0) return 0; p = strjoina("/run/systemd/units/log-rate-limit-interval:", u->id); - if (asprintf(&buf, "%" PRIu64, c->log_ratelimit_interval_usec) < 0) + if (asprintf(&buf, "%" PRIu64, c->log_ratelimit.interval) < 0) return log_oom(); r = symlink_atomic(buf, p); @@ -5720,12 +5717,12 @@ static int unit_export_log_ratelimit_burst(Unit *u, const ExecContext *c) { if (u->exported_log_ratelimit_burst) return 0; - if (c->log_ratelimit_burst == 0) + if (c->log_ratelimit.burst == 0) return 0; p = strjoina("/run/systemd/units/log-rate-limit-burst:", u->id); - if (asprintf(&buf, "%u", c->log_ratelimit_burst) < 0) + if (asprintf(&buf, "%u", c->log_ratelimit.burst) < 0) return log_oom(); r = symlink_atomic(buf, p);