The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/1270

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From 5af85cb1447fec6f05513c0e34991ccd0f5a6560 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.ander...@canonical.com>
Date: Tue, 1 Nov 2016 17:07:26 -0600
Subject: [PATCH 1/2] c/r: save criu's stdout during dump too

This also allows us to commonize some bits of the dup2 code.

Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
---
 src/lxc/criu.c | 76 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 60 insertions(+), 16 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 867139b..f49968b 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -62,6 +62,9 @@
 lxc_log_define(lxc_criu, lxc);
 
 struct criu_opts {
+       /* the thing to hook to stdout and stderr for logging */
+       int pipefd;
+
        /* The type of criu invocation, one of "dump" or "restore" */
        char *action;
 
@@ -134,6 +137,7 @@ static void exec_criu(struct criu_opts *opts)
 
        char buf[4096], tty_info[32];
        size_t pos;
+
        /* If we are currently in a cgroup /foo/bar, and the container is in a
         * cgroup /lxc/foo, lxcfs will give us an ENOENT if some task in the
         * container has an open fd that points to one of the cgroup files
@@ -541,6 +545,21 @@ static void exec_criu(struct criu_opts *opts)
 
        INFO("execing: %s", buf);
 
+       /* before criu inits its log, it sometimes prints things to stdout/err;
+        * let's be sure we capture that.
+        */
+       if (dup2(opts->pipefd, STDOUT_FILENO) < 0) {
+               SYSERROR("dup2 stdout failed");
+               goto err;
+       }
+
+       if (dup2(opts->pipefd, STDERR_FILENO) < 0) {
+               SYSERROR("dup2 stderr failed");
+               goto err;
+       }
+
+       close(opts->pipefd);
+
 #undef DECLARE_ARG
        execv(argv[0], argv);
 err:
@@ -781,15 +800,6 @@ static void do_restore(struct lxc_container *c, int 
status_pipe, struct migrate_
 
                close(pipes[0]);
                pipes[0] = -1;
-               if (dup2(pipes[1], STDERR_FILENO) < 0) {
-                       SYSERROR("dup2 failed");
-                       goto out_fini_handler;
-               }
-
-               if (dup2(pipes[1], STDOUT_FILENO) < 0) {
-                       SYSERROR("dup2 failed");
-                       goto out_fini_handler;
-               }
 
                if (unshare(CLONE_NEWNS))
                        goto out_fini_handler;
@@ -816,6 +826,7 @@ static void do_restore(struct lxc_container *c, int 
status_pipe, struct migrate_
                        }
                }
 
+               os.pipefd = pipes[1];
                os.action = "restore";
                os.user = opts;
                os.c = c;
@@ -1013,29 +1024,38 @@ static bool do_dump(struct lxc_container *c, char 
*mode, struct migrate_opts *op
 {
        pid_t pid;
        char *criu_version = NULL;
+       int criuout[2];
 
        if (!criu_ok(c, &criu_version))
                return false;
 
-       if (mkdir_p(opts->directory, 0700) < 0)
+       if (pipe(criuout) < 0) {
+               SYSERROR("pipe() failed");
                return false;
+       }
+
+       if (mkdir_p(opts->directory, 0700) < 0)
+               goto fail;
 
        pid = fork();
        if (pid < 0) {
                SYSERROR("fork failed");
-               return false;
+               goto fail;
        }
 
        if (pid == 0) {
                struct criu_opts os;
                struct lxc_handler h;
 
+               close(criuout[0]);
+
                h.name = c->name;
                if (!cgroup_init(&h)) {
                        ERROR("failed to cgroup_init()");
                        exit(1);
                }
 
+               os.pipefd = criuout[1];
                os.action = mode;
                os.user = opts;
                os.c = c;
@@ -1050,27 +1070,51 @@ static bool do_dump(struct lxc_container *c, char 
*mode, struct migrate_opts *op
                exit(1);
        } else {
                int status;
+               ssize_t n;
+               char buf[4096];
+               bool ret;
+
+               close(criuout[1]);
+
                pid_t w = waitpid(pid, &status, 0);
                if (w == -1) {
                        SYSERROR("waitpid");
+                       close(criuout[0]);
                        return false;
                }
 
+               n = read(criuout[0], buf, sizeof(buf));
+               close(criuout[0]);
+               if (n < 0) {
+                       SYSERROR("read");
+                       n = 0;
+               }
+               buf[n] = 0;
+
                if (WIFEXITED(status)) {
                        if (WEXITSTATUS(status)) {
                                ERROR("dump failed with %d\n", 
WEXITSTATUS(status));
-                               return false;
+                               ret = false;
+                       } else {
+                               ret = true;
                        }
-
-                       return true;
                } else if (WIFSIGNALED(status)) {
                        ERROR("dump signaled with %d\n", WTERMSIG(status));
-                       return false;
+                       ret = false;
                } else {
                        ERROR("unknown dump exit %d\n", status);
-                       return false;
+                       ret = false;
                }
+
+               if (!ret)
+                       ERROR("criu output: %s", buf);
+               return ret;
        }
+fail:
+       close(criuout[0]);
+       close(criuout[1]);
+       rmdir(opts->directory);
+       return false;
 }
 
 bool __criu_pre_dump(struct lxc_container *c, struct migrate_opts *opts)

From 9f1f54b0c5fc600cecc43d1608271dbf9b78d20b Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.ander...@canonical.com>
Date: Wed, 2 Nov 2016 15:10:13 +0000
Subject: [PATCH 2/2] c/r: remove extra \ns from logs

The macros put a \n in for us, so let's not put another one in.

Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
---
 src/lxc/criu.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index f49968b..3588b00 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -216,7 +216,7 @@ static void exec_criu(struct criu_opts *opts)
 
        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");
+               ERROR("logfile name too long");
                return;
        }
 
@@ -239,7 +239,7 @@ static void exec_criu(struct criu_opts *opts)
 
        argv[argc++] = on_path("criu", NULL);
        if (!argv[argc-1]) {
-               ERROR("Couldn't find criu binary\n");
+               ERROR("Couldn't find criu binary");
                goto err;
        }
 
@@ -506,7 +506,7 @@ static void exec_criu(struct criu_opts *opts)
                                break;
                        case LXC_NET_MACVLAN:
                                if (!n->link) {
-                                       ERROR("no host interface for macvlan 
%s\n", n->name);
+                                       ERROR("no host interface for macvlan 
%s", n->name);
                                        goto err;
                                }
 
@@ -519,7 +519,7 @@ static void exec_criu(struct criu_opts *opts)
                                break;
                        default:
                                /* we have screened for this earlier... */
-                               ERROR("unexpected network type %d\n", n->type);
+                               ERROR("unexpected network type %d", n->type);
                                goto err;
                        }
 
@@ -670,7 +670,7 @@ static bool criu_version_ok(char **version)
 version_error:
                fclose(f);
                free(tmp);
-               ERROR("must have criu " CRIU_VERSION " or greater to 
checkpoint/restore\n");
+               ERROR("must have criu " CRIU_VERSION " or greater to 
checkpoint/restore");
                return false;
        }
 }
@@ -685,7 +685,7 @@ static bool criu_ok(struct lxc_container *c, char 
**criu_version)
                return false;
 
        if (geteuid()) {
-               ERROR("Must be root to checkpoint\n");
+               ERROR("Must be root to checkpoint");
                return false;
        }
 
@@ -699,7 +699,7 @@ static bool criu_ok(struct lxc_container *c, char 
**criu_version)
                case LXC_NET_MACVLAN:
                        break;
                default:
-                       ERROR("Found un-dumpable network: %s (%s)\n", 
lxc_net_type_to_str(n->type), n->name);
+                       ERROR("Found un-dumpable network: %s (%s)", 
lxc_net_type_to_str(n->type), n->name);
                        return false;
                }
        }
@@ -885,7 +885,7 @@ static void do_restore(struct lxc_container *c, int 
status_pipe, struct migrate_
 
                                buf[n] = 0;
 
-                               ERROR("criu process exited %d, output:\n%s\n", 
WEXITSTATUS(status), buf);
+                               ERROR("criu process exited %d, output:\n%s", 
WEXITSTATUS(status), buf);
                                goto out_fini_handler;
                        } else {
                                ret = snprintf(buf, sizeof(buf), 
"/proc/self/task/%lu/children", (unsigned long)syscall(__NR_gettid));
@@ -896,7 +896,7 @@ static void do_restore(struct lxc_container *c, int 
status_pipe, struct migrate_
 
                                FILE *f = fopen(buf, "r");
                                if (!f) {
-                                       SYSERROR("couldn't read restore's 
children file %s\n", buf);
+                                       SYSERROR("couldn't read restore's 
children file %s", buf);
                                        goto out_fini_handler;
                                }
 
@@ -913,7 +913,7 @@ static void do_restore(struct lxc_container *c, int 
status_pipe, struct migrate_
                                }
                        }
                } else {
-                       ERROR("CRIU was killed with signal %d\n", 
WTERMSIG(status));
+                       ERROR("CRIU was killed with signal %d", 
WTERMSIG(status));
                        goto out_fini_handler;
                }
 
@@ -1093,16 +1093,16 @@ static bool do_dump(struct lxc_container *c, char 
*mode, struct migrate_opts *op
 
                if (WIFEXITED(status)) {
                        if (WEXITSTATUS(status)) {
-                               ERROR("dump failed with %d\n", 
WEXITSTATUS(status));
+                               ERROR("dump failed with %d", 
WEXITSTATUS(status));
                                ret = false;
                        } else {
                                ret = true;
                        }
                } else if (WIFSIGNALED(status)) {
-                       ERROR("dump signaled with %d\n", WTERMSIG(status));
+                       ERROR("dump signaled with %d", WTERMSIG(status));
                        ret = false;
                } else {
-                       ERROR("unknown dump exit %d\n", status);
+                       ERROR("unknown dump exit %d", status);
                        ret = false;
                }
 
@@ -1132,7 +1132,7 @@ bool __criu_dump(struct lxc_container *c, struct 
migrate_opts *opts)
                return false;
 
        if (access(path, F_OK) == 0) {
-               ERROR("please use a fresh directory for the dump directory\n");
+               ERROR("please use a fresh directory for the dump directory");
                return false;
        }
 
@@ -1150,7 +1150,7 @@ bool __criu_restore(struct lxc_container *c, struct 
migrate_opts *opts)
                return false;
 
        if (geteuid()) {
-               ERROR("Must be root to restore\n");
+               ERROR("Must be root to restore");
                return false;
        }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to