]> git.proxmox.com Git - mirror_lxc.git/commitdiff
cgroup: add cgroup_escape() call
authorTycho Andersen <tycho.andersen@canonical.com>
Tue, 8 Dec 2015 00:07:05 +0000 (17:07 -0700)
committerStéphane Graber <stgraber@ubuntu.com>
Thu, 10 Dec 2015 04:00:21 +0000 (23:00 -0500)
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 <tycho.andersen@canonical.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
src/lxc/cgfs.c
src/lxc/cgmanager.c
src/lxc/cgroup.c
src/lxc/cgroup.h

index d65f2d709e0d934f47908cf628647b90aa2b8e64..94b3d879c76d2870aaff9c4c25a5fd76228fae94 100644 (file)
@@ -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,
index 05df0da6e8193fb14fb86d72c50590d8c1ef8254..b82be599c244cd3853ab57b181a6308247b15eb6 100644 (file)
@@ -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,
index 0f7a2ac16cba2b97cee0ea5679d10e230e6df658..8954733c12ca6e2a423dff97d6f5c411fd2174e7 100644 (file)
@@ -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()) {
index 7704c04d391b8a208bfaa278c19decdd15c05ef8..e3d3ce4cc7464b1a7d6ee58ddd4cae16d8aebc97 100644 (file)
@@ -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.