mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Fix reboot command for LXC containers
The virNetDaemonQuit(dmn) command in virLXCControllerSignalChildIO triggers an early close of all clients of lxc_controller. Here, libvirtd itself is a client of this controller, and the client connection is used to notify libvirtd if a reboot of the container is required. However, the client connection was closed before such a status could be sent to libvirtd. To fix this bug, we will immediately send the reboot or shutdown status of the container to libvirtd, and only after client disconnect will we trigger virNetDaemonQuit. Fixes: https://gitlab.com/libvirt/libvirt/-/issues/237 Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=991773 Signed-off-by: Joachim Falk <joachim.falk@gmx.de> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
a7a03324d8
commit
93c47e2c39
@ -894,8 +894,10 @@ static void virLXCControllerClientCloseHook(virNetServerClient *client)
|
||||
virLXCController *ctrl = virNetServerClientGetPrivateData(client);
|
||||
|
||||
VIR_DEBUG("Client %p has closed", client);
|
||||
if (ctrl->client == client)
|
||||
if (ctrl->client == client) {
|
||||
ctrl->client = NULL;
|
||||
VIR_DEBUG("Client has gone away");
|
||||
}
|
||||
if (ctrl->inShutdown) {
|
||||
VIR_DEBUG("Arm timer to quit event loop");
|
||||
virEventUpdateTimeout(ctrl->timerShutdown, 0);
|
||||
@ -1006,8 +1008,11 @@ static int lxcControllerClearCapabilities(void)
|
||||
static bool wantReboot;
|
||||
static virMutex lock = VIR_MUTEX_INITIALIZER;
|
||||
|
||||
static int
|
||||
virLXCControllerEventSendExit(virLXCController *ctrl,
|
||||
int exitstatus);
|
||||
|
||||
static void virLXCControllerSignalChildIO(virNetDaemon *dmn,
|
||||
static void virLXCControllerSignalChildIO(virNetDaemon *dmn G_GNUC_UNUSED,
|
||||
siginfo_t *info G_GNUC_UNUSED,
|
||||
void *opaque)
|
||||
{
|
||||
@ -1018,7 +1023,6 @@ static void virLXCControllerSignalChildIO(virNetDaemon *dmn,
|
||||
ret = waitpid(-1, &status, WNOHANG);
|
||||
VIR_DEBUG("Got sig child %d vs %lld", ret, (long long)ctrl->initpid);
|
||||
if (ret == ctrl->initpid) {
|
||||
virNetDaemonQuit(dmn);
|
||||
virMutexLock(&lock);
|
||||
if (WIFSIGNALED(status) &&
|
||||
WTERMSIG(status) == SIGHUP) {
|
||||
@ -1026,6 +1030,7 @@ static void virLXCControllerSignalChildIO(virNetDaemon *dmn,
|
||||
wantReboot = true;
|
||||
}
|
||||
virMutexUnlock(&lock);
|
||||
virLXCControllerEventSendExit(ctrl, wantReboot ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2276,9 +2281,10 @@ virLXCControllerEventSendExit(virLXCController *ctrl,
|
||||
VIR_DEBUG("Waiting for client to complete dispatch");
|
||||
ctrl->inShutdown = true;
|
||||
virNetServerClientDelayedClose(ctrl->client);
|
||||
virNetDaemonRun(ctrl->daemon);
|
||||
} else {
|
||||
VIR_DEBUG("Arm timer to quit event loop");
|
||||
virEventUpdateTimeout(ctrl->timerShutdown, 0);
|
||||
}
|
||||
VIR_DEBUG("Client has gone away");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2430,8 +2436,6 @@ virLXCControllerRun(virLXCController *ctrl)
|
||||
|
||||
rc = virLXCControllerMain(ctrl);
|
||||
|
||||
virLXCControllerEventSendExit(ctrl, rc);
|
||||
|
||||
cleanup:
|
||||
VIR_FORCE_CLOSE(control[0]);
|
||||
VIR_FORCE_CLOSE(control[1]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user