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@canonical.com>
}
/* 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,
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"
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);
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.
* /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;
}
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;
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;
os.predump_dir = predump_dir;
/* exec_criu() returning is an error */
- exec_criu(handler, &os);
+ exec_criu(&os);
exit(1);
} else {
int status;