From: Tycho Andersen Date: Tue, 8 Dec 2015 00:07:05 +0000 (-0700) Subject: cgroup: add cgroup_escape() call X-Git-Tag: lxc-2.0.0.beta1~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06078509e389d093b85465e9eef9215928ee51a0;p=thirdparty%2Flxc.git cgroup: add cgroup_escape() call We'll use this in the next patch to escape to the root cgroup before we exec criu. v2: s/cgm_connected/cmg_needs_disconnect/g Signed-off-by: Tycho Andersen Acked-by: Serge E. Hallyn --- diff --git a/src/lxc/cgfs.c b/src/lxc/cgfs.c index d65f2d709..94b3d879c 100644 --- a/src/lxc/cgfs.c +++ b/src/lxc/cgfs.c @@ -2343,6 +2343,55 @@ static const char *cgfs_canonical_path(void *hdata) return path; } +static bool cgfs_escape(void) +{ + struct cgroup_meta_data *md; + int i; + bool ret = false; + + md = lxc_cgroup_load_meta(); + if (!md) + return false; + + for (i = 1; i <= md->maximum_hierarchy; i++) { + struct cgroup_hierarchy *h = md->hierarchies[i]; + struct cgroup_mount_point *mp; + char *tasks; + FILE *f; + int written; + + if (!h) { + WARN("not escaping hierarchy %d", i); + continue; + } + + mp = lxc_cgroup_find_mount_point(h, "/", true); + if (!mp) + goto out; + + tasks = cgroup_to_absolute_path(mp, "/", "tasks"); + if (!tasks) + goto out; + + f = fopen(tasks, "a"); + free(tasks); + if (!f) + goto out; + + written = fprintf(f, "%d\n", getpid()); + fclose(f); + if (written < 0) { + SYSERROR("writing tasks failed\n"); + goto out; + } + } + + ret = true; +out: + lxc_cgroup_put_meta(md); + return ret; +} + static bool cgfs_unfreeze(void *hdata) { struct cgfs_data *d = hdata; @@ -2408,6 +2457,7 @@ static struct cgroup_ops cgfs_ops = { .create_legacy = cgfs_create_legacy, .get_cgroup = cgfs_get_cgroup, .canonical_path = cgfs_canonical_path, + .escape = cgfs_escape, .get = lxc_cgroupfs_get, .set = lxc_cgroupfs_set, .unfreeze = cgfs_unfreeze, diff --git a/src/lxc/cgmanager.c b/src/lxc/cgmanager.c index 05df0da6e..b82be599c 100644 --- a/src/lxc/cgmanager.c +++ b/src/lxc/cgmanager.c @@ -312,13 +312,22 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path * be in "/lxc/c1" rather than "/user/..../c1" * called internally with connection already open */ -static bool lxc_cgmanager_escape(void) +static bool cgm_escape(void) { - bool ret = true; + bool ret = true, cgm_needs_disconnect = false; pid_t me = getpid(); char **slist = subsystems; int i; + if (!cgroup_manager) { + if (!cgm_dbus_connect()) { + ERROR("Error connecting to cgroup manager"); + return false; + } + cgm_needs_disconnect = true; + } + + if (cgm_all_controllers_same) slist = subsystems_inone; @@ -335,6 +344,9 @@ static bool lxc_cgmanager_escape(void) } } + if (cgm_needs_disconnect) + cgm_dbus_disconnect(); + return ret; } @@ -1307,7 +1319,7 @@ struct cgroup_ops *cgm_ops_init(void) goto err1; // root; try to escape to root cgroup - if (geteuid() == 0 && !lxc_cgmanager_escape()) + if (geteuid() == 0 && !cgm_escape()) goto err2; cgm_dbus_disconnect(); @@ -1524,6 +1536,7 @@ static struct cgroup_ops cgmanager_ops = { .create_legacy = NULL, .get_cgroup = cgm_get_cgroup, .canonical_path = cgm_canonical_path, + .escape = cgm_escape, .get = cgm_get, .set = cgm_set, .unfreeze = cgm_unfreeze, diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index 0f7a2ac16..8954733c1 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -109,6 +109,13 @@ const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem return NULL; } +bool cgroup_escape(void) +{ + if (ops) + return ops->escape(); + return false; +} + const char *cgroup_canonical_path(struct lxc_handler *handler) { if (geteuid()) { diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h index 7704c04d3..e3d3ce4cc 100644 --- a/src/lxc/cgroup.h +++ b/src/lxc/cgroup.h @@ -47,6 +47,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); 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); @@ -71,6 +72,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(void); /* * Currently, this call only makes sense for privileged containers.