From: Qiang Huang Date: Wed, 22 Jan 2014 04:11:38 +0000 (+0800) Subject: daemon: fix the wrong pid in daemon model X-Git-Tag: lxc-2.1.1~1958 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=6eaac3034e8c19eab2b91e201628c4ab5a85a085;p=mirror_lxc.git daemon: fix the wrong pid in daemon model 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 Signed-off-by: Qiang Huang Acked-by: Serge E. Hallyn --- diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index fd2dc6ebd..4b6b1f75b 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 f1c98a4b6..28de4550b 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,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);