[libvirt] [PATCH 5/7] lxc: controller: Improve container error reporting

Cole Robinson crobinso at redhat.com
Thu Jun 2 19:40:24 UTC 2011


Add a handshake with the cloned container process to try and detect
if it fails to start.

Signed-off-by: Cole Robinson <crobinso at redhat.com>
---
 src/lxc/lxc_container.c  |   18 ++++++++++++++----
 src/lxc/lxc_container.h  |    1 +
 src/lxc/lxc_controller.c |   17 +++++++++++++++++
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index ff90842..26b493e 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -90,6 +90,7 @@ struct __lxc_child_argv {
     char **veths;
     int monitor;
     char *ttyPath;
+    int handshakefd;
 };
 
 
@@ -128,7 +129,7 @@ static virCommandPtr lxcContainerBuildInitCmd(virDomainDefPtr vmDef)
  *
  * Returns 0 on success or -1 in case of error
  */
-static int lxcContainerSetStdio(int control, int ttyfd)
+static int lxcContainerSetStdio(int control, int ttyfd, int handshakefd)
 {
     int rc = -1;
     int open_max, i;
@@ -149,7 +150,7 @@ static int lxcContainerSetStdio(int control, int ttyfd)
      * close all FDs before executing the container */
     open_max = sysconf (_SC_OPEN_MAX);
     for (i = 0; i < open_max; i++)
-        if (i != ttyfd && i != control) {
+        if (i != ttyfd && i != control && i != handshakefd) {
             int tmpfd = i;
             VIR_FORCE_CLOSE(tmpfd);
         }
@@ -802,7 +803,13 @@ static int lxcContainerChild( void *data )
     if (lxcContainerDropCapabilities() < 0)
         goto cleanup;
 
-    if (lxcContainerSetStdio(argv->monitor, ttyfd) < 0) {
+    if (lxcContainerSendContinue(argv->handshakefd) < 0) {
+        virReportSystemError(errno, "%s",
+                            _("failed to send continue signal to controller"));
+        goto cleanup;
+    }
+
+    if (lxcContainerSetStdio(argv->monitor, ttyfd, argv->handshakefd) < 0) {
         goto cleanup;
     }
 
@@ -811,6 +818,7 @@ cleanup:
     VIR_FREE(ttyPath);
     VIR_FORCE_CLOSE(ttyfd);
     VIR_FORCE_CLOSE(argv->monitor);
+    VIR_FORCE_CLOSE(argv->handshakefd);
 
     if (ret == 0) {
         /* this function will only return if an error occured */
@@ -870,13 +878,15 @@ int lxcContainerStart(virDomainDefPtr def,
                       unsigned int nveths,
                       char **veths,
                       int control,
+                      int handshakefd,
                       char *ttyPath)
 {
     pid_t pid;
     int flags;
     int stacksize = getpagesize() * 4;
     char *stack, *stacktop;
-    lxc_child_argv_t args = { def, nveths, veths, control, ttyPath };
+    lxc_child_argv_t args = { def, nveths, veths, control, ttyPath,
+                              handshakefd};
 
     /* allocate a stack for the container */
     if (VIR_ALLOC_N(stack, stacksize) < 0) {
diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h
index a3e457e..d6d9b6d 100644
--- a/src/lxc/lxc_container.h
+++ b/src/lxc/lxc_container.h
@@ -52,6 +52,7 @@ int lxcContainerStart(virDomainDefPtr def,
                       unsigned int nveths,
                       char **veths,
                       int control,
+                      int handshakefd,
                       char *ttyPath);
 
 int lxcContainerAvailable(int features);
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 5bf8ee3..c94d0d0 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -617,6 +617,7 @@ lxcControllerRun(virDomainDefPtr def,
 {
     int rc = -1;
     int control[2] = { -1, -1};
+    int containerhandshake[2] = { -1, -1 };
     int containerPty = -1;
     char *containerPtyPath = NULL;
     pid_t container = -1;
@@ -630,6 +631,12 @@ lxcControllerRun(virDomainDefPtr def,
         goto cleanup;
     }
 
+    if (socketpair(PF_UNIX, SOCK_STREAM, 0, containerhandshake) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("socketpair failed"));
+        goto cleanup;
+    }
+
     root = virDomainGetRootFilesystem(def);
 
     if (lxcSetContainerResources(def) < 0)
@@ -725,9 +732,11 @@ lxcControllerRun(virDomainDefPtr def,
                                        nveths,
                                        veths,
                                        control[1],
+                                       containerhandshake[1],
                                        containerPtyPath)) < 0)
         goto cleanup;
     VIR_FORCE_CLOSE(control[1]);
+    VIR_FORCE_CLOSE(containerhandshake[1]);
 
     if (lxcControllerMoveInterfaces(nveths, veths, container) < 0)
         goto cleanup;
@@ -738,6 +747,12 @@ lxcControllerRun(virDomainDefPtr def,
         goto cleanup;
     }
 
+    if (lxcContainerWaitForContinue(containerhandshake[0]) < 0) {
+        virReportSystemError(errno, "%s",
+                             _("error receiving signal from container"));
+        goto cleanup;
+    }
+
     /* Now the container is running, there's no need for us to keep
        any elevated capabilities */
     if (lxcControllerClearCapabilities() < 0)
@@ -760,6 +775,8 @@ cleanup:
     VIR_FREE(containerPtyPath);
     VIR_FORCE_CLOSE(containerPty);
     VIR_FORCE_CLOSE(handshakefd);
+    VIR_FORCE_CLOSE(containerhandshake[0]);
+    VIR_FORCE_CLOSE(containerhandshake[1]);
 
     if (container > 1) {
         int status;
-- 
1.7.4.4




More information about the libvir-list mailing list