We can also narrow the scope of this, since we only need it in the process that
is actually going to use it.

Reported-by: Serge Hallyn <serge.hal...@ubuntu.com>
Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
---
 src/lxc/lxccontainer.c | 43 ++++++++++++++++++++++++++-----------------
 src/lxc/start.c        |  2 +-
 src/lxc/start.h        |  1 +
 3 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 6d45c8e..cd0f7df 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -3843,12 +3843,6 @@ static bool lxcapi_restore(struct lxc_container *c, char 
*directory, bool verbos
        if (!tmpnam(pidfile))
                return false;
 
-       struct lxc_handler *handler;
-
-       handler = lxc_init(c->name, c->lxc_conf, c->config_path);
-       if (!handler)
-               return false;
-
        pid = fork();
        if (pid < 0)
                return false;
@@ -3890,6 +3884,9 @@ static bool lxcapi_restore(struct lxc_container *c, char 
*directory, bool verbos
                exit(1);
        } else {
                int status;
+               struct lxc_handler *handler;
+               bool error = false;
+
                pid_t w = waitpid(pid, &status, 0);
 
                if (w == -1) {
@@ -3897,29 +3894,37 @@ static bool lxcapi_restore(struct lxc_container *c, 
char *directory, bool verbos
                        return false;
                }
 
+               handler = lxc_init(c->name, c->lxc_conf, c->config_path);
+               if (!handler)
+                       return false;
+
                if (WIFEXITED(status)) {
                        if (WEXITSTATUS(status)) {
-                               return false;
+                               error = true;
+                               goto out_fini_handler;
                        }
                        else {
                                int netnr = 0, ret;
-                               bool error = false;
                                FILE *f = fopen(pidfile, "r");
                                if (!f) {
+                                       error = true;
                                        perror("reading pidfile");
                                        ERROR("couldn't read restore's init 
pidfile %s\n", pidfile);
-                                       return false;
+                                       goto out_fini_handler;
                                }
 
                                ret = fscanf(f, "%d", (int*) &handler->pid);
                                fclose(f);
                                if (ret != 1) {
+                                       error = true;
                                        ERROR("reading restore pid failed");
-                                       return false;
+                                       goto out_fini_handler;
                                }
 
-                               if (container_mem_lock(c))
-                                       return false;
+                               if (container_mem_lock(c)) {
+                                       error = true;
+                                       goto out_fini_handler;
+                               }
 
                                lxc_list_for_each(it, &c->lxc_conf->network) {
                                        char eth[128], veth[128];
@@ -3943,10 +3948,12 @@ static bool lxcapi_restore(struct lxc_container *c, 
char *directory, bool verbos
 out_unlock:
                                container_mem_unlock(c);
                                if (error)
-                                       return false;
+                                       goto out_fini_handler;
 
-                               if (lxc_set_state(c->name, handler, RUNNING))
-                                       return false;
+                               if (lxc_set_state(c->name, handler, RUNNING)) {
+                                       error = true;
+                                       goto out_fini_handler;
+                               }
                        }
                }
 
@@ -3954,9 +3961,11 @@ out_unlock:
                        lxc_abort(c->name, handler);
                        return false;
                }
-       }
 
-       return true;
+out_fini_handler:
+               lxc_fini(c->name, handler);
+               return !error;
+       }
 }
 
 static int lxcapi_attach_run_waitl(struct lxc_container *c, 
lxc_attach_options_t *options, const char *program, const char *arg, ...)
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 98849e1..f931bfa 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -460,7 +460,7 @@ out_free:
        return NULL;
 }
 
-static void lxc_fini(const char *name, struct lxc_handler *handler)
+void lxc_fini(const char *name, struct lxc_handler *handler)
 {
        /* The STOPPING state is there for future cleanup code
         * which can take awhile
diff --git a/src/lxc/start.h b/src/lxc/start.h
index 8af0a06..7c75b16 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -79,6 +79,7 @@ extern int lxc_poll(const char *name, struct lxc_handler 
*handler);
 extern int lxc_set_state(const char *name, struct lxc_handler *handler, 
lxc_state_t state);
 extern void lxc_abort(const char *name, struct lxc_handler *handler);
 extern struct lxc_handler *lxc_init(const char *name, struct lxc_conf *, const 
char *);
+extern void lxc_fini(const char *name, struct lxc_handler *handler);
 
 extern int lxc_check_inherited(struct lxc_conf *conf, int fd_to_ignore);
 int __lxc_start(const char *, struct lxc_conf *, struct lxc_operations *,
-- 
1.9.1

_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to