]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: systemd-oomd pid1 integration
authorAnita Zhang <the.anitazha@gmail.com>
Wed, 9 Sep 2020 07:24:23 +0000 (00:24 -0700)
committerAnita Zhang <the.anitazha@gmail.com>
Thu, 8 Oct 2020 00:12:24 +0000 (17:12 -0700)
src/core/cgroup.c
src/core/cgroup.h
src/core/manager.c
src/core/unit.c
src/core/unit.h
src/systemd/sd-messages.h

index 95b5f2de596dea72ed30f6f251806b37a2e85310..1958c1be2b9f24124c047d4463300b9911a15ccc 100644 (file)
@@ -2681,6 +2681,47 @@ static void unit_remove_from_cgroup_empty_queue(Unit *u) {
         u->in_cgroup_empty_queue = false;
 }
 
+int unit_check_oomd_kill(Unit *u) {
+        _cleanup_free_ char *value = NULL;
+        bool increased;
+        uint64_t n = 0;
+        int r;
+
+        if (!u->cgroup_path)
+                return 0;
+
+        r = cg_all_unified();
+        if (r < 0)
+                return log_unit_debug_errno(u, r, "Couldn't determine whether we are in all unified mode: %m");
+        else if (r == 0)
+                return 0;
+
+        r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "user.systemd_oomd_kill", &value);
+        if (r < 0 && r != -ENODATA)
+                return r;
+
+        if (!isempty(value)) {
+                 r = safe_atou64(value, &n);
+                 if (r < 0)
+                         return r;
+        }
+
+        increased = n > u->managed_oom_kill_last;
+        u->managed_oom_kill_last = n;
+
+        if (!increased)
+                return 0;
+
+        if (n > 0)
+                log_struct(LOG_NOTICE,
+                           "MESSAGE_ID=" SD_MESSAGE_UNIT_OOMD_KILL_STR,
+                           LOG_UNIT_ID(u),
+                           LOG_UNIT_INVOCATION_ID(u),
+                           LOG_UNIT_MESSAGE(u, "systemd-oomd killed %"PRIu64" process(es) in this unit.", n));
+
+        return 1;
+}
+
 int unit_check_oom(Unit *u) {
         _cleanup_free_ char *oom_kill = NULL;
         bool increased;
index 1f592ef559ae12b67be42aefb7e6c5eaf2ccf8d9..881b3f3dfe88ac053b80cf791e89b9465fb9bd2a 100644 (file)
@@ -229,6 +229,7 @@ int unit_watch_cgroup(Unit *u);
 int unit_watch_cgroup_memory(Unit *u);
 
 void unit_add_to_cgroup_empty_queue(Unit *u);
+int unit_check_oomd_kill(Unit *u);
 int unit_check_oom(Unit *u);
 
 int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path);
index d85d938e7bab25f665bc3e4194da3b671636b2aa..611ecf23b216b758461a3a85821069fbf0d336d7 100644 (file)
@@ -2578,6 +2578,11 @@ static int manager_dispatch_sigchld(sd_event_source *source, void *userdata) {
                          * We only do this for the cgroup the PID belonged to. */
                         (void) unit_check_oom(u1);
 
+                        /* This only logs for now. In the future when the interface for kills/notifications
+                         * is more stable we can extend service results table similar to how kernel oom kills
+                         * are managed. */
+                        (void) unit_check_oomd_kill(u1);
+
                         manager_invoke_sigchld_event(m, u1, &si);
                 }
                 if (u2)
index 44b9f66e422a73de5949eb2bf701a84ab94ce2cb..0792fd8ede31de748f7f4e7dd72abacf1e3b89cc 100644 (file)
@@ -3571,6 +3571,9 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
         if (u->cpu_usage_last != NSEC_INFINITY)
                 (void) serialize_item_format(f, "cpu-usage-last", "%" PRIu64, u->cpu_usage_last);
 
+        if (u->managed_oom_kill_last > 0)
+                (void) serialize_item_format(f, "managed-oom-kill-last", "%" PRIu64, u->managed_oom_kill_last);
+
         if (u->oom_kill_last > 0)
                 (void) serialize_item_format(f, "oom-kill-last", "%" PRIu64, u->oom_kill_last);
 
@@ -3816,6 +3819,14 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
 
                         continue;
 
+                } else if (streq(l, "managed-oom-kill-last")) {
+
+                        r = safe_atou64(v, &u->managed_oom_kill_last);
+                        if (r < 0)
+                                log_unit_debug(u, "Failed to read managed OOM kill last %s, ignoring.", v);
+
+                        continue;
+
                 } else if (streq(l, "oom-kill-last")) {
 
                         r = safe_atou64(v, &u->oom_kill_last);
index 9b2ea6c79f7ea6fbc8cb8e562a7b9626ebe67495..1e6d7ccf6be2612f2de92754aecce0f640d873ac 100644 (file)
@@ -260,7 +260,10 @@ typedef struct Unit {
         nsec_t cpu_usage_base;
         nsec_t cpu_usage_last; /* the most recently read value */
 
-        /* The  current counter of the oom_kill field in the memory.events cgroup attribute */
+        /* The current counter of processes sent SIGKILL by systemd-oomd */
+        uint64_t managed_oom_kill_last;
+
+        /* The current counter of the oom_kill field in the memory.events cgroup attribute */
         uint64_t oom_kill_last;
 
         /* Where the io.stat data was at the time the unit was started */
index 05f00ed5770c42d039d19305645b4224a91b1c87..eea8c2c900ad8c32aef9aa6c9a88ecee5e471f48 100644 (file)
@@ -127,6 +127,9 @@ _SD_BEGIN_DECLARATIONS;
 #define SD_MESSAGE_OVERMOUNTING           SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7)
 #define SD_MESSAGE_OVERMOUNTING_STR       SD_ID128_MAKE_STR(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7)
 
+#define SD_MESSAGE_UNIT_OOMD_KILL         SD_ID128_MAKE(d9,89,61,1b,15,e4,4c,9d,bf,31,e3,c8,12,56,e4,ed)
+#define SD_MESSAGE_UNIT_OOMD_KILL_STR     SD_ID128_MAKE_STR(d9,89,61,1b,15,e4,4c,9d,bf,31,e3,c8,12,56,e4,ed)
+
 #define SD_MESSAGE_UNIT_OUT_OF_MEMORY     SD_ID128_MAKE(fe,6f,aa,94,e7,77,46,63,a0,da,52,71,78,91,d8,ef)
 #define SD_MESSAGE_UNIT_OUT_OF_MEMORY_STR SD_ID128_MAKE_STR(fe,6f,aa,94,e7,77,46,63,a0,da,52,71,78,91,d8,ef)