[lxc-devel] [lxc/master] confile: enable tune host's OOM preferences

tanyifeng on Github lxc-bot at linuxcontainers.org
Thu Dec 7 09:55:31 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 350 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171207/fcfde73c/attachment.bin>
-------------- next part --------------
From 2e736cdf4280c7127db4bb260df8ad00516bb55e Mon Sep 17 00:00:00 2001
From: Yifeng Tan <tanyifeng1 at huawei.com>
Date: Fri, 8 Dec 2017 02:00:47 +0800
Subject: [PATCH] confile: enable tune host's OOM preferences

Signed-off-by: Yifeng Tan <tanyifeng1 at huawei.com>
---
 doc/lxc.container.conf.sgml.in | 22 ++++++++++++++++++++++
 src/lxc/conf.h                 |  3 +++
 src/lxc/confile.c              | 33 +++++++++++++++++++++++++++++++++
 src/lxc/start.c                | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 91 insertions(+)

diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index 21d9cfcc1..1c496ed0b 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -338,6 +338,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
       </variablelist>
     </refsect2>
 
+    <refsect2>
+      <title>Oom score adjustment</title>
+      <para>
+        Specifies the adjustment to be made by the kernel when calculating oom scores
+        for a process. Valid values are between the range [-1000, 1000], where processes
+        with higher scores are preferred for being killed.
+      </para>
+      <variablelist>
+        <varlistentry>
+          <term>
+            <option>lxc.oom_score_adj</option>
+          </term>
+          <listitem>
+            <para>
+              An integer value containing the score given to the container
+              in order to tune OOM killer preferences.
+            </para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
     <refsect2>
       <title>Ephemeral</title>
       <para>
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index ce259c42b..63b3359fc 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -337,6 +337,9 @@ struct lxc_conf {
 	uid_t init_uid;
 	gid_t init_gid;
 
+	/* oom score adjustment */
+	int oom_score_adj;
+
 	/* indicator if the container will be destroyed on shutdown */
 	unsigned int ephemeral;
 
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 35f4326ba..d4887fd85 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -98,6 +98,7 @@ lxc_config_define(init_cmd);
 lxc_config_define(init_cwd);
 lxc_config_define(init_gid);
 lxc_config_define(init_uid);
+lxc_config_define(oom_score_adj);
 lxc_config_define(log_file);
 lxc_config_define(log_level);
 lxc_config_define(log_syslog);
@@ -178,6 +179,7 @@ static struct lxc_config_t config[] = {
 	{ "lxc.init.gid",                  false,                  set_config_init_gid,                    get_config_init_gid,                    clr_config_init_gid,                  },
 	{ "lxc.init.uid",                  false,                  set_config_init_uid,                    get_config_init_uid,                    clr_config_init_uid,                  },
 	{ "lxc.init.cwd",                  false,                  set_config_init_cwd,                    get_config_init_cwd,                    clr_config_init_cwd,                  },
+	{ "lxc.oom_score_adj",             false,                  set_config_oom_score_adj,               get_config_oom_score_adj,               clr_config_oom_score_adj,             },
 	{ "lxc.log.file",                  false,                  set_config_log_file,                    get_config_log_file,                    clr_config_log_file,                  },
 	{ "lxc.log.level",                 false,                  set_config_log_level,                   get_config_log_level,                   clr_config_log_level,                 },
 	{ "lxc.log.syslog",                false,                  set_config_log_syslog,                  get_config_log_syslog,                  clr_config_log_syslog,                },
@@ -929,6 +931,24 @@ static int set_config_init_gid(const char *key, const char *value,
 	return 0;
 }
 
+static int set_config_oom_score_adj(const char *key, const char *value,
+			       struct lxc_conf *lxc_conf, void *data)
+{
+	int oom_score_adj;
+
+	if (lxc_config_value_empty(value)) {
+		lxc_conf->oom_score_adj = 0;
+		return 0;
+	}
+
+	if (lxc_safe_int(value, &oom_score_adj) < 0)
+		return -1;
+
+	lxc_conf->oom_score_adj = oom_score_adj;
+
+	return 0;
+}
+
 static int set_config_hooks(const char *key, const char *value,
 			    struct lxc_conf *lxc_conf, void *data)
 {
@@ -3207,6 +3227,12 @@ static int get_config_init_gid(const char *key, char *retv, int inlen,
 	return lxc_get_conf_int(c, retv, inlen, c->init_gid);
 }
 
+static int get_config_oom_score_adj(const char *key, char *retv, int inlen,
+			       struct lxc_conf *c, void *data)
+{
+	return lxc_get_conf_int(c, retv, inlen, c->oom_score_adj);
+}
+
 static int get_config_ephemeral(const char *key, char *retv, int inlen,
 				struct lxc_conf *c, void *data)
 {
@@ -3633,6 +3659,13 @@ static inline int clr_config_init_gid(const char *key, struct lxc_conf *c,
 	return 0;
 }
 
+static inline int clr_config_oom_score_adj(const char *key, struct lxc_conf *c,
+				      void *data)
+{
+	c->oom_score_adj = 0;
+	return 0;
+}
+
 static inline int clr_config_ephemeral(const char *key, struct lxc_conf *c,
 				       void *data)
 {
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 72e3f0146..41436dbd8 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -174,6 +174,34 @@ static bool preserve_ns(int ns_fd[LXC_NS_MAX], int clone_flags, pid_t pid)
 	return false;
 }
 
+static int set_oom_score_adj(int oom_score_adj, pid_t pid)
+{
+	int ret;
+	FILE *f;
+/* 5 /proc + 21 /int_as_str + 14 /oom_score_adj + 1 \0 */
+#define OOM_PATH_LEN 45
+	char path[OOM_PATH_LEN];
+
+	ret = snprintf(path, OOM_PATH_LEN, "/proc/%d/oom_score_adj", pid);
+	if (ret < 0 || (size_t)ret >= OOM_PATH_LEN)
+		return -EFBIG;
+
+	f = fopen(path, "w");
+	if (!f) {
+		ERROR("Failed to open %s", path);
+		return -1;
+	}
+
+	if (fprintf(f, "%d", oom_score_adj) < 0) {
+		ERROR("Error writing oom score");
+		fclose(f);
+		return -1;
+	}
+
+	fclose(f);
+	return 0;
+}
+
 static int match_fd(int fd)
 {
 	return (fd == 0 || fd == 1 || fd == 2);
@@ -1386,6 +1414,11 @@ static int lxc_spawn(struct lxc_handler *handler)
 		goto out_delete_net;
 	}
 
+	if (set_oom_score_adj(handler->conf->oom_score_adj, handler->pid)) {
+		ERROR("Failed to set oom score");
+		goto out_delete_net;
+	}
+
 	/* Tell the child to continue its initialization. We'll get
 	 * LXC_SYNC_CGROUP when it is ready for us to setup cgroups.
 	 */


More information about the lxc-devel mailing list