The problem is that the fd table is shared between threads and if a thread
forks() while another thread has an open fd to the monitor, the duped fd
in the fork()ed child will not get closed, thus causing monitord to stay
around since it thinks it still has a client. This only happened when
calling lxcapi_start() in the daemonized case since that is the only time
we try to get the status from the monitor.

Signed-off-by: Dwight Engen <dwight.en...@oracle.com>
---
 src/lxc/lxccontainer.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 04a9208..bac94c2 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -18,6 +18,7 @@
  */
 
 #define _GNU_SOURCE
+#include <pthread.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -37,6 +38,8 @@
 #include <lxc/utils.h>
 #include <lxc/monitor.h>
 
+static pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 /* Define unshare() if missing from the C library */
 /* this is also in attach.c and lxccontainer.c: commonize it in utils.c */
 #ifndef HAVE_UNSHARE
@@ -58,6 +61,7 @@ lxc_log_define(lxc_container, lxc);
 /* LOCKING
  * c->privlock protects the struct lxc_container from multiple threads.
  * c->slock protects the on-disk container data
+ * thread_mutex protects process data (ex: fd table) from multiple threads
  * NOTHING mutexes two independent programs with their own struct
  * lxc_container for the same c->name, between API calls.  For instance,
  * c->config_read(); c->start();  Between those calls, data on disk
@@ -391,13 +395,24 @@ static bool lxcapi_start(struct lxc_container *c, int 
useinit, char * const argv
                if (!lxc_container_get(c))
                        return false;
                lxc_monitord_spawn(c->config_path);
+
+               ret = pthread_mutex_lock(&thread_mutex);
+               if (ret != 0) {
+                       ERROR("pthread_mutex_lock returned:%d %s", ret, 
strerror(ret));
+                       return false;
+               }
                pid_t pid = fork();
                if (pid < 0) {
                        lxc_container_put(c);
+                       pthread_mutex_unlock(&thread_mutex);
                        return false;
                }
-               if (pid != 0)
-                       return wait_on_daemonized_start(c);
+               if (pid != 0) {
+                       ret = wait_on_daemonized_start(c);
+                       pthread_mutex_unlock(&thread_mutex);
+                       return ret;
+               }
+               pthread_mutex_unlock(&thread_mutex);
                /* second fork to be reparented by init */
                pid = fork();
                if (pid < 0) {
-- 
1.8.1.4


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and 
their applications. This 200-page book is written by three acclaimed 
leaders in the field. The early access version is available now. 
Download your free book today! http://p.sf.net/sfu/neotech_d2d_may
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to