]> git.proxmox.com Git - mirror_lxc.git/commitdiff
daemon: fix the wrong pid in daemon model
authorQiang Huang <h.huangqiang@huawei.com>
Wed, 22 Jan 2014 04:11:38 +0000 (12:11 +0800)
committerStéphane Graber <stgraber@ubuntu.com>
Thu, 23 Jan 2014 00:53:22 +0000 (19:53 -0500)
When you start a container in daemon model, you have at least
3 processes:
 1. The command the user start (lxc-start -d)
 2. The backgrounded fork of that command after start() is done
 3. The container init process

In PID file, we need (2), but currently we are writing (1),
this is wrong because (1) exits as soon as the container is
started, it's complately useless.

So we write pid after daemonize, so that we'll always write
the right pid to PID file.

Reported-by: Stephane Graber <stgraber@ubuntu.com>
Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
src/lxc/lxc_start.c
src/lxc/lxccontainer.c

index fd2dc6ebdb99a7204d6bcffffd531a9ee7820381..4b6b1f75b14bdac94970ef14d444a6e614b72242 100644 (file)
@@ -211,7 +211,6 @@ int main(int argc, char *argv[])
                "/sbin/init",
                '\0',
        };
-       FILE *pid_fp = NULL;
        struct lxc_container *c;
 
        lxc_list_init(&defines);
@@ -306,13 +305,6 @@ int main(int argc, char *argv[])
                        ERROR("failed to ensure pidfile '%s'", my_args.pidfile);
                        goto out;
                }
-
-               pid_fp = fopen(my_args.pidfile, "w");
-               if (pid_fp == NULL) {
-                       SYSERROR("failed to create pidfile '%s' for '%s'",
-                                my_args.pidfile, my_args.name);
-                       goto out;
-               }
        }
 
        int i;
@@ -334,23 +326,12 @@ int main(int argc, char *argv[])
                c->want_daemonize(c, false);
        }
 
-       if (pid_fp != NULL) {
-               if (fprintf(pid_fp, "%d\n", getpid()) < 0) {
-                       SYSERROR("failed to write '%s'", my_args.pidfile);
-                       goto out;
-               }
-               fclose(pid_fp);
-               pid_fp = NULL;
-       }
-
        if (my_args.close_all_fds)
                c->want_close_all_fds(c, true);
 
        err = c->start(c, 0, args) ? 0 : -1;
 out:
        lxc_container_put(c);
-       if (pid_fp)
-               fclose(pid_fp);
        return err;
 }
 
index f1c98a4b64a58913ccf676e9180f57378ca18f21..28de4550bc2d17f029e86a95db80f352e60aff29 100644 (file)
@@ -545,6 +545,7 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
        int ret;
        struct lxc_conf *conf;
        bool daemonize = false;
+       FILE *pid_fp = NULL;
        char *default_args[] = {
                "/sbin/init",
                '\0',
@@ -600,8 +601,14 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
                pid_t pid = fork();
                if (pid < 0)
                        return false;
-               if (pid != 0)
+
+               if (pid != 0) {
+                       /* Set to NULL because we don't want father unlink
+                        * the PID file, child will do the free and unlink.
+                        */
+                       c->pidfile = NULL;
                        return wait_on_daemonized_start(c, pid);
+               }
 
                /* second fork to be reparented by init */
                pid = fork();
@@ -630,6 +637,28 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv
                }
        }
 
+       /* We need to write PID file after daeminize, so we always
+        * write the right PID.
+        */
+       if (c->pidfile) {
+               pid_fp = fopen(c->pidfile, "w");
+               if (pid_fp == NULL) {
+                       SYSERROR("Failed to create pidfile '%s' for '%s'",
+                                c->pidfile, c->name);
+                       return false;
+               }
+
+               if (fprintf(pid_fp, "%d\n", getpid()) < 0) {
+                       SYSERROR("Failed to write '%s'", c->pidfile);
+                       fclose(pid_fp);
+                       pid_fp = NULL;
+                       return false;
+               }
+
+               fclose(pid_fp);
+               pid_fp = NULL;
+       }
+
 reboot:
        conf->reboot = 0;
        ret = lxc_start(c->name, argv, conf, c->config_path);