Add a handshake with the cloned container process to try and detect
if it fails to start.
Signed-off-by: Cole Robinson <crobinso(a)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