Commit 5f4e44a2 by Tycho Andersen

c/r: explicitly emit bind mounts as criu arguments

We switched to --ext-mount-map auto because of "system" (liblxc) added mounts like the cgmanager socket that weren't in the config file. This had the added advantage that we could drop all the mount processing code, because we no longer needed an --ext-mount-map argument. The problem here is that mounts can move between hosts. While --ext-mount-map auto does its best to detect this situation, it explicitly disallows moves that change the path name. In LXD, we bind mount /var/lib/lxd/shmounts/$container to /dev/.lxd-mounts for each container, and so when a container is renamed in a migration, the name changes. --ext-mount-map auto won't detect this, and so the migration fails. We *could* implement mount rewriting in CRIU, but my experience with cgroup and apparmor rewriting is that this is painful and error prone. Instead, it is much easier to go back to explicitly listing --ext-mount-map arguments from the config file, and allow the source of the bind to change. We leave --ext-mount-map auto to catch any stragling (or future) system added mounts. I believe this should fix Launchpad Bug 1580765 Signed-off-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
parent dfef27a5
...@@ -46,6 +46,12 @@ ...@@ -46,6 +46,12 @@
#include "network.h" #include "network.h"
#include "utils.h" #include "utils.h"
#if IS_BIONIC
#include <../include/lxcmntent.h>
#else
#include <mntent.h>
#endif
#define CRIU_VERSION "2.0" #define CRIU_VERSION "2.0"
#define CRIU_GITID_VERSION "2.0" #define CRIU_GITID_VERSION "2.0"
...@@ -123,6 +129,8 @@ static void exec_criu(struct criu_opts *opts) ...@@ -123,6 +129,8 @@ static void exec_criu(struct criu_opts *opts)
int static_args = 23, argc = 0, i, ret; int static_args = 23, argc = 0, i, ret;
int netnr = 0; int netnr = 0;
struct lxc_list *it; struct lxc_list *it;
FILE *mnts;
struct mntent mntent;
char buf[4096], tty_info[32]; char buf[4096], tty_info[32];
size_t pos; size_t pos;
...@@ -200,6 +208,8 @@ static void exec_criu(struct criu_opts *opts) ...@@ -200,6 +208,8 @@ static void exec_criu(struct criu_opts *opts)
if (opts->user->action_script) if (opts->user->action_script)
static_args += 2; static_args += 2;
static_args += 2 * lxc_list_len(&opts->c->lxc_conf->mount_list);
ret = snprintf(log, PATH_MAX, "%s/%s.log", opts->user->directory, opts->action); ret = snprintf(log, PATH_MAX, "%s/%s.log", opts->user->directory, opts->action);
if (ret < 0 || ret >= PATH_MAX) { if (ret < 0 || ret >= PATH_MAX) {
ERROR("logfile name too long\n"); ERROR("logfile name too long\n");
...@@ -315,6 +325,36 @@ static void exec_criu(struct criu_opts *opts) ...@@ -315,6 +325,36 @@ static void exec_criu(struct criu_opts *opts)
DECLARE_ARG(opts->user->action_script); DECLARE_ARG(opts->user->action_script);
} }
mnts = write_mount_file(&opts->c->lxc_conf->mount_list);
if (!mnts)
goto err;
while (getmntent_r(mnts, &mntent, buf, sizeof(buf))) {
char *fmt, *key, *val;
char arg[2 * PATH_MAX + 2];
if (strcmp(opts->action, "dump") == 0) {
fmt = "/%s:%s";
key = mntent.mnt_dir;
val = mntent.mnt_dir;
} else {
fmt = "%s:%s";
key = mntent.mnt_dir;
val = mntent.mnt_fsname;
}
ret = snprintf(arg, sizeof(arg), fmt, key, val);
if (ret < 0 || ret >= sizeof(arg)) {
fclose(mnts);
ERROR("snprintf failed");
goto err;
}
DECLARE_ARG("--ext-mount-map");
DECLARE_ARG(arg);
}
fclose(mnts);
if (strcmp(opts->action, "dump") == 0 || strcmp(opts->action, "pre-dump") == 0) { if (strcmp(opts->action, "dump") == 0 || strcmp(opts->action, "pre-dump") == 0) {
char pid[32], *freezer_relative; char pid[32], *freezer_relative;
......
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