From 4d824a4e0b008a359adda0e960706316f207047e Mon Sep 17 00:00:00 2001 From: Anita Zhang Date: Mon, 9 Mar 2020 15:09:17 -0700 Subject: [PATCH] core: add ManagedOOM*= properties to configure systemd-oomd on the unit This adds the hook ups so it can be read with the usual systemd utilities. Used in later commits by sytemd-oomd. --- docs/TRANSIENT-SETTINGS.md | 3 + man/org.freedesktop.systemd1.xml | 108 ++++++++++++++++++++++++++ src/basic/cgroup-util.c | 7 ++ src/basic/cgroup-util.h | 10 +++ src/core/cgroup.c | 13 +++- src/core/cgroup.h | 5 ++ src/core/dbus-cgroup.c | 35 +++++++++ src/core/dbus-util.c | 29 +++++++ src/core/dbus-util.h | 1 + src/core/load-fragment-gperf.gperf.m4 | 3 + src/core/load-fragment.c | 73 +++++++++++++++++ src/core/load-fragment.h | 2 + src/core/scope.c | 1 + src/core/service.c | 1 + src/core/slice.c | 1 + src/core/unit.h | 3 + src/shared/bus-get-properties.c | 18 +++++ src/shared/bus-get-properties.h | 1 + src/shared/bus-unit-util.c | 6 +- src/test/test-tables.c | 2 + 20 files changed, 319 insertions(+), 3 deletions(-) diff --git a/docs/TRANSIENT-SETTINGS.md b/docs/TRANSIENT-SETTINGS.md index f8ff413d28..f0dc2ee20f 100644 --- a/docs/TRANSIENT-SETTINGS.md +++ b/docs/TRANSIENT-SETTINGS.md @@ -270,6 +270,9 @@ All cgroup/resource control settings are available for transient units ✓ IPAccounting= ✓ IPAddressAllow= ✓ IPAddressDeny= +✓ ManagedOOMSwap= +✓ ManagedOOMMemoryPressure= +✓ ManagedOOMMemoryPressureLimitPercent= ``` ## Process Killing Settings diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index 02f7293288..3c0e5b6eb1 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -2414,6 +2414,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { readonly as IPEgressFilterPath = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly as DisableControllers = ['...', ...]; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMSwap = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressure = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressureLimitPercent = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly as Environment = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") @@ -2928,6 +2934,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + + + + + @@ -3478,6 +3490,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + + + + + @@ -4121,6 +4139,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { readonly as IPEgressFilterPath = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly as DisableControllers = ['...', ...]; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMSwap = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressure = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressureLimitPercent = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly as Environment = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") @@ -4661,6 +4685,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + + + + + @@ -5211,6 +5241,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + + + + + @@ -5780,6 +5816,12 @@ node /org/freedesktop/systemd1/unit/home_2emount { readonly as IPEgressFilterPath = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly as DisableControllers = ['...', ...]; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMSwap = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressure = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressureLimitPercent = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly as Environment = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") @@ -6250,6 +6292,12 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + + + + + @@ -6720,6 +6768,12 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + + + + + @@ -7404,6 +7458,12 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { readonly as IPEgressFilterPath = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly as DisableControllers = ['...', ...]; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMSwap = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressure = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressureLimitPercent = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly as Environment = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") @@ -7860,6 +7920,12 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + + + + + @@ -8316,6 +8382,12 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + + + + + @@ -8859,6 +8931,12 @@ node /org/freedesktop/systemd1/unit/system_2eslice { readonly as IPEgressFilterPath = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly as DisableControllers = ['...', ...]; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMSwap = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressure = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressureLimitPercent = '...'; }; interface org.freedesktop.DBus.Peer { ... }; interface org.freedesktop.DBus.Introspectable { ... }; @@ -8989,6 +9067,12 @@ node /org/freedesktop/systemd1/unit/system_2eslice { + + + + + + @@ -9123,6 +9207,12 @@ node /org/freedesktop/systemd1/unit/system_2eslice { + + + + + + @@ -9276,6 +9366,12 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { readonly as IPEgressFilterPath = ['...', ...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("false") readonly as DisableControllers = ['...', ...]; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMSwap = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressure = '...'; + @org.freedesktop.DBus.Property.EmitsChangedSignal("false") + readonly s ManagedOOMMemoryPressureLimitPercent = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s KillMode = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") @@ -9422,6 +9518,12 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { + + + + + + @@ -9582,6 +9684,12 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope { + + + + + + diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 6210347553..8f32296333 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -2161,3 +2161,10 @@ CGroupMask get_cpu_accounting_mask(void) { bool cpu_accounting_is_cheap(void) { return get_cpu_accounting_mask() == 0; } + +static const char* const managed_oom_mode_table[_MANAGED_OOM_MODE_MAX] = { + [MANAGED_OOM_AUTO] = "auto", + [MANAGED_OOM_KILL] = "kill", +}; + +DEFINE_STRING_TABLE_LOOKUP(managed_oom_mode, ManagedOOMMode); diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 2b88571bc1..6f76417a04 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -275,3 +275,13 @@ CGroupController cgroup_controller_from_string(const char *s) _pure_; bool is_cgroup_fs(const struct statfs *s); bool fd_is_cgroup_fs(int fd); + +typedef enum ManagedOOMMode { + MANAGED_OOM_AUTO, + MANAGED_OOM_KILL, + _MANAGED_OOM_MODE_MAX, + _MANAGED_OOM_MODE_INVALID = -1, +} ManagedOOMMode; + +const char* managed_oom_mode_to_string(ManagedOOMMode m) _const_; +ManagedOOMMode managed_oom_mode_from_string(const char *s) _pure_; diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 211e4a5945..95b5f2de59 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -128,6 +128,9 @@ void cgroup_context_init(CGroupContext *c) { .startup_blockio_weight = CGROUP_BLKIO_WEIGHT_INVALID, .tasks_max = TASKS_MAX_UNSET, + + .moom_swap = MANAGED_OOM_AUTO, + .moom_mem_pressure = MANAGED_OOM_AUTO, }; } @@ -411,7 +414,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) { "%sTasksMax: %" PRIu64 "\n" "%sDevicePolicy: %s\n" "%sDisableControllers: %s\n" - "%sDelegate: %s\n", + "%sDelegate: %s\n" + "%sManagedOOMSwap: %s\n" + "%sManagedOOMMemoryPressure: %s\n" + "%sManagedOOMMemoryPressureLimitPercent: %d%%\n", prefix, yes_no(c->cpu_accounting), prefix, yes_no(c->io_accounting), prefix, yes_no(c->blockio_accounting), @@ -441,7 +447,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) { prefix, tasks_max_resolve(&c->tasks_max), prefix, cgroup_device_policy_to_string(c->device_policy), prefix, strempty(disable_controllers_str), - prefix, yes_no(c->delegate)); + prefix, yes_no(c->delegate), + prefix, managed_oom_mode_to_string(c->moom_swap), + prefix, managed_oom_mode_to_string(c->moom_mem_pressure), + prefix, c->moom_mem_pressure_limit); if (c->delegate) { _cleanup_free_ char *t = NULL; diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 9ac5c8bfc0..1f592ef559 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -159,6 +159,11 @@ struct CGroupContext { /* Common */ TasksMax tasks_max; + + /* Settings for systemd-oomd */ + ManagedOOMMode moom_swap; + ManagedOOMMode moom_mem_pressure; + int moom_mem_pressure_limit; }; /* Used when querying IP accounting data */ diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index b7d2e32639..78abcbdbc8 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -19,6 +19,7 @@ BUS_DEFINE_PROPERTY_GET(bus_property_get_tasks_max, "t", TasksMax, tasks_max_resolve); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy); +static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_managed_oom_mode, managed_oom_mode, ManagedOOMMode); static int property_get_cgroup_mask( sd_bus *bus, @@ -391,6 +392,9 @@ const sd_bus_vtable bus_cgroup_vtable[] = { SD_BUS_PROPERTY("IPIngressFilterPath", "as", NULL, offsetof(CGroupContext, ip_filters_ingress), 0), SD_BUS_PROPERTY("IPEgressFilterPath", "as", NULL, offsetof(CGroupContext, ip_filters_egress), 0), SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask, offsetof(CGroupContext, disable_controllers), 0), + SD_BUS_PROPERTY("ManagedOOMSwap", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_swap), 0), + SD_BUS_PROPERTY("ManagedOOMMemoryPressure", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_mem_pressure), 0), + SD_BUS_PROPERTY("ManagedOOMMemoryPressureLimitPercent", "s", bus_property_get_percent, offsetof(CGroupContext, moom_mem_pressure_limit), 0), SD_BUS_VTABLE_END }; @@ -1667,6 +1671,37 @@ int bus_cgroup_set_property( return 1; } + if (STR_IN_SET(name, "ManagedOOMSwap", "ManagedOOMMemoryPressure")) { + ManagedOOMMode *cgroup_mode = streq(name, "ManagedOOMSwap") ? &c->moom_swap : &c->moom_mem_pressure; + ManagedOOMMode m; + const char *mode; + + if (!UNIT_VTABLE(u)->can_set_managed_oom) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set %s for this unit type", name); + + r = sd_bus_message_read(message, "s", &mode); + if (r < 0) + return r; + + m = managed_oom_mode_from_string(mode); + if (m < 0) + return -EINVAL; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + *cgroup_mode = m; + unit_write_settingf(u, flags, name, "%s=%s", name, mode); + } + + return 1; + } + + if (streq(name, "ManagedOOMMemoryPressureLimitPercent")) { + if (!UNIT_VTABLE(u)->can_set_managed_oom) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set %s for this unit type", name); + + return bus_set_transient_percent(u, name, &c->moom_mem_pressure_limit, message, flags, error); + } + if (streq(name, "DisableControllers") || (u->transient && u->load_state == UNIT_STUB)) return bus_cgroup_set_transient_property(u, c, name, message, flags, error); diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c index 951450e53d..f534001a9c 100644 --- a/src/core/dbus-util.c +++ b/src/core/dbus-util.c @@ -91,6 +91,35 @@ int bus_set_transient_bool( return 1; } +int bus_set_transient_percent( + Unit *u, + const char *name, + int *p, + sd_bus_message *message, + UnitWriteFlags flags, + sd_bus_error *error) { + + const char *v; + int r; + + assert(p); + + r = sd_bus_message_read(message, "s", &v); + if (r < 0) + return r; + + r = parse_percent(v); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + *p = r; + unit_write_settingf(u, flags, name, "%s=%d%%", name, r); + } + + return 1; +} + int bus_set_transient_usec_internal( Unit *u, const char *name, diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h index 654ceb5279..7781a425be 100644 --- a/src/core/dbus-util.h +++ b/src/core/dbus-util.h @@ -240,6 +240,7 @@ int bus_set_transient_user_relaxed(Unit *u, const char *name, char **p, sd_bus_m int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); +int bus_set_transient_percent(Unit *u, const char *name, int *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_set_transient_usec_internal(Unit *u, const char *name, usec_t *p, bool fix_0, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); static inline int bus_set_transient_usec(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { return bus_set_transient_usec_internal(u, name, p, false, message, flags, error); diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index c60d565eb4..f84febd953 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -224,6 +224,9 @@ $1.IPAddressAllow, config_parse_ip_address_access, 0, $1.IPAddressDeny, config_parse_ip_address_access, 0, offsetof($1, cgroup_context.ip_address_deny) $1.IPIngressFilterPath, config_parse_ip_filter_bpf_progs, 0, offsetof($1, cgroup_context.ip_filters_ingress) $1.IPEgressFilterPath, config_parse_ip_filter_bpf_progs, 0, offsetof($1, cgroup_context.ip_filters_egress) +$1.ManagedOOMSwap, config_parse_managed_oom_mode, 0, offsetof($1, cgroup_context.moom_swap) +$1.ManagedOOMMemoryPressure, config_parse_managed_oom_mode, 0, offsetof($1, cgroup_context.moom_mem_pressure) +$1.ManagedOOMMemoryPressureLimitPercent,config_parse_managed_oom_mem_pressure_limit,0, offsetof($1, cgroup_context.moom_mem_pressure_limit) $1.NetClass, config_parse_warn_compat, DISABLED_LEGACY, 0' )m4_dnl Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index df40119175..81253239aa 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -3812,6 +3812,79 @@ int config_parse_delegate( return 0; } +int config_parse_managed_oom_mode( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ManagedOOMMode *mode = data, m; + UnitType t; + + t = unit_name_to_type(unit); + assert(t != _UNIT_TYPE_INVALID); + + if (!unit_vtable[t]->can_set_managed_oom) + return log_syntax(unit, LOG_WARNING, filename, line, 0, "%s= is not supported for this unit type, ignoring.", lvalue); + + if (isempty(rvalue)) { + *mode = MANAGED_OOM_AUTO; + return 0; + } + + m = managed_oom_mode_from_string(rvalue); + if (m < 0) { + log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid syntax, ignoring: %s", rvalue); + return 0; + } + + *mode = m; + return 0; +} + +int config_parse_managed_oom_mem_pressure_limit( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + unsigned *limit = data; + UnitType t; + int r; + + t = unit_name_to_type(unit); + assert(t != _UNIT_TYPE_INVALID); + + if (!unit_vtable[t]->can_set_managed_oom) + return log_syntax(unit, LOG_WARNING, filename, line, 0, "%s= is not supported for this unit type, ignoring.", lvalue); + + if (isempty(rvalue)) { + *limit = 0; + return 0; + } + + r = parse_percent(rvalue); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse limit percent value, ignoring: %s", rvalue); + return 0; + } + + *limit = r; + return 0; +} + int config_parse_device_allow( const char *unit, const char *filename, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index d67852a74d..fa4c1fb1a0 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -76,6 +76,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_cpu_shares); CONFIG_PARSER_PROTOTYPE(config_parse_memory_limit); CONFIG_PARSER_PROTOTYPE(config_parse_tasks_max); CONFIG_PARSER_PROTOTYPE(config_parse_delegate); +CONFIG_PARSER_PROTOTYPE(config_parse_managed_oom_mode); +CONFIG_PARSER_PROTOTYPE(config_parse_managed_oom_mem_pressure_limit); CONFIG_PARSER_PROTOTYPE(config_parse_device_policy); CONFIG_PARSER_PROTOTYPE(config_parse_device_allow); CONFIG_PARSER_PROTOTYPE(config_parse_io_device_latency); diff --git a/src/core/scope.c b/src/core/scope.c index 42c51b0865..540c83ba45 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -621,6 +621,7 @@ const UnitVTable scope_vtable = { .can_delegate = true, .can_fail = true, .once_only = true, + .can_set_managed_oom = true, .init = scope_init, .load = scope_load, diff --git a/src/core/service.c b/src/core/service.c index 863b6755b1..131f462a9c 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -4533,6 +4533,7 @@ const UnitVTable service_vtable = { .can_transient = true, .can_delegate = true, .can_fail = true, + .can_set_managed_oom = true, .init = service_init, .done = service_done, diff --git a/src/core/slice.c b/src/core/slice.c index 49541aacab..36e5d6a40f 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -435,6 +435,7 @@ const UnitVTable slice_vtable = { .private_section = "Slice", .can_transient = true, + .can_set_managed_oom = true, .init = slice_init, .load = slice_load, diff --git a/src/core/unit.h b/src/core/unit.h index 35873d57bc..9b2ea6c79f 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -625,6 +625,9 @@ typedef struct UnitVTable { /* True if queued jobs of this type should be GC'ed if no other job needs them anymore */ bool gc_jobs:1; + + /* True if systemd-oomd can monitor and act on this unit's recursive children's cgroup(s) */ + bool can_set_managed_oom:1; } UnitVTable; extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; diff --git a/src/shared/bus-get-properties.c b/src/shared/bus-get-properties.c index 8ad4694046..5a123bb8f3 100644 --- a/src/shared/bus-get-properties.c +++ b/src/shared/bus-get-properties.c @@ -2,6 +2,7 @@ #include "bus-get-properties.h" #include "rlimit-util.h" +#include "stdio-util.h" #include "string-util.h" int bus_property_get_bool( @@ -54,6 +55,23 @@ int bus_property_get_id128( return sd_bus_message_append_array(reply, 'y', id->bytes, 16); } +int bus_property_get_percent( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + char pstr[DECIMAL_STR_MAX(int) + 2]; + int p = *(int*) userdata; + + xsprintf(pstr, "%d%%", p); + + return sd_bus_message_append_basic(reply, 's', pstr); +} + #if __SIZEOF_SIZE_T__ != 8 int bus_property_get_size( sd_bus *bus, diff --git a/src/shared/bus-get-properties.h b/src/shared/bus-get-properties.h index 81af74309d..f3934a86a2 100644 --- a/src/shared/bus-get-properties.h +++ b/src/shared/bus-get-properties.h @@ -8,6 +8,7 @@ int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); int bus_property_set_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error); int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); +int bus_property_get_percent(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); #define bus_property_get_usec ((sd_bus_property_get_t) NULL) #define bus_property_set_usec ((sd_bus_property_set_t) NULL) diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 3ae3c12f92..f51a99c8d7 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -432,7 +432,11 @@ static int bus_append_ip_address_access(sd_bus_message *m, int family, const uni static int bus_append_cgroup_property(sd_bus_message *m, const char *field, const char *eq) { int r; - if (STR_IN_SET(field, "DevicePolicy", "Slice")) + if (STR_IN_SET(field, "DevicePolicy", + "Slice", + "ManagedOOMSwap", + "ManagedOOMMemoryPressure", + "ManagedOOMMemoryPressureLimitPercent")) return bus_append_string(m, field, eq); if (STR_IN_SET(field, "CPUAccounting", diff --git a/src/test/test-tables.c b/src/test/test-tables.c index 59f90b76ec..7273611143 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -3,6 +3,7 @@ #include "architecture.h" #include "automount.h" #include "cgroup.h" +#include "cgroup-util.h" #include "compress.h" #include "condition.h" #include "device-private.h" @@ -71,6 +72,7 @@ int main(int argc, char **argv) { test_table(locale_variable, VARIABLE_LC); test_table(log_target, LOG_TARGET); test_table(mac_address_policy, MAC_ADDRESS_POLICY); + test_table(managed_oom_mode, MANAGED_OOM_MODE); test_table(manager_state, MANAGER_STATE); test_table(manager_timestamp, MANAGER_TIMESTAMP); test_table(mount_exec_command, MOUNT_EXEC_COMMAND);