summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorAnita Zhang <the.anitazha@gmail.com>2020-09-09 00:24:23 -0700
committerAnita Zhang <the.anitazha@gmail.com>2020-10-07 17:12:24 -0700
commitfe8d22fb09ae6e5c4f27970bf29bf317d3c9d86a (patch)
treef02477e87a2e898093229448441c64fc7b2f8e6d /src/core
parent9de5e32136949a531e71cb31170025c2e1d3430e (diff)
downloadsystemd-fe8d22fb09ae6e5c4f27970bf29bf317d3c9d86a.tar.gz
core: systemd-oomd pid1 integration
Diffstat (limited to 'src/core')
-rw-r--r--src/core/cgroup.c41
-rw-r--r--src/core/cgroup.h1
-rw-r--r--src/core/manager.c5
-rw-r--r--src/core/unit.c11
-rw-r--r--src/core/unit.h5
5 files changed, 62 insertions, 1 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 95b5f2de59..1958c1be2b 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -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;
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
index 1f592ef559..881b3f3dfe 100644
--- a/src/core/cgroup.h
+++ b/src/core/cgroup.h
@@ -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);
diff --git a/src/core/manager.c b/src/core/manager.c
index d85d938e7b..611ecf23b2 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -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)
diff --git a/src/core/unit.c b/src/core/unit.c
index 44b9f66e42..0792fd8ede 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -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);
diff --git a/src/core/unit.h b/src/core/unit.h
index 9b2ea6c79f..1e6d7ccf6b 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -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 */