]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: Expose oom kills and managed oom kills as properties
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 12 Sep 2025 12:14:26 +0000 (14:14 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 19 Sep 2025 11:54:54 +0000 (13:54 +0200)
It can be useful for users to know this information so let's expose
it as properties so it can be queried.

man/org.freedesktop.systemd1.xml
src/core/dbus-unit.c
src/core/varlink-cgroup.c
src/shared/varlink-io.systemd.Unit.c
test/units/TEST-55-OOMD.sh

index ed227127489bed8463e9d82a3fcb92bc6a7530c1..2b30adab9b4562bfe3ad881760f35105964b9a23 100644 (file)
@@ -2691,6 +2691,15 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       or the restart rate limit is reached. See the <literal>RestartMode=</literal> section in
       <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
       for more details.</para>
+
+      <para><varname>OOMKills</varname> contains a different value depending on whether
+      <varname>OOMPolicy=kill</varname> is enabled for the unit or not. If enabled, the property contains the
+      number of times the kernel OOM killer killed all the processes in the unit's cgroup and its
+      descendant cgroups. If disabled, the property contains the number of processes the kernel OOM killer
+      has killed in the unit's cgroup and its descendant cgroups.</para>
+
+      <para><varname>ManagedOOMKills</varname> contains the number of times <command>systemd-oomd</command>
+      killed all the processes in the unit's cgroup and its descendant cgroups.</para>
     </refsect2>
 
     <refsect2>
@@ -2900,6 +2909,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t IOWriteOperations = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t OOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t ManagedOOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly b Delegate = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly as DelegateControllers = ['...', ...];
@@ -4247,6 +4260,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="IOWriteOperations"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="OOMKills"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMKills"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Delegate"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DelegateControllers"/>
@@ -5139,6 +5156,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t IOWriteOperations = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t OOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t ManagedOOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly b Delegate = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly as DelegateControllers = ['...', ...];
@@ -6486,6 +6507,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <variablelist class="dbus-property" generated="True" extra-ref="IOWriteOperations"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="OOMKills"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMKills"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Delegate"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DelegateControllers"/>
@@ -7202,6 +7227,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t IOWriteOperations = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t OOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t ManagedOOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly b Delegate = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly as DelegateControllers = ['...', ...];
@@ -8379,6 +8408,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
 
     <variablelist class="dbus-property" generated="True" extra-ref="IOWriteOperations"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="OOMKills"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMKills"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Delegate"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DelegateControllers"/>
@@ -9228,6 +9261,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t IOWriteOperations = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t OOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t ManagedOOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly b Delegate = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly as DelegateControllers = ['...', ...];
@@ -10369,6 +10406,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
 
     <variablelist class="dbus-property" generated="True" extra-ref="IOWriteOperations"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="OOMKills"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMKills"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Delegate"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DelegateControllers"/>
@@ -11071,6 +11112,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t IOWriteOperations = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t OOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t ManagedOOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly b Delegate = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly as DelegateControllers = ['...', ...];
@@ -11436,6 +11481,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="IOWriteOperations"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="OOMKills"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMKills"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Delegate"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DelegateControllers"/>
@@ -11647,6 +11696,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t IOWriteOperations = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t OOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t ManagedOOMKills = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly b Delegate = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly as DelegateControllers = ['...', ...];
@@ -12050,6 +12103,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
 
     <variablelist class="dbus-property" generated="True" extra-ref="IOWriteOperations"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="OOMKills"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMKills"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="Delegate"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DelegateControllers"/>
@@ -12459,6 +12516,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <varname>LogsDirectoryQuotaUsage</varname>,
       <varname>LogsDirectoryAccounting</varname>, and
       <function>KillSubgroup()</function> were added in version 258.</para>
+      <para><varname>OOMKills</varname>, and
+      <varname>ManagedOOMKills</varname> were added in 259.</para>
     </refsect2>
     <refsect2>
       <title>Socket Unit Objects</title>
@@ -12524,6 +12583,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <varname>LogsDirectoryQuotaUsage</varname>,
       <varname>LogsDirectoryAccounting</varname>, and
       <function>KillSubgroup()</function> were added in version 258.</para>
+      <para><varname>OOMKills</varname>, and
+      <varname>ManagedOOMKills</varname> were added in 259.</para>
     </refsect2>
     <refsect2>
       <title>Mount Unit Objects</title>
@@ -12584,6 +12645,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <varname>LogsDirectoryQuotaUsage</varname>,
       <varname>LogsDirectoryAccounting</varname>, and
       <function>KillSubgroup()</function> were added in version 258.</para>
+      <para><varname>OOMKills</varname>, and
+      <varname>ManagedOOMKills</varname> were added in 259.</para>
     </refsect2>
     <refsect2>
       <title>Swap Unit Objects</title>
@@ -12642,6 +12705,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <varname>LogsDirectoryQuotaUsage</varname>,
       <varname>LogsDirectoryAccounting</varname>, and
       <function>KillSubgroup()</function> were added in version 258.</para>
+      <para><varname>OOMKills</varname>, and
+      <varname>ManagedOOMKills</varname> were added in 259.</para>
     </refsect2>
     <refsect2>
       <title>Slice Unit Objects</title>
@@ -12672,6 +12737,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <varname>NCurrentlyActive</varname>,
       <function>RemoveSubgroup()</function>, and
       <function>KillSubgroup()</function> were added in version 258.</para>
+      <para><varname>OOMKills</varname>, and
+      <varname>ManagedOOMKills</varname> were added in 259.</para>
     </refsect2>
     <refsect2>
       <title>Scope Unit Objects</title>
@@ -12700,6 +12767,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <para><varname>ManagedOOMMemoryPressureDurationUSec</varname> was added in version 257.</para>
       <para><function>RemoveSubgroup()</function> and
       <function>KillSubgroup()</function> were added in version 258.</para>
+      <para><varname>OOMKills</varname>, and
+      <varname>ManagedOOMKills</varname> were added in 259.</para>
     </refsect2>
     <refsect2>
       <title>Job Objects</title>
index cf015b5a7bcc5f00587e613f6d5ca4308a9706e5..a524cfad22c945297d3d609520d34835513c4057 100644 (file)
@@ -1295,6 +1295,42 @@ static int property_get_cgroup_id(
         return sd_bus_message_append(reply, "t", crt ? crt->cgroup_id : UINT64_C(0));
 }
 
+static int property_get_oom_kills(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Unit *u = ASSERT_PTR(userdata);
+
+        assert(bus);
+        assert(reply);
+
+        CGroupRuntime *crt = unit_get_cgroup_runtime(u);
+        return sd_bus_message_append(reply, "t", crt ? crt->oom_kill_last : UINT64_MAX);
+}
+
+static int property_get_managed_oom_kills(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Unit *u = ASSERT_PTR(userdata);
+
+        assert(bus);
+        assert(reply);
+
+        CGroupRuntime *crt = unit_get_cgroup_runtime(u);
+        return sd_bus_message_append(reply, "t", crt ? crt->managed_oom_kill_last : UINT64_MAX);
+}
+
 static int append_process(sd_bus_message *reply, const char *p, PidRef *pid, Set *pids) {
         _cleanup_free_ char *buf = NULL, *cmdline = NULL;
         int r;
@@ -1715,6 +1751,8 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
         SD_BUS_PROPERTY("IOReadOperations", "t", property_get_io_counter, 0, 0),
         SD_BUS_PROPERTY("IOWriteBytes", "t", property_get_io_counter, 0, 0),
         SD_BUS_PROPERTY("IOWriteOperations", "t", property_get_io_counter, 0, 0),
+        SD_BUS_PROPERTY("OOMKills", "t", property_get_oom_kills, 0, 0),
+        SD_BUS_PROPERTY("ManagedOOMKills", "t", property_get_managed_oom_kills, 0, 0),
 
         SD_BUS_METHOD_WITH_ARGS("GetProcesses",
                                 SD_BUS_NO_ARGS,
index 88d13f3c45b1ea8a40a5b326cc0b025e2fc94666..7e23d4a0f7adf88d77f361a33e934a4fbe92cade 100644 (file)
@@ -615,5 +615,9 @@ int unit_cgroup_runtime_build_json(sd_json_variant **ret, const char *name, void
                         JSON_BUILD_PAIR_CALLBACK_NON_NULL("IOReadBytes", get_io_counter_build_json, u),
                         JSON_BUILD_PAIR_CALLBACK_NON_NULL("IOReadOperations", get_io_counter_build_json, u),
                         JSON_BUILD_PAIR_CALLBACK_NON_NULL("IOWriteBytes", get_io_counter_build_json, u),
-                        JSON_BUILD_PAIR_CALLBACK_NON_NULL("IOWriteOperations", get_io_counter_build_json, u));
+                        JSON_BUILD_PAIR_CALLBACK_NON_NULL("IOWriteOperations", get_io_counter_build_json, u),
+
+                        /* OOM */
+                        SD_JSON_BUILD_PAIR_UNSIGNED("OOMKills", crt->oom_kill_last),
+                        SD_JSON_BUILD_PAIR_UNSIGNED("ManagedOOMKills", crt->managed_oom_kill_last));
 }
index 30d5d8cd5746c6d610c3ec8900cd809ea56caaed..32c72f0040cbf6e558ad989ab01b1709419b75eb 100644 (file)
@@ -455,7 +455,13 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 SD_VARLINK_FIELD_COMMENT("The total number of bytes written to block devices by the cgroup"),
                 SD_VARLINK_DEFINE_FIELD(IOWriteBytes, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
                 SD_VARLINK_FIELD_COMMENT("The total number of write operations performed on block devices by the cgroup"),
-                SD_VARLINK_DEFINE_FIELD(IOWriteOperations, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
+                SD_VARLINK_DEFINE_FIELD(IOWriteOperations, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
+
+                /* OOM */
+                SD_VARLINK_FIELD_COMMENT("The number of processes of this unit killed by the kernel OOM killer"),
+                SD_VARLINK_DEFINE_FIELD(OOMKills, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
+                SD_VARLINK_FIELD_COMMENT("The number of processes of this unit killed by systemd-oomd"),
+                SD_VARLINK_DEFINE_FIELD(ManagedOOMKills, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
 
 static SD_VARLINK_DEFINE_STRUCT_TYPE(
                 UnitRuntime,
index 66793378584c6ff4ab8f10e9094dacb19347ed74..ae0081063c3b29cc887b5f89b3977b368939055b 100755 (executable)
@@ -125,6 +125,8 @@ test_basic() {
     if systemctl "$@" status TEST-55-OOMD-testbloat.service; then exit 42; fi
     if ! systemctl "$@" status TEST-55-OOMD-testchill.service; then exit 24; fi
 
+    assert_eq "$(systemctl "$@" show TEST-55-OOMD-testbloat.service -P ManagedOOMKills)" "1"
+
     systemctl "$@" kill --signal=KILL TEST-55-OOMD-testbloat.service || :
     systemctl "$@" stop TEST-55-OOMD-testbloat.service
     systemctl "$@" stop TEST-55-OOMD-testchill.service