]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add ManagedOOM*= properties to configure systemd-oomd on the unit
authorAnita Zhang <the.anitazha@gmail.com>
Mon, 9 Mar 2020 22:09:17 +0000 (15:09 -0700)
committerAnita Zhang <the.anitazha@gmail.com>
Wed, 7 Oct 2020 23:17:23 +0000 (16:17 -0700)
This adds the hook ups so it can be read with the usual systemd
utilities. Used in later commits by sytemd-oomd.

20 files changed:
docs/TRANSIENT-SETTINGS.md
man/org.freedesktop.systemd1.xml
src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/core/cgroup.c
src/core/cgroup.h
src/core/dbus-cgroup.c
src/core/dbus-util.c
src/core/dbus-util.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/scope.c
src/core/service.c
src/core/slice.c
src/core/unit.h
src/shared/bus-get-properties.c
src/shared/bus-get-properties.h
src/shared/bus-unit-util.c
src/test/test-tables.c

index f8ff413d28f4f8aecae9edde484b7ebafef1e124..f0dc2ee20ffb88cc6ee5301ae88f27dc8d26351c 100644 (file)
@@ -270,6 +270,9 @@ All cgroup/resource control settings are available for transient units
 ✓ IPAccounting=
 ✓ IPAddressAllow=
 ✓ IPAddressDeny=
+✓ ManagedOOMSwap=
+✓ ManagedOOMMemoryPressure=
+✓ ManagedOOMMemoryPressureLimitPercent=
 ```
 
 ## Process Killing Settings
index 02f72932881d12f82b60d5a0b372e442e8ccb295..3c0e5b6eb14712344192c3628f217a97612fd0ab 100644 (file)
@@ -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 {
 
     <!--property DisableControllers is not documented!-->
 
+    <!--property ManagedOOMSwap is not documented!-->
+
+    <!--property ManagedOOMMemoryPressure is not documented!-->
+
+    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+
     <!--property EnvironmentFiles is not documented!-->
 
     <!--property PassEnvironment is not documented!-->
@@ -3478,6 +3490,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DisableControllers"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMSwap"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
@@ -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 {
 
     <!--property DisableControllers is not documented!-->
 
+    <!--property ManagedOOMSwap is not documented!-->
+
+    <!--property ManagedOOMMemoryPressure is not documented!-->
+
+    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+
     <!--property EnvironmentFiles is not documented!-->
 
     <!--property PassEnvironment is not documented!-->
@@ -5211,6 +5241,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DisableControllers"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMSwap"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
@@ -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 {
 
     <!--property DisableControllers is not documented!-->
 
+    <!--property ManagedOOMSwap is not documented!-->
+
+    <!--property ManagedOOMMemoryPressure is not documented!-->
+
+    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+
     <!--property EnvironmentFiles is not documented!-->
 
     <!--property PassEnvironment is not documented!-->
@@ -6720,6 +6768,12 @@ node /org/freedesktop/systemd1/unit/home_2emount {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DisableControllers"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMSwap"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
@@ -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 {
 
     <!--property DisableControllers is not documented!-->
 
+    <!--property ManagedOOMSwap is not documented!-->
+
+    <!--property ManagedOOMMemoryPressure is not documented!-->
+
+    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+
     <!--property EnvironmentFiles is not documented!-->
 
     <!--property PassEnvironment is not documented!-->
@@ -8316,6 +8382,12 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DisableControllers"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMSwap"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="EnvironmentFiles"/>
@@ -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 {
 
     <!--property DisableControllers is not documented!-->
 
+    <!--property ManagedOOMSwap is not documented!-->
+
+    <!--property ManagedOOMMemoryPressure is not documented!-->
+
+    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+
     <!--Autogenerated cross-references for systemd.directives, do not edit-->
 
     <variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.systemd1.Unit"/>
@@ -9123,6 +9207,12 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DisableControllers"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMSwap"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+
     <!--End of Autogenerated section-->
 
     <refsect2>
@@ -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 {
 
     <!--property DisableControllers is not documented!-->
 
+    <!--property ManagedOOMSwap is not documented!-->
+
+    <!--property ManagedOOMMemoryPressure is not documented!-->
+
+    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+
     <!--property KillMode is not documented!-->
 
     <!--property KillSignal is not documented!-->
@@ -9582,6 +9684,12 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DisableControllers"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMSwap"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="KillMode"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="KillSignal"/>
index 6210347553c4088c3df20d85eb8eb00cd0b24140..8f32296333f4511dbab5545359f41a3431bdac51 100644 (file)
@@ -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);
index 2b88571bc1c7767d57cc9de9d0a417fe2e0cbb82..6f76417a04e34cf0930f5be8117f0aa4a8a35d57 100644 (file)
@@ -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_;
index 211e4a5945f02f65309b5fdc03f3979e77becbe7..95b5f2de596dea72ed30f6f251806b37a2e85310 100644 (file)
@@ -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;
index 9ac5c8bfc0b993a0a9567335eceeff777c2ce1e4..1f592ef559ae12b67be42aefb7e6c5eaf2ccf8d9 100644 (file)
@@ -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 */
index b7d2e32639a51699b5df2404c3260e73bb672a9c..78abcbdbc8d31b6625079c96738d1cd239e86795 100644 (file)
@@ -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);
 
index 951450e53daa418bde5406b806b6fb9e393424df..f534001a9c2c252eb641785104fe6c2f8357e561 100644 (file)
@@ -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,
index 654ceb527950600a6adbdfe2bd572909d3b57571..7781a425befe5c0f271925d23f22b1fc09027d6a 100644 (file)
@@ -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);
index c60d565eb49efb87a9bd8a67f61535c0b3c2dc72..f84febd9536fe74633e80ab522c5349a1918672b 100644 (file)
@@ -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)
index df4011917582cd4a24ea349b7315a301c81181c9..81253239aa342cc97ea3046355dd841143930153 100644 (file)
@@ -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,
index d67852a74d0fb8ac7dec9cf90e9ecd4ed2bc2707..fa4c1fb1a01855fea20d2e09e8339a14802db748 100644 (file)
@@ -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);
index 42c51b08651641664183950ea874c110dbc1139c..540c83ba451b6ab75dc162753f410123276c02e4 100644 (file)
@@ -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,
index 863b6755b1d6068d4b5fff4ca071efd5051e7641..131f462a9cd4d07f4576ec5106ff61c75ad83646 100644 (file)
@@ -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,
index 49541aacab452f97048a4a80d0e03e1f604364a1..36e5d6a40fdd38d553a50b8f1101c3d86266f636 100644 (file)
@@ -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,
index 35873d57bc341c89dbe6bb3ec5db9187cfa2be9a..9b2ea6c79f7ea6fbc8cb8e562a7b9626ebe67495 100644 (file)
@@ -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];
index 8ad4694046607ac719afe31c5058d9805925a6b1..5a123bb8f32ad859065fb8eb9a679d9e0ca5b31d 100644 (file)
@@ -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,
index 81af74309d965699c237214c3df09254cb84a3c5..f3934a86a25f8f192e3487760ec9c0331a01bfc5 100644 (file)
@@ -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)
index 3ae3c12f92149165644996692cc97630b933ef21..f51a99c8d7b3421dfd8dd780af04145c2c3d32a2 100644 (file)
@@ -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",
index 59f90b76ec4ac71ded12201008a1a64e7018b7d7..72736111438555232237e2e48cea3c03f48a2f65 100644 (file)
@@ -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);