[lxc-devel] [lxc/master] Cgfsng fixes

tych0 on Github lxc-bot at linuxcontainers.org
Thu Mar 10 19:01:56 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 300 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160310/48ada5f8/attachment.bin>
-------------- next part --------------
From 9451eeffb0688b801034d963c455c8b31ccbf28c Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Thu, 10 Mar 2016 10:54:19 -0700
Subject: [PATCH 1/2] criu: make exec_criu static

This is no longer needed outside of criu.c with the ->migrate API call, so
let's mark it that way.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/criu.c | 2 +-
 src/lxc/criu.h | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 25e8d70..b4ebf42 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -47,7 +47,7 @@
 
 lxc_log_define(lxc_criu, lxc);
 
-void exec_criu(struct lxc_handler *handler, struct criu_opts *opts)
+static void exec_criu(struct criu_opts *opts)
 {
 	char **argv, log[PATH_MAX];
 	int static_args = 22, argc = 0, i, ret;
diff --git a/src/lxc/criu.h b/src/lxc/criu.h
index 75e6381..ed6dc81 100644
--- a/src/lxc/criu.h
+++ b/src/lxc/criu.h
@@ -58,8 +58,6 @@ struct criu_opts {
 	const char *cgroup_path;
 };
 
-void exec_criu(struct lxc_handler *handler, struct criu_opts *opts);
-
 /* Check and make sure the container has a configuration that we know CRIU can
  * dump. */
 bool criu_ok(struct lxc_container *c);

From 7103fe6f08cb04a498e3090d8416b4275a4a0d7e Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Thu, 10 Mar 2016 11:10:14 -0700
Subject: [PATCH 2/2] cgroup: cgroup_escape takes no arguments

cgroup_escape() is a slight abuse of the cgroup code: what we really want
here is to escape the *current* process, whether it happens to be the LXC
monitor or not, into the / cgroups.

In the case of dump, we can't do an lxc_init(), because:

lxc 20160310103501.547 ERROR    lxc_commands - commands.c:lxc_cmd_init:993 - ##
lxc 20160310103501.547 ERROR    lxc_commands - commands.c:lxc_cmd_init:994 - # The container appears to be already running!
lxc 20160310103501.547 ERROR    lxc_commands - commands.c:lxc_cmd_init:995 - ##

We don't want to make this a command to send to the handler, because again,
cgroup_escape() is intended to escape the *current* task to the root
cgroups.

So, let's just have cgroup_escape() build its own handler when required.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/cgfsng.c | 18 ++++++++++++++----
 src/lxc/cgroup.h |  4 ++--
 src/lxc/criu.c   | 16 +++-------------
 3 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/lxc/cgfsng.c b/src/lxc/cgfsng.c
index 32213bf..90b8358 100644
--- a/src/lxc/cgfsng.c
+++ b/src/lxc/cgfsng.c
@@ -1280,14 +1280,21 @@ static int cgfsng_nrtasks(void *hdata) {
 }
 
 /* Only root needs to escape to the cgroup of its init */
-static bool cgfsng_escape(void *hdata)
+static bool cgfsng_escape()
 {
-	struct cgfsng_handler_data *d = hdata;
+	struct cgfsng_handler_data *d;
 	int i;
+	bool ret = false;
 
 	if (geteuid())
 		return true;
 
+	d = cgfsng_init("criu-temp-cgfsng");
+	if (!d) {
+		ERROR("cgfsng_init failed");
+		return false;
+	}
+
 	for (i = 0; d->hierarchies[i]; i++) {
 		char *fullpath = must_make_path(d->hierarchies[i]->mountpoint,
 						d->hierarchies[i]->base_cgroup,
@@ -1295,12 +1302,15 @@ static bool cgfsng_escape(void *hdata)
 		if (lxc_write_to_file(fullpath, "0", 2, false) != 0) {
 			SYSERROR("Failed to escape to %s", fullpath);
 			free(fullpath);
-			return false;
+			goto out;
 		}
 		free(fullpath);
 	}
 
-	return true;
+	ret = true;
+out:
+	free_handler_data(d);
+	return ret;
 }
 
 #define THAWED "THAWED"
diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h
index ff3651e..e56a115 100644
--- a/src/lxc/cgroup.h
+++ b/src/lxc/cgroup.h
@@ -48,7 +48,7 @@ struct cgroup_ops {
 	bool (*create_legacy)(void *hdata, pid_t pid);
 	const char *(*get_cgroup)(void *hdata, const char *subsystem);
 	const char *(*canonical_path)(void *hdata);
-	bool (*escape)(void *hdata);
+	bool (*escape)();
 	int (*set)(const char *filename, const char *value, const char *name, const char *lxcpath);
 	int (*get)(const char *filename, char *value, size_t len, const char *name, const char *lxcpath);
 	bool (*unfreeze)(void *hdata);
@@ -73,7 +73,7 @@ extern void cgroup_cleanup(struct lxc_handler *handler);
 extern bool cgroup_create_legacy(struct lxc_handler *handler);
 extern int cgroup_nrtasks(struct lxc_handler *handler);
 extern const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem);
-extern bool cgroup_escape(struct lxc_handler *handler);
+extern bool cgroup_escape();
 
 /*
  * Currently, this call  only makes sense for privileged containers.
diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index b4ebf42..a683130 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -63,7 +63,7 @@ static void exec_criu(struct criu_opts *opts)
 	 * /actual/ root cgroup so that lxcfs thinks criu has enough rights to
 	 * see all cgroups.
 	 */
-	if (!cgroup_escape(handler)) {
+	if (!cgroup_escape()) {
 		ERROR("failed to escape cgroups");
 		return;
 	}
@@ -517,7 +517,7 @@ void do_restore(struct lxc_container *c, int pipe, char *directory, bool verbose
 		os.cgroup_path = cgroup_canonical_path(handler);
 
 		/* exec_criu() returning is an error */
-		exec_criu(handler, &os);
+		exec_criu(&os);
 		umount(rootfs->mount);
 		rmdir(rootfs->mount);
 		goto out_fini_handler;
@@ -624,16 +624,6 @@ static bool do_dump(struct lxc_container *c, char *mode, char *directory,
 
 	if (pid == 0) {
 		struct criu_opts os;
-		struct lxc_handler *handler;
-
-		handler = lxc_init(c->name, c->lxc_conf, c->config_path);
-		if (!handler)
-			exit(1);
-
-		if (!cgroup_init(handler)) {
-			ERROR("failed initing cgroups");
-			exit(1);
-		}
 
 		os.action = mode;
 		os.directory = directory;
@@ -643,7 +633,7 @@ static bool do_dump(struct lxc_container *c, char *mode, char *directory,
 		os.predump_dir = predump_dir;
 
 		/* exec_criu() returning is an error */
-		exec_criu(handler, &os);
+		exec_criu(&os);
 		exit(1);
 	} else {
 		int status;


More information about the lxc-devel mailing list