[lxc-devel] [lxc/master] Cgroup root on dump

tych0 on Github lxc-bot at linuxcontainers.org
Fri Sep 16 21:20:48 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 490 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160916/7c4edec7/attachment.bin>
-------------- next part --------------
From 5f178bc983a7050205b0ba374163646e9e378cf6 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Mon, 12 Sep 2016 18:04:18 +0000
Subject: [PATCH 1/6] c/r: fix typo in comment

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

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 71c9b9c..2799102 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -140,7 +140,7 @@ static void exec_criu(struct criu_opts *opts)
 
 	/* The command line always looks like:
 	 * criu $(action) --tcp-established --file-locks --link-remap \
-	 * --manage-cgroups=full action-script foo.sh -D $(directory) \
+	 * --manage-cgroups=full --action-script foo.sh -D $(directory) \
 	 * -o $(directory)/$(action).log --ext-mount-map auto
 	 * --enable-external-sharing --enable-external-masters
 	 * --enable-fs hugetlbfs --enable-fs tracefs --ext-mount-map console:/dev/pts/n

From 36662416441b051bf9d3bb0e1b5d08a61b3a6420 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Wed, 14 Sep 2016 14:38:46 +0000
Subject: [PATCH 2/6] cgroup: add new functions for interacting with hierachies

N.B. that these are only implemented in cgfsng, but,

15:28:28    tych0 | do we still use cgfs anywhere? or the cgm backend?
15:29:19 stgraber | not anywhere we care about

...I think that's okay.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/cgroups/cgfs.c      | 14 ++++++++++++++
 src/lxc/cgroups/cgfsng.c    | 27 +++++++++++++++++++++++++++
 src/lxc/cgroups/cgmanager.c | 14 ++++++++++++++
 src/lxc/cgroups/cgroup.c    | 16 ++++++++++++++++
 src/lxc/cgroups/cgroup.h    |  4 ++++
 5 files changed, 75 insertions(+)

diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c
index 2d0de0c..80a336d 100644
--- a/src/lxc/cgroups/cgfs.c
+++ b/src/lxc/cgroups/cgfs.c
@@ -2434,6 +2434,18 @@ static bool cgfs_escape(void *hdata)
 	return ret;
 }
 
+static int cgfs_num_hierarchies(void)
+{
+	/* not implemented */
+	return -1;
+}
+
+static bool cgfs_get_hierarchies(int i, char ***out)
+{
+	/* not implemented */
+	return false;
+}
+
 static bool cgfs_unfreeze(void *hdata)
 {
 	struct cgfs_data *d = hdata;
@@ -2627,6 +2639,8 @@ static struct cgroup_ops cgfs_ops = {
 	.get_cgroup = cgfs_get_cgroup,
 	.canonical_path = cgfs_canonical_path,
 	.escape = cgfs_escape,
+	.num_hierarchies = cgfs_num_hierarchies,
+	.get_hierarchies = cgfs_get_hierarchies,
 	.get = lxc_cgroupfs_get,
 	.set = lxc_cgroupfs_set,
 	.unfreeze = cgfs_unfreeze,
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 95f29ca..5b61554 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1457,6 +1457,31 @@ static bool cgfsng_escape()
 	return ret;
 }
 
+static int cgfsng_num_hierarchies(void)
+{
+	int i;
+
+	for (i = 0; hierarchies[i]; i++)
+		;
+
+	return i;
+}
+
+static bool cgfsng_get_hierarchies(int n, char ***out)
+{
+	int i;
+
+	/* sanity check n */
+	for (i = 0; i < n; i++) {
+		if (!hierarchies[i])
+			return false;
+	}
+
+	*out = hierarchies[i]->controllers;
+
+	return true;
+}
+
 #define THAWED "THAWED"
 #define THAWED_LEN (strlen(THAWED))
 
@@ -1674,6 +1699,8 @@ static struct cgroup_ops cgfsng_ops = {
 	.enter = cgfsng_enter,
 	.canonical_path = cgfsng_canonical_path,
 	.escape = cgfsng_escape,
+	.num_hierarchies = cgfsng_num_hierarchies,
+	.get_hierarchies = cgfsng_get_hierarchies,
 	.get_cgroup = cgfsng_get_cgroup,
 	.get = cgfsng_get,
 	.set = cgfsng_set,
diff --git a/src/lxc/cgroups/cgmanager.c b/src/lxc/cgroups/cgmanager.c
index 4da891d..f14eb17 100644
--- a/src/lxc/cgroups/cgmanager.c
+++ b/src/lxc/cgroups/cgmanager.c
@@ -337,6 +337,18 @@ static bool cgm_escape(void *hdata)
 	return ret;
 }
 
+static int cgm_num_hierarchies(void)
+{
+	/* not implemented */
+	return -1;
+}
+
+static bool cgm_get_hierarchies(int i, char ***out)
+{
+	/* not implemented */
+	return false;
+}
+
 struct chown_data {
 	const char *cgroup_path;
 	uid_t origuid;
@@ -1657,6 +1669,8 @@ static struct cgroup_ops cgmanager_ops = {
 	.get_cgroup = cgm_get_cgroup,
 	.canonical_path = cgm_canonical_path,
 	.escape = cgm_escape,
+	.num_hierarchies = cgm_num_hierarchies,
+	.get_hierarchies = cgm_get_hierarchies,
 	.get = cgm_get,
 	.set = cgm_set,
 	.unfreeze = cgm_unfreeze,
diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index 91ef359..48cd403 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -132,6 +132,22 @@ const char *cgroup_canonical_path(struct lxc_handler *handler)
 	return NULL;
 }
 
+int cgroup_num_hierarchies(void)
+{
+	if (!ops)
+		return -1;
+
+	return ops->num_hierarchies();
+}
+
+bool cgroup_get_hierarchies(int n, char ***out)
+{
+	if (!ops)
+		return false;
+
+	return ops->get_hierarchies(n, out);
+}
+
 bool cgroup_unfreeze(struct lxc_handler *handler)
 {
 	if (ops)
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index e56a115..f65cbfe 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -49,6 +49,8 @@ struct cgroup_ops {
 	const char *(*get_cgroup)(void *hdata, const char *subsystem);
 	const char *(*canonical_path)(void *hdata);
 	bool (*escape)();
+	int (*num_hierarchies)();
+	bool (*get_hierarchies)(int n, char ***out);
 	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);
@@ -74,6 +76,8 @@ 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();
+extern int cgroup_num_hierarchies();
+extern bool cgroup_get_hierarchies(int i, char ***out);
 
 /*
  * Currently, this call  only makes sense for privileged containers.

From aeb3682ff631e6afaa9c0b5d8a32654e8ebd2771 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Wed, 14 Sep 2016 14:46:47 +0000
Subject: [PATCH 3/6] utils: add lxc_deslashify

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/utils.c | 18 ++++++++++++++++++
 src/lxc/utils.h |  2 ++
 2 files changed, 20 insertions(+)

diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 27362da..9a6ef4b 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -716,6 +716,24 @@ char **lxc_normalize_path(const char *path)
 	return components;
 }
 
+bool lxc_deslashify(char *path)
+{
+	char **parts = NULL, *path2;
+
+	parts = lxc_normalize_path(path);
+	if (!parts)
+		return false;
+
+	path2 = lxc_string_join("/", (const char **) parts, *path == '/');
+	lxc_free_array((void **) parts, free);
+	if (!path2)
+		return false;
+
+	strncpy(path, path2, strlen(path));
+	free(path2);
+	return true;
+}
+
 char *lxc_append_paths(const char *first, const char *second)
 {
 	size_t len = strlen(first) + strlen(second) + 1;
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 98b4e13..c2eef50 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -248,6 +248,8 @@ extern char *lxc_string_join(const char *sep, const char **parts, bool use_as_pr
  *     foo//bar     ->   { foo, bar, NULL }
  */
 extern char **lxc_normalize_path(const char *path);
+/* remove multiple slashes from the path, e.g. ///foo//bar -> /foo/bar */
+extern bool lxc_deslashify(char *path);
 extern char *lxc_append_paths(const char *first, const char *second);
 /* Note: the following two functions use strtok(), so they will never
  *       consider an empty element, even if two delimiters are next to

From 0ab5703fcff8aafc3512c8b3cb446780b1c6974c Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Wed, 14 Sep 2016 14:47:38 +0000
Subject: [PATCH 4/6] c/r: pass --cgroup-roots on checkpoint

CRIU has added support for passing --cgroup-root on dump, which we should
use (see the criu commit 07d259f365f224b32914de26ea0fd59fc6db0001 for
details). Note that we don't have to do any version checking or anything,
because CRIU just ignored --cgroup-root on checkpoint before, so passing it
is safe, and will result in correct behavior when a sufficient version of
CRIU is present.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/criu.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 73 insertions(+), 6 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 2799102..0702ad2 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -69,7 +69,7 @@ struct criu_opts {
 	char tty_id[32]; /* the criu tty id for /dev/console, i.e. "tty[${rdev}:${dev}]" */
 
 	/* restore: the file to write the init process' pid into */
-	const char *cgroup_path;
+	struct lxc_handler *handler;
 	int console_fd;
 	/* The path that is bind mounted from /dev/console, if any. We don't
 	 * want to use `--ext-mount-map auto`'s result here because the pts
@@ -175,10 +175,10 @@ static void exec_criu(struct criu_opts *opts)
 			static_args += 2;
 	} else if (strcmp(opts->action, "restore") == 0) {
 		/* --root $(lxc_mount_point) --restore-detached
-		 * --restore-sibling --cgroup-root $foo
+		 * --restore-sibling
 		 * --lsm-profile apparmor:whatever
 		 */
-		static_args += 8;
+		static_args += 6;
 
 		tty_info[0] = 0;
 		if (load_tty_major_minor(opts->user->directory, tty_info, sizeof(tty_info)))
@@ -191,6 +191,8 @@ static void exec_criu(struct criu_opts *opts)
 		return;
 	}
 
+	static_args += 2 * cgroup_num_hierarchies();
+
 	if (opts->user->verbose)
 		static_args++;
 
@@ -244,6 +246,66 @@ static void exec_criu(struct criu_opts *opts)
 	DECLARE_ARG("-o");
 	DECLARE_ARG(log);
 
+	for (i = 0; i < cgroup_num_hierarchies(); i++) {
+		char **controllers = NULL, *fullname;
+		char *path;
+
+		if (!cgroup_get_hierarchies(i, &controllers)) {
+			ERROR("failed to get hierarchy %d", i);
+			goto err;
+		}
+
+		/* if we are in a dump, we have to ask the monitor process what
+		 * the right cgroup is. if this is a restore, we can just use
+		 * the handler the restore task created.
+		 */
+		if (!strcmp(opts->action, "dump") || !strcmp(opts->action, "pre-dump")) {
+			path = lxc_cmd_get_cgroup_path(opts->c->name, opts->c->config_path, controllers[0]);
+			if (!path) {
+				ERROR("failed to get cgroup path for %s", controllers[0]);
+				goto err;
+			}
+		} else {
+			const char *p;
+
+			p = cgroup_get_cgroup(opts->handler, controllers[0]);
+			if (!p) {
+				ERROR("failed to get cgroup path for %s", controllers[0]);
+				goto err;
+			}
+
+			path = strdup(p);
+			if (!path) {
+				ERROR("strdup failed");
+				goto err;
+			}
+		}
+
+		if (!lxc_deslashify(path)) {
+			ERROR("failed to deslashify %s", path);
+			free(path);
+			goto err;
+		}
+
+		fullname = lxc_string_join(",", (const char **) controllers, false);
+		if (!fullname) {
+			ERROR("failed to join controllers");
+			free(path);
+			goto err;
+		}
+
+		ret = sprintf(buf, "%s:%s", fullname, path);
+		free(path);
+		free(fullname);
+		if (ret < 0 || ret >= sizeof(buf)) {
+			ERROR("sprintf of cgroup root arg failed");
+			goto err;
+		}
+
+		DECLARE_ARG("--cgroup-root");
+		DECLARE_ARG(buf);
+	}
+
 	if (opts->user->verbose)
 		DECLARE_ARG("-vvvvvv");
 
@@ -329,8 +391,6 @@ static void exec_criu(struct criu_opts *opts)
 		DECLARE_ARG(opts->c->lxc_conf->rootfs.mount);
 		DECLARE_ARG("--restore-detached");
 		DECLARE_ARG("--restore-sibling");
-		DECLARE_ARG("--cgroup-root");
-		DECLARE_ARG(opts->cgroup_path);
 
 		if (tty_info[0]) {
 			if (opts->console_fd < 0) {
@@ -682,9 +742,9 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
 		os.action = "restore";
 		os.user = opts;
 		os.c = c;
-		os.cgroup_path = cgroup_canonical_path(handler);
 		os.console_fd = c->lxc_conf->console.slave;
 		os.criu_version = criu_version;
+		os.handler = handler;
 
 		if (os.console_fd >= 0) {
 			/* Twiddle the FD_CLOEXEC bit. We want to pass this FD to criu
@@ -891,6 +951,13 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
 
 	if (pid == 0) {
 		struct criu_opts os;
+		struct lxc_handler h;
+
+		h.name = c->name;
+		if (!cgroup_init(&h)) {
+			ERROR("failed to cgroup_init()");
+			exit(1);
+		}
 
 		os.action = mode;
 		os.user = opts;

From 6df334d1588dfcf99a405fb700971ac27cac438c Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Wed, 14 Sep 2016 14:53:21 +0000
Subject: [PATCH 5/6] cgroup: get rid of weird hack in cgfsng_escape

We initialized cgfsng in a strange way inside of its implementation of
escape so we could use it during checkpoint. Instead, the previous patch
does a hacky initialization in criu.c, and we can get rid of the hacks
elsewhere :)

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/cgroups/cgfsng.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 5b61554..0777bf3 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1426,19 +1426,11 @@ static int cgfsng_nrtasks(void *hdata) {
 /* Only root needs to escape to the cgroup of its init */
 static bool cgfsng_escape()
 {
-	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; hierarchies[i]; i++) {
 		char *fullpath = must_make_path(hierarchies[i]->mountpoint,
 						hierarchies[i]->base_cgroup,
@@ -1446,15 +1438,12 @@ static bool cgfsng_escape()
 		if (lxc_write_to_file(fullpath, "0", 2, false) != 0) {
 			SYSERROR("Failed to escape to %s", fullpath);
 			free(fullpath);
-			goto out;
+			return false;
 		}
 		free(fullpath);
 	}
 
-	ret = true;
-out:
-	free_handler_data(d);
-	return ret;
+	return true;
 }
 
 static int cgfsng_num_hierarchies(void)

From a0c91fccd9a1ae9c68a10880d4660d63a3b411e8 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Wed, 14 Sep 2016 14:58:38 +0000
Subject: [PATCH 6/6] cgroup: drop cgroup_canonical_path

This is almost never the right thing to use, and we don't use it any more
anyway.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/cgroups/cgfs.c      | 23 -----------------------
 src/lxc/cgroups/cgfsng.c    |  8 --------
 src/lxc/cgroups/cgmanager.c | 10 ----------
 src/lxc/cgroups/cgroup.c    | 13 -------------
 src/lxc/cgroups/cgroup.h    |  6 ------
 5 files changed, 60 deletions(-)

diff --git a/src/lxc/cgroups/cgfs.c b/src/lxc/cgroups/cgfs.c
index 80a336d..c5ba765 100644
--- a/src/lxc/cgroups/cgfs.c
+++ b/src/lxc/cgroups/cgfs.c
@@ -2363,28 +2363,6 @@ static const char *cgfs_get_cgroup(void *hdata, const char *subsystem)
 	return lxc_cgroup_get_hierarchy_path_data(subsystem, d);
 }
 
-static const char *cgfs_canonical_path(void *hdata)
-{
-	struct cgfs_data *d = hdata;
-	struct cgroup_process_info *info_ptr;
-	char *path = NULL;
-
-	if (!d)
-		return NULL;
-
-	for (info_ptr = d->info; info_ptr; info_ptr = info_ptr->next) {
-		if (!path)
-			path = info_ptr->cgroup_path;
-		else if (strcmp(path, info_ptr->cgroup_path) != 0) {
-			ERROR("not all paths match %s, %s has path %s", path,
-				info_ptr->hierarchy->subsystems[0], info_ptr->cgroup_path);
-			return NULL;
-		}
-	}
-
-	return path;
-}
-
 static bool cgfs_escape(void *hdata)
 {
 	struct cgroup_meta_data *md;
@@ -2637,7 +2615,6 @@ static struct cgroup_ops cgfs_ops = {
 	.enter = cgfs_enter,
 	.create_legacy = cgfs_create_legacy,
 	.get_cgroup = cgfs_get_cgroup,
-	.canonical_path = cgfs_canonical_path,
 	.escape = cgfs_escape,
 	.num_hierarchies = cgfs_num_hierarchies,
 	.get_hierarchies = cgfs_get_hierarchies,
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 0777bf3..ec94099 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1087,13 +1087,6 @@ static inline bool cgfsng_create(void *hdata)
 	return false;
 }
 
-static const char *cgfsng_canonical_path(void *hdata)
-{
-	struct cgfsng_handler_data *d = hdata;
-
-	return d->container_cgroup;
-}
-
 static bool cgfsng_enter(void *hdata, pid_t pid)
 {
 	char pidstr[25];
@@ -1686,7 +1679,6 @@ static struct cgroup_ops cgfsng_ops = {
 	.destroy = cgfsng_destroy,
 	.create = cgfsng_create,
 	.enter = cgfsng_enter,
-	.canonical_path = cgfsng_canonical_path,
 	.escape = cgfsng_escape,
 	.num_hierarchies = cgfsng_num_hierarchies,
 	.get_hierarchies = cgfsng_get_hierarchies,
diff --git a/src/lxc/cgroups/cgmanager.c b/src/lxc/cgroups/cgmanager.c
index f14eb17..f2756b0 100644
--- a/src/lxc/cgroups/cgmanager.c
+++ b/src/lxc/cgroups/cgmanager.c
@@ -746,15 +746,6 @@ static const char *cgm_get_cgroup(void *hdata, const char *subsystem)
 	return d->cgroup_path;
 }
 
-static const char *cgm_canonical_path(void *hdata)
-{
-	struct cgm_data *d = hdata;
-
-	if (!d || !d->cgroup_path)
-		return NULL;
-	return d->cgroup_path;
-}
-
 #if HAVE_CGMANAGER_GET_PID_CGROUP_ABS_SYNC
 static inline bool abs_cgroup_supported(void) {
 	return api_version >= CGM_SUPPORTS_GET_ABS;
@@ -1667,7 +1658,6 @@ static struct cgroup_ops cgmanager_ops = {
 	.enter = cgm_enter,
 	.create_legacy = NULL,
 	.get_cgroup = cgm_get_cgroup,
-	.canonical_path = cgm_canonical_path,
 	.escape = cgm_escape,
 	.num_hierarchies = cgm_num_hierarchies,
 	.get_hierarchies = cgm_get_hierarchies,
diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index 48cd403..78472d4 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -119,19 +119,6 @@ bool cgroup_escape(struct lxc_handler *handler)
 	return false;
 }
 
-const char *cgroup_canonical_path(struct lxc_handler *handler)
-{
-	if (geteuid()) {
-		WARN("cgroup_canonical_path only makes sense for privileged containers.\n");
-		return NULL;
-	}
-
-	if (ops)
-		return ops->canonical_path(handler->cgroup_data);
-
-	return NULL;
-}
-
 int cgroup_num_hierarchies(void)
 {
 	if (!ops)
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index f65cbfe..11b251e 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -47,7 +47,6 @@ struct cgroup_ops {
 	bool (*enter)(void *hdata, pid_t pid);
 	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)();
 	int (*num_hierarchies)();
 	bool (*get_hierarchies)(int n, char ***out);
@@ -78,11 +77,6 @@ extern const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *su
 extern bool cgroup_escape();
 extern int cgroup_num_hierarchies();
 extern bool cgroup_get_hierarchies(int i, char ***out);
-
-/*
- * Currently, this call  only makes sense for privileged containers.
- */
-extern const char *cgroup_canonical_path(struct lxc_handler *handler);
 extern bool cgroup_unfreeze(struct lxc_handler *handler);
 extern void cgroup_disconnect(void);
 extern cgroup_driver_t cgroup_driver(void);


More information about the lxc-devel mailing list