]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
c/r: drop in-flight connections during CRIU dump 1072/head
authorAdrian Reber <areber@redhat.com>
Mon, 4 Jul 2016 14:58:09 +0000 (16:58 +0200)
committerAdrian Reber <areber@redhat.com>
Tue, 12 Jul 2016 12:09:17 +0000 (14:09 +0200)
Shortly after CRIU 2.3 has been released a patch has been added to skip
in-flight TCP connections. In-flight connections are not completely
established connections (SYN, SYN-ACK). Skipping in-flight TCP
connections means that the client has to re-initiate the connection
establishment.

This patch stores the CRIU version detected during version check, so
that during dump/checkpoint options can be dynamically enabled depending
on the available CRIU version.

v2:
   * use the newly introduced criu version interface
   * add an option to disable skipping in-flight connections

Signed-off-by: Adrian Reber <areber@redhat.com>
src/lxc/criu.c
src/lxc/lxccontainer.h

index 6bf06068366e489ec54cda94e822494d76dd92e9..630e67b55e147c9550aaac53c1baba1824d39239 100644 (file)
@@ -50,6 +50,8 @@
 #define CRIU_GITID_VERSION     "2.0"
 #define CRIU_GITID_PATCHLEVEL  0
 
+#define CRIU_IN_FLIGHT_SUPPORT "2.4"
+
 lxc_log_define(lxc_criu, lxc);
 
 struct criu_opts {
@@ -75,6 +77,9 @@ struct criu_opts {
         * different) on the target host. NULL if lxc.console = "none".
         */
        char *console_name;
+
+       /* The detected version of criu */
+       char *criu_version;
 };
 
 static int load_tty_major_minor(char *directory, char *output, int len)
@@ -264,6 +269,10 @@ static void exec_criu(struct criu_opts *opts)
                if (ret < 0 || ret >= sizeof(log))
                        goto err;
 
+               if (!opts->user->disable_skip_in_flight &&
+                               strcmp(opts->criu_version, CRIU_IN_FLIGHT_SUPPORT) >= 0)
+                       DECLARE_ARG("--skip-in-flight");
+
                DECLARE_ARG("--freeze-cgroup");
                DECLARE_ARG(log);
 
@@ -511,11 +520,11 @@ version_error:
 
 /* Check and make sure the container has a configuration that we know CRIU can
  * dump. */
-static bool criu_ok(struct lxc_container *c)
+static bool criu_ok(struct lxc_container *c, char **criu_version)
 {
        struct lxc_list *it;
 
-       if (!criu_version_ok(NULL))
+       if (!criu_version_ok(criu_version))
                return false;
 
        if (geteuid()) {
@@ -573,7 +582,7 @@ out_unlock:
 
 // 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, struct migrate_opts *opts)
+void do_restore(struct lxc_container *c, int status_pipe, struct migrate_opts *opts, char *criu_version)
 {
        pid_t pid;
        char pidfile[L_tmpnam];
@@ -664,6 +673,7 @@ void do_restore(struct lxc_container *c, int status_pipe, struct migrate_opts *o
                os.pidfile = pidfile;
                os.cgroup_path = cgroup_canonical_path(handler);
                os.console_fd = c->lxc_conf->console.slave;
+               os.criu_version = criu_version;
 
                if (os.console_fd >= 0) {
                        /* Twiddle the FD_CLOEXEC bit. We want to pass this FD to criu
@@ -848,8 +858,9 @@ static int save_tty_major_minor(char *directory, struct lxc_container *c, char *
 static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *opts)
 {
        pid_t pid;
+       char *criu_version = NULL;
 
-       if (!criu_ok(c))
+       if (!criu_ok(c, &criu_version))
                return false;
 
        if (mkdir_p(opts->directory, 0700) < 0)
@@ -868,6 +879,7 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
                os.user = opts;
                os.c = c;
                os.console_name = c->lxc_conf->console.path;
+               os.criu_version = criu_version;
 
                if (save_tty_major_minor(opts->directory, c, os.tty_id, sizeof(os.tty_id)) < 0)
                        exit(1);
@@ -927,8 +939,9 @@ bool __criu_restore(struct lxc_container *c, struct migrate_opts *opts)
        pid_t pid;
        int status, nread;
        int pipefd[2];
+       char *criu_version = NULL;
 
-       if (!criu_ok(c))
+       if (!criu_ok(c, &criu_version))
                return false;
 
        if (geteuid()) {
@@ -951,7 +964,7 @@ bool __criu_restore(struct lxc_container *c, struct migrate_opts *opts)
        if (pid == 0) {
                close(pipefd[0]);
                // this never returns
-               do_restore(c, pipefd[1], opts);
+               do_restore(c, pipefd[1], opts, criu_version);
        }
 
        close(pipefd[1]);
index bde4912bdce3a4e65888edd6ec19fe0b0964fea5..e4915d2ff18b8ab92f2bac1faa5aa5d5929a6407 100644 (file)
@@ -896,6 +896,12 @@ struct migrate_opts {
         * "action script"
         */
        char *action_script;
+
+       /* If CRIU >= 2.4 is detected the option to skip in-flight connections
+        * will be enabled by default. The flag 'disable_skip_in_flight' will
+        * unconditionally disable this feature. In-flight connections are
+        * not fully established TCP connections: SYN, SYN-ACK */
+       bool disable_skip_in_flight;
 };
 
 /*!