[lxc-devel] [lxc/master] Dont force irmap

tych0 on Github lxc-bot at linuxcontainers.org
Wed May 11 14:27:05 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160511/df36f1a7/attachment.bin>
-------------- next part --------------
From b2c3710f7485a6f8ae90bc79e25b408de075bcc4 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Fri, 6 May 2016 18:19:16 +0000
Subject: [PATCH 1/2] c/r: rearrange things to pass struct migrate_opts all the
 way down

If we don't do this, we'll end up changing the function signatures for the
internal __criu_* functions each time we add a new parameter, which will
get very annoying very quickly. Since we already have the user's arguments
struct, let's just pass that all the way down.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/criu.c         | 77 +++++++++++++++++++-------------------------------
 src/lxc/criu.h         |  6 ++--
 src/lxc/lxccontainer.c |  6 ++--
 3 files changed, 35 insertions(+), 54 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 3645bab..18cca3c 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -56,20 +56,13 @@ struct criu_opts {
 	/* The type of criu invocation, one of "dump" or "restore" */
 	char *action;
 
-	/* The directory to pass to criu */
-	char *directory;
+	/* the user-provided migrate options relevant to this action */
+	struct migrate_opts *user;
 
 	/* The container to dump */
 	struct lxc_container *c;
 
-	/* Enable criu verbose mode? */
-	bool verbose;
-
-	/* (pre-)dump: a directory for the previous dump's images */
-	char *predump_dir;
-
 	/* dump: stop the container or not after dumping? */
-	bool stop;
 	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 */
@@ -82,10 +75,6 @@ struct criu_opts {
 	 * different) on the target host. NULL if lxc.console = "none".
 	 */
 	char *console_name;
-
-	/* Address and port where a criu pageserver is listening */
-	char *pageserver_address;
-	char *pageserver_port;
 };
 
 static int load_tty_major_minor(char *directory, char *output, int len)
@@ -157,15 +146,15 @@ static void exec_criu(struct criu_opts *opts)
 		static_args += 4;
 
 		/* --prev-images-dir <path-to-directory-A-relative-to-B> */
-		if (opts->predump_dir)
+		if (opts->user->predump_dir)
 			static_args += 2;
 
 		/* --page-server --address <address> --port <port> */
-		if (opts->pageserver_address && opts->pageserver_port)
+		if (opts->user->pageserver_address && opts->user->pageserver_port)
 			static_args += 5;
 
 		/* --leave-running (only for final dump) */
-		if (strcmp(opts->action, "dump") == 0 && !opts->stop)
+		if (strcmp(opts->action, "dump") == 0 && !opts->user->stop)
 			static_args++;
 
 		/* --external tty[88,4] */
@@ -179,7 +168,7 @@ static void exec_criu(struct criu_opts *opts)
 		static_args += 10;
 
 		tty_info[0] = 0;
-		if (load_tty_major_minor(opts->directory, tty_info, sizeof(tty_info)))
+		if (load_tty_major_minor(opts->user->directory, tty_info, sizeof(tty_info)))
 			return;
 
 		/* --inherit-fd fd[%d]:tty[%s] */
@@ -189,10 +178,10 @@ static void exec_criu(struct criu_opts *opts)
 		return;
 	}
 
-	if (opts->verbose)
+	if (opts->user->verbose)
 		static_args++;
 
-	ret = snprintf(log, PATH_MAX, "%s/%s.log", opts->directory, opts->action);
+	ret = snprintf(log, PATH_MAX, "%s/%s.log", opts->user->directory, opts->action);
 	if (ret < 0 || ret >= PATH_MAX) {
 		ERROR("logfile name too long\n");
 		return;
@@ -236,11 +225,11 @@ static void exec_criu(struct criu_opts *opts)
 	DECLARE_ARG("--enable-fs");
 	DECLARE_ARG("tracefs");
 	DECLARE_ARG("-D");
-	DECLARE_ARG(opts->directory);
+	DECLARE_ARG(opts->user->directory);
 	DECLARE_ARG("-o");
 	DECLARE_ARG(log);
 
-	if (opts->verbose)
+	if (opts->user->verbose)
 		DECLARE_ARG("-vvvvvv");
 
 	if (strcmp(opts->action, "dump") == 0 || strcmp(opts->action, "pre-dump") == 0) {
@@ -275,21 +264,21 @@ static void exec_criu(struct criu_opts *opts)
 			DECLARE_ARG(opts->tty_id);
 		}
 
-		if (opts->predump_dir) {
+		if (opts->user->predump_dir) {
 			DECLARE_ARG("--prev-images-dir");
-			DECLARE_ARG(opts->predump_dir);
+			DECLARE_ARG(opts->user->predump_dir);
 		}
 
-		if (opts->pageserver_address && opts->pageserver_port) {
+		if (opts->user->pageserver_address && opts->user->pageserver_port) {
 			DECLARE_ARG("--page-server");
 			DECLARE_ARG("--address");
-			DECLARE_ARG(opts->pageserver_address);
+			DECLARE_ARG(opts->user->pageserver_address);
 			DECLARE_ARG("--port");
-			DECLARE_ARG(opts->pageserver_port);
+			DECLARE_ARG(opts->user->pageserver_port);
 		}
 
 		/* only for final dump */
-		if (strcmp(opts->action, "dump") == 0 && !opts->stop)
+		if (strcmp(opts->action, "dump") == 0 && !opts->user->stop)
 			DECLARE_ARG("--leave-running");
 	} else if (strcmp(opts->action, "restore") == 0) {
 		void *m;
@@ -556,7 +545,7 @@ static bool restore_net_info(struct lxc_container *c)
 
 // do_restore never returns, the calling process is used as the
 // monitor process. do_restore calls exit() if it fails.
-void do_restore(struct lxc_container *c, int status_pipe, char *directory, bool verbose)
+void do_restore(struct lxc_container *c, int status_pipe, struct migrate_opts *opts)
 {
 	pid_t pid;
 	char pidfile[L_tmpnam];
@@ -642,10 +631,9 @@ void do_restore(struct lxc_container *c, int status_pipe, char *directory, bool
 		}
 
 		os.action = "restore";
-		os.directory = directory;
+		os.user = opts;
 		os.c = c;
 		os.pidfile = pidfile;
-		os.verbose = verbose;
 		os.cgroup_path = cgroup_canonical_path(handler);
 		os.console_fd = c->lxc_conf->console.slave;
 
@@ -829,16 +817,14 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char *
 }
 
 /* do one of either predump or a regular dump */
-static bool do_dump(struct lxc_container *c, char *mode, char *directory,
-		    bool stop, bool verbose, char *predump_dir,
-		    char *pageserver_address, char *pageserver_port)
+static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *opts)
 {
 	pid_t pid;
 
 	if (!criu_ok(c))
 		return false;
 
-	if (mkdir_p(directory, 0700) < 0)
+	if (mkdir_p(opts->directory, 0700) < 0)
 		return false;
 
 	pid = fork();
@@ -851,16 +837,11 @@ static bool do_dump(struct lxc_container *c, char *mode, char *directory,
 		struct criu_opts os;
 
 		os.action = mode;
-		os.directory = directory;
+		os.user = opts;
 		os.c = c;
-		os.stop = stop;
-		os.verbose = verbose;
-		os.predump_dir = predump_dir;
 		os.console_name = c->lxc_conf->console.path;
-		os.pageserver_address = pageserver_address;
-		os.pageserver_port = pageserver_port;
 
-		if (save_tty_major_minor(directory, c, os.tty_id, sizeof(os.tty_id)) < 0)
+		if (save_tty_major_minor(opts->directory, c, os.tty_id, sizeof(os.tty_id)) < 0)
 			exit(1);
 
 		/* exec_criu() returning is an error */
@@ -891,17 +872,17 @@ static bool do_dump(struct lxc_container *c, char *mode, char *directory,
 	}
 }
 
-bool __criu_pre_dump(struct lxc_container *c, char *directory, bool verbose, char *predump_dir, char *pageserver_address, char *pageserver_port)
+bool __criu_pre_dump(struct lxc_container *c, struct migrate_opts *opts)
 {
-	return do_dump(c, "pre-dump", directory, false, verbose, predump_dir, pageserver_address, pageserver_port);
+	return do_dump(c, "pre-dump", opts);
 }
 
-bool __criu_dump(struct lxc_container *c, char *directory, bool stop, bool verbose, char *predump_dir, char *pageserver_address, char *pageserver_port)
+bool __criu_dump(struct lxc_container *c, struct migrate_opts *opts)
 {
 	char path[PATH_MAX];
 	int ret;
 
-	ret = snprintf(path, sizeof(path), "%s/inventory.img", directory);
+	ret = snprintf(path, sizeof(path), "%s/inventory.img", opts->directory);
 	if (ret < 0 || ret >= sizeof(path))
 		return false;
 
@@ -910,10 +891,10 @@ bool __criu_dump(struct lxc_container *c, char *directory, bool stop, bool verbo
 		return false;
 	}
 
-	return do_dump(c, "dump", directory, stop, verbose, predump_dir, pageserver_address, pageserver_port);
+	return do_dump(c, "dump", opts);
 }
 
-bool __criu_restore(struct lxc_container *c, char *directory, bool verbose)
+bool __criu_restore(struct lxc_container *c, struct migrate_opts *opts)
 {
 	pid_t pid;
 	int status, nread;
@@ -942,7 +923,7 @@ bool __criu_restore(struct lxc_container *c, char *directory, bool verbose)
 	if (pid == 0) {
 		close(pipefd[0]);
 		// this never returns
-		do_restore(c, pipefd[1], directory, verbose);
+		do_restore(c, pipefd[1], opts);
 	}
 
 	close(pipefd[1]);
diff --git a/src/lxc/criu.h b/src/lxc/criu.h
index db2ab11..ce94b31 100644
--- a/src/lxc/criu.h
+++ b/src/lxc/criu.h
@@ -27,8 +27,8 @@
 
 #include <lxc/lxccontainer.h>
 
-bool __criu_pre_dump(struct lxc_container *c, char *directory, bool verbose, char *predump_dir, char *pageserver_address, char *pageserver_port);
-bool __criu_dump(struct lxc_container *c, char *directory, bool stop, bool verbose, char *predump_dir, char *pageserver_address, char *pageserver_port);
-bool __criu_restore(struct lxc_container *c, char *directory, bool verbose);
+bool __criu_pre_dump(struct lxc_container *c, struct migrate_opts *opts);
+bool __criu_dump(struct lxc_container *c, struct migrate_opts *opts);
+bool __criu_restore(struct lxc_container *c, struct migrate_opts *opts);
 
 #endif
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 50cfc69..8bd9b8e 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -3968,13 +3968,13 @@ static int do_lxcapi_migrate(struct lxc_container *c, unsigned int cmd,
 
 	switch (cmd) {
 	case MIGRATE_PRE_DUMP:
-		ret = !__criu_pre_dump(c, opts->directory, opts->verbose, opts->predump_dir, opts->pageserver_address, opts->pageserver_port);
+		ret = !__criu_pre_dump(c, opts);
 		break;
 	case MIGRATE_DUMP:
-		ret = !__criu_dump(c, opts->directory, opts->stop, opts->verbose, opts->predump_dir, opts->pageserver_address, opts->pageserver_port);
+		ret = !__criu_dump(c, opts);
 		break;
 	case MIGRATE_RESTORE:
-		ret = !__criu_restore(c, opts->directory, opts->verbose);
+		ret = !__criu_restore(c, opts);
 		break;
 	default:
 		ERROR("invalid migrate command %u", cmd);

From 19d1509c398a910762d8b1d4ad90ddde356e5dd9 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.andersen at canonical.com>
Date: Wed, 11 May 2016 07:51:11 -0600
Subject: [PATCH 2/2] c/r: add an option to use faster inotify support in CRIU

The idea here is that criu can use open_by_handle on a configuration which
will preserve inodes on moves across hosts, but shouldn't do that on
configurations which won't preserve inodes. Before, we forced it to always
be slow, but we don't have to do this.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 src/lxc/criu.c         | 12 +++++++++---
 src/lxc/lxccontainer.h |  7 +++++++
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 18cca3c..ce8ada6 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -115,7 +115,7 @@ static int load_tty_major_minor(char *directory, char *output, int len)
 static void exec_criu(struct criu_opts *opts)
 {
 	char **argv, log[PATH_MAX];
-	int static_args = 24, argc = 0, i, ret;
+	int static_args = 23, argc = 0, i, ret;
 	int netnr = 0;
 	struct lxc_list *it;
 
@@ -134,7 +134,7 @@ static void exec_criu(struct criu_opts *opts)
 	}
 
 	/* The command line always looks like:
-	 * criu $(action) --tcp-established --file-locks --link-remap --force-irmap \
+	 * criu $(action) --tcp-established --file-locks --link-remap \
 	 * --manage-cgroups action-script foo.sh -D $(directory) \
 	 * -o $(directory)/$(action).log --ext-mount-map auto
 	 * --enable-external-sharing --enable-external-masters
@@ -160,6 +160,10 @@ static void exec_criu(struct criu_opts *opts)
 		/* --external tty[88,4] */
 		if (opts->tty_id[0])
 			static_args += 2;
+
+		/* --force-irmap */
+		if (!opts->user->preserves_inodes)
+			static_args++;
 	} else if (strcmp(opts->action, "restore") == 0) {
 		/* --root $(lxc_mount_point) --restore-detached
 		 * --restore-sibling --pidfile $foo --cgroup-root $foo
@@ -214,7 +218,6 @@ static void exec_criu(struct criu_opts *opts)
 	DECLARE_ARG("--tcp-established");
 	DECLARE_ARG("--file-locks");
 	DECLARE_ARG("--link-remap");
-	DECLARE_ARG("--force-irmap");
 	DECLARE_ARG("--manage-cgroups");
 	DECLARE_ARG("--ext-mount-map");
 	DECLARE_ARG("auto");
@@ -277,6 +280,9 @@ static void exec_criu(struct criu_opts *opts)
 			DECLARE_ARG(opts->user->pageserver_port);
 		}
 
+		if (!opts->user->preserves_inodes)
+			DECLARE_ARG("--force-irmap");
+
 		/* only for final dump */
 		if (strcmp(opts->action, "dump") == 0 && !opts->user->stop)
 			DECLARE_ARG("--leave-running");
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 0e014bc..ecc66e2 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -884,6 +884,13 @@ struct migrate_opts {
 	char *predump_dir; /* relative to directory above */
 	char *pageserver_address; /* where should memory pages be send? */
 	char *pageserver_port;
+
+	/* This flag indicates whether or not the container's rootfs will have
+	 * the same inodes on checkpoint and restore. In the case of e.g. zfs
+	 * send or btrfs send, or an LVM snapshot, this will be true, but it
+	 * won't if e.g. you rsync the filesystems between two machines.
+	 */
+	bool preserves_inodes;
 };
 
 /*!


More information about the lxc-devel mailing list