diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 8f0ece98cd..066e013ed4 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -348,7 +348,7 @@ static int virLXCControllerConsoleSetNonblocking(virLXCControllerConsole *consol } -static int virLXCControllerDaemonHandshake(virLXCController *ctrl) +static int virLXCControllerDaemonHandshakeCont(virLXCController *ctrl) { if (lxcContainerSendContinue(ctrl->handshakeFds[1]) < 0) { virReportSystemError(errno, "%s", @@ -358,6 +358,15 @@ static int virLXCControllerDaemonHandshake(virLXCController *ctrl) return 0; } +static int virLXCControllerDaemonHandshakeWait(virLXCController *ctrl) +{ + if (lxcContainerWaitForContinue(ctrl->handshakeFds[0]) < 0) { + virReportSystemError(errno, "%s", + _("error waiting for continue signal from daemon")); + return -1; + } + return 0; +} static int virLXCControllerValidateNICs(virLXCController *ctrl) { @@ -2372,6 +2381,11 @@ virLXCControllerRun(virLXCController *ctrl) if (virLXCControllerSetupCgroupLimits(ctrl) < 0) goto cleanup; + /* Allow daemon to detect CGroups. */ + if (virLXCControllerDaemonHandshakeCont(ctrl) < 0 || + virLXCControllerDaemonHandshakeWait(ctrl) < 0) + goto cleanup; + if (virLXCControllerSetupUserns(ctrl) < 0) goto cleanup; @@ -2401,7 +2415,8 @@ virLXCControllerRun(virLXCController *ctrl) if (virLXCControllerConsoleSetNonblocking(&(ctrl->consoles[i])) < 0) goto cleanup; - if (virLXCControllerDaemonHandshake(ctrl) < 0) + /* Allow daemon to connect to the monitor. */ + if (virLXCControllerDaemonHandshakeCont(ctrl) < 0) goto cleanup; /* and preemptively close handshakeFds */ diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index dd51c778a4..cfa009f14e 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1473,6 +1473,7 @@ int virLXCProcessStart(virConnectPtr conn, if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) driver->inhibitCallback(true, driver->inhibitOpaque); + /* The first synchronization point is when the controller creates CGroups. */ if (lxcContainerWaitForContinue(handshakefds[0]) < 0) { char out[1024]; @@ -1504,6 +1505,25 @@ int virLXCProcessStart(virConnectPtr conn, goto cleanup; } + if (lxcContainerSendContinue(handshakefds[3]) < 0) { + virReportSystemError(errno, "%s", + _("Failed to send continue signal to controller")); + goto cleanup; + } + + /* The second synchronization point is when the controller finished + * creating the container. */ + if (lxcContainerWaitForContinue(handshakefds[0]) < 0) { + char out[1024]; + + if (!(virLXCProcessReadLogOutput(vm, logfile, pos, out, 1024) < 0)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("guest failed to start: %s"), out); + } + + goto cleanup; + } + /* And we can get the first monitor connection now too */ if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm))) { /* Intentionally overwrite the real monitor error message,