Commit 06078509 by Tycho Andersen Committed by Stéphane Graber

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: 's avatarTycho Andersen <tycho.andersen@canonical.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent ba3004da
...@@ -2343,6 +2343,55 @@ static const char *cgfs_canonical_path(void *hdata) ...@@ -2343,6 +2343,55 @@ static const char *cgfs_canonical_path(void *hdata)
return path; 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) static bool cgfs_unfreeze(void *hdata)
{ {
struct cgfs_data *d = hdata; struct cgfs_data *d = hdata;
...@@ -2408,6 +2457,7 @@ static struct cgroup_ops cgfs_ops = { ...@@ -2408,6 +2457,7 @@ static struct cgroup_ops cgfs_ops = {
.create_legacy = cgfs_create_legacy, .create_legacy = cgfs_create_legacy,
.get_cgroup = cgfs_get_cgroup, .get_cgroup = cgfs_get_cgroup,
.canonical_path = cgfs_canonical_path, .canonical_path = cgfs_canonical_path,
.escape = cgfs_escape,
.get = lxc_cgroupfs_get, .get = lxc_cgroupfs_get,
.set = lxc_cgroupfs_set, .set = lxc_cgroupfs_set,
.unfreeze = cgfs_unfreeze, .unfreeze = cgfs_unfreeze,
......
...@@ -312,13 +312,22 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path ...@@ -312,13 +312,22 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path
* be in "/lxc/c1" rather than "/user/..../c1" * be in "/lxc/c1" rather than "/user/..../c1"
* called internally with connection already open * 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(); pid_t me = getpid();
char **slist = subsystems; char **slist = subsystems;
int i; 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) if (cgm_all_controllers_same)
slist = subsystems_inone; slist = subsystems_inone;
...@@ -335,6 +344,9 @@ static bool lxc_cgmanager_escape(void) ...@@ -335,6 +344,9 @@ static bool lxc_cgmanager_escape(void)
} }
} }
if (cgm_needs_disconnect)
cgm_dbus_disconnect();
return ret; return ret;
} }
...@@ -1307,7 +1319,7 @@ struct cgroup_ops *cgm_ops_init(void) ...@@ -1307,7 +1319,7 @@ struct cgroup_ops *cgm_ops_init(void)
goto err1; goto err1;
// root; try to escape to root cgroup // root; try to escape to root cgroup
if (geteuid() == 0 && !lxc_cgmanager_escape()) if (geteuid() == 0 && !cgm_escape())
goto err2; goto err2;
cgm_dbus_disconnect(); cgm_dbus_disconnect();
...@@ -1524,6 +1536,7 @@ static struct cgroup_ops cgmanager_ops = { ...@@ -1524,6 +1536,7 @@ static struct cgroup_ops cgmanager_ops = {
.create_legacy = NULL, .create_legacy = NULL,
.get_cgroup = cgm_get_cgroup, .get_cgroup = cgm_get_cgroup,
.canonical_path = cgm_canonical_path, .canonical_path = cgm_canonical_path,
.escape = cgm_escape,
.get = cgm_get, .get = cgm_get,
.set = cgm_set, .set = cgm_set,
.unfreeze = cgm_unfreeze, .unfreeze = cgm_unfreeze,
......
...@@ -109,6 +109,13 @@ const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem ...@@ -109,6 +109,13 @@ const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem
return NULL; return NULL;
} }
bool cgroup_escape(void)
{
if (ops)
return ops->escape();
return false;
}
const char *cgroup_canonical_path(struct lxc_handler *handler) const char *cgroup_canonical_path(struct lxc_handler *handler)
{ {
if (geteuid()) { if (geteuid()) {
......
...@@ -47,6 +47,7 @@ struct cgroup_ops { ...@@ -47,6 +47,7 @@ struct cgroup_ops {
bool (*create_legacy)(void *hdata, pid_t pid); bool (*create_legacy)(void *hdata, pid_t pid);
const char *(*get_cgroup)(void *hdata, const char *subsystem); const char *(*get_cgroup)(void *hdata, const char *subsystem);
const char *(*canonical_path)(void *hdata); const char *(*canonical_path)(void *hdata);
bool (*escape)(void);
int (*set)(const char *filename, const char *value, const char *name, const char *lxcpath); 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); int (*get)(const char *filename, char *value, size_t len, const char *name, const char *lxcpath);
bool (*unfreeze)(void *hdata); bool (*unfreeze)(void *hdata);
...@@ -71,6 +72,7 @@ extern void cgroup_cleanup(struct lxc_handler *handler); ...@@ -71,6 +72,7 @@ extern void cgroup_cleanup(struct lxc_handler *handler);
extern bool cgroup_create_legacy(struct lxc_handler *handler); extern bool cgroup_create_legacy(struct lxc_handler *handler);
extern int cgroup_nrtasks(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 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. * Currently, this call only makes sense for privileged containers.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment