From f33e43c2353cc10065b8a5f9965d5a57cfe8991f Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 16 Nov 2012 09:11:23 +0000 Subject: [PATCH] Use virNetServerRun instead of custom main loop The LXC controller code currently directly invokes the libvirt main loop code. The problem is that this misses the cleanup of virNetServerClient connections that virNetServerRun takes care of. The result is that when libvirtd is stopped, the libvirt_lxc controller process gets stuck in a I/O loop. When libvirtd is then started again, it fails to connect to the controller and thus kills off the entire domain. Signed-off-by: Daniel P. Berrange --- src/lxc/lxc_controller.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 4746897def..aec2d4ccd3 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -97,6 +97,8 @@ struct _virLXCControllerConsole { char fromHostBuf[1024]; size_t fromContLen; char fromContBuf[1024]; + + virNetServerPtr server; }; typedef struct _virLXCController virLXCController; @@ -278,6 +280,7 @@ static int virLXCControllerAddConsole(virLXCControllerPtr ctrl, virReportOOMError(); return -1; } + ctrl->consoles[ctrl->nconsoles-1].server = ctrl->server; ctrl->consoles[ctrl->nconsoles-1].hostFd = hostFd; ctrl->consoles[ctrl->nconsoles-1].hostWatch = -1; @@ -663,12 +666,11 @@ static int lxcControllerClearCapabilities(void) return 0; } -static bool quit = false; static bool wantReboot = false; static virMutex lock; -static void virLXCControllerSignalChildIO(virNetServerPtr server ATTRIBUTE_UNUSED, +static void virLXCControllerSignalChildIO(virNetServerPtr server, siginfo_t *info ATTRIBUTE_UNUSED, void *opaque) { @@ -678,8 +680,8 @@ static void virLXCControllerSignalChildIO(virNetServerPtr server ATTRIBUTE_UNUSE ret = waitpid(-1, &status, WNOHANG); if (ret == ctrl->initpid) { + virNetServerQuit(server); virMutexLock(&lock); - quit = true; if (WIFSIGNALED(status) && WTERMSIG(status) == SIGHUP) wantReboot = true; @@ -731,7 +733,7 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol VIR_DEBUG(":fail"); virReportSystemError(errno, "%s", _("Unable to add epoll fd")); - quit = true; + virNetServerQuit(console->server); goto cleanup; } console->hostEpoll = events; @@ -742,8 +744,8 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol if (epoll_ctl(console->epollFd, EPOLL_CTL_DEL, console->hostFd, NULL) < 0) { virReportSystemError(errno, "%s", _("Unable to remove epoll fd")); - VIR_DEBUG(":fail"); - quit = true; + VIR_DEBUG(":fail"); + virNetServerQuit(console->server); goto cleanup; } console->hostEpoll = 0; @@ -768,7 +770,7 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol virReportSystemError(errno, "%s", _("Unable to add epoll fd")); VIR_DEBUG(":fail"); - quit = true; + virNetServerQuit(console->server); goto cleanup; } console->contEpoll = events; @@ -779,8 +781,8 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol if (epoll_ctl(console->epollFd, EPOLL_CTL_DEL, console->contFd, NULL) < 0) { virReportSystemError(errno, "%s", _("Unable to remove epoll fd")); - VIR_DEBUG(":fail"); - quit = true; + VIR_DEBUG(":fail"); + virNetServerQuit(console->server); goto cleanup; } console->contEpoll = 0; @@ -809,7 +811,7 @@ static void virLXCControllerConsoleEPoll(int watch, int fd, int events, void *op continue; virReportSystemError(errno, "%s", _("Unable to wait on epoll")); - quit = true; + virNetServerQuit(console->server); goto cleanup; } @@ -926,7 +928,7 @@ error: virEventRemoveHandle(console->contWatch); virEventRemoveHandle(console->hostWatch); console->contWatch = console->hostWatch = -1; - quit = true; + virNetServerQuit(console->server); virMutexUnlock(&lock); } @@ -995,14 +997,7 @@ static int virLXCControllerMain(virLXCControllerPtr ctrl) } } - virMutexLock(&lock); - while (!quit) { - virMutexUnlock(&lock); - if (virEventRunDefaultImpl() < 0) - goto cleanup; - virMutexLock(&lock); - } - virMutexUnlock(&lock); + virNetServerRun(ctrl->server); err = virGetLastError(); if (!err || err->code == VIR_ERR_OK)