Quoting Qiang Huang (h.huangqi...@huawei.com):
> 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: St??phane Graber <stgra...@ubuntu.com>
> Signed-off-by: Qiang Huang <h.huangqi...@huawei.com>

(For a follow-on patch it would be nice if the large hunk at
the bottom were separated out into a helper function, so that
right above reboot: just was

        if (setup_pidfile(c->pidfile()))
                goto out;
)

Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com>

> ---
>  src/lxc/lxc_start.c    | 19 -------------------
>  src/lxc/lxccontainer.c | 30 +++++++++++++++++++++++++++++-
>  2 files changed, 29 insertions(+), 20 deletions(-)
> 
> diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
> index fd2dc6e..4b6b1f7 100644
> --- a/src/lxc/lxc_start.c
> +++ b/src/lxc/lxc_start.c
> @@ -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;
>  }
>  
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 579c50c..c949526 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -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,13 @@ 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 +636,28 @@ static bool lxcapi_start(struct lxc_container *c, int 
> useinit, char * const argv
>               }
>       }
>  
> +     /* We need to write PID file after daeminize, so we alway
> +      * 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);
> -- 
> 1.8.3
> 
> 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to