The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8254
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Fixes 8253
From 1f8d31f61d7f375b5fd8029d4d79d4ce6da8292e Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 15 Dec 2020 12:41:08 +0000 Subject: [PATCH 1/2] lxd/instance/drivers/qmp/monitor: Handle closed event channel from qmp package in run Fixes #8253 Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/instance/drivers/qmp/monitor.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lxd/instance/drivers/qmp/monitor.go b/lxd/instance/drivers/qmp/monitor.go index 20c6dd4d01..ea564e6080 100644 --- a/lxd/instance/drivers/qmp/monitor.go +++ b/lxd/instance/drivers/qmp/monitor.go @@ -12,6 +12,7 @@ import ( "github.com/digitalocean/go-qemu/qmp" "github.com/lxc/lxd/shared" + "github.com/lxc/lxd/shared/logger" ) var monitors = map[string]*Monitor{} @@ -126,13 +127,22 @@ func (m *Monitor) run() error { select { case <-m.chDisconnect: return - case e := <-chEvents: - if e.Event == "" { - continue + case e, more := <-chEvents: + // Deliver non-empty events to the event handler. + if m.eventHandler != nil && e.Event != "" { + go m.eventHandler(e.Event, e.Data) } - if m.eventHandler != nil { - go m.eventHandler(e.Event, e.Data) + // Event channel is closed, lets disconnect. + if !more { + m.Disconnect() + return + } + + if e.Event == "" { + logger.Warnf("Unexpected empty event received from qmp event channel") + time.Sleep(time.Second) // Don't busy wait if we receive a lot of these. + continue } // Check if the ringbuffer was updated (non-blocking). From 2ab69cfc1fa49211b3fb3de0ed9ed29ac78c6e0a Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 15 Dec 2020 12:41:56 +0000 Subject: [PATCH 2/2] lxd/instance/drivers/driver/qemu: Logs when instance is stopped in getMonitorEventHandler And removes some references to the instance in the function returned from getMonitorEventHandler so they are not kept in memory. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/instance/drivers/driver_qemu.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index d01f47a3f7..b6168a3f6e 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -343,9 +343,12 @@ func (d *qemu) getStoragePool() (storagePools.Pool, error) { } func (d *qemu) getMonitorEventHandler() func(event string, data map[string]interface{}) { + // Create local variables from device properties we need so as not to keep references to device around + // after we have returned the callback function. projectName := d.Project() instanceName := d.Name() state := d.state + logger := d.logger return func(event string, data map[string]interface{}) { if !shared.StringInSlice(event, []string{"SHUTDOWN"}) { @@ -354,11 +357,13 @@ func (d *qemu) getMonitorEventHandler() func(event string, data map[string]inter inst, err := instance.LoadByProjectAndName(state, projectName, instanceName) if err != nil { - d.logger.Error("Failed to load instance", log.Ctx{"err": err}) + logger.Error("Failed to load instance", log.Ctx{"err": err}) return } if event == "SHUTDOWN" { + logger.Debug("Instance stopped") + target := "stop" entry, ok := data["reason"] if ok && entry == "guest-reset" { @@ -367,7 +372,7 @@ func (d *qemu) getMonitorEventHandler() func(event string, data map[string]inter err = inst.(*qemu).onStop(target) if err != nil { - d.logger.Error("Failed to cleanly stop instance", log.Ctx{"err": err}) + logger.Error("Failed to cleanly stop instance", log.Ctx{"err": err}) return } }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel