]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
c/r: pass --cgroup-roots on checkpoint
authorTycho Andersen <tycho.andersen@canonical.com>
Wed, 14 Sep 2016 14:47:38 +0000 (14:47 +0000)
committerTycho Andersen <tycho.andersen@canonical.com>
Fri, 16 Sep 2016 21:19:07 +0000 (15:19 -0600)
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@canonical.com>
src/lxc/criu.c

index 2799102eab75ee8163275fd04beb10cba48daae6..0702ad2f1056f1f7b950d8e813bbaf4f75f36e4f 100644 (file)
@@ -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;