[lxc-devel] [lxd/master] vm: console and exec fixes

brauner on Github lxc-bot at linuxcontainers.org
Thu Mar 12 11:03:51 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200312/8dbf436e/attachment-0001.bin>
-------------- next part --------------
From 146e6a80542fc4623af13f47126f036d7a940e7a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 12 Mar 2020 11:33:05 +0100
Subject: [PATCH 1/2] driver_qemu: delete vm id from vmConsole

Otherwise I'd expect the map to be growing.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/instance/drivers/driver_qemu.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 3c83c55619..6c937be053 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -3161,7 +3161,7 @@ func (vm *qemu) Console() (*os.File, chan error, error) {
 		<-chDisconnect
 
 		vmConsoleLock.Lock()
-		vmConsole[vm.id] = false
+		delete(vmConsole, vm.id)
 		vmConsoleLock.Unlock()
 	}()
 

From a95bf4d5671dd91bd74280f1d0a60a4bb76f5a27 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 12 Mar 2020 11:53:26 +0100
Subject: [PATCH 2/2] ExecReaderToChannel: Prevent endless loops

Well, there's a bug in ExecReaderToChannel() where we can end up in an endless
loop when the error we get from poll() is non-transient. Realistically, when
poll() returns -1 it means something is so wrong we can't recover from it and a
next call to poll() won't be any better. If we get POLLNVAL that's pretty
obvious that the fd has been closed and so this is guaranteed to end up in an
endless loop. If we get POLLERR we could maybe maybe argue that there's
something we can do but realistically, not really. So exit in all those cases.

(Note, that we've never hit this problem before with containers. It suddenly
 started appearing when the lxd-agent became a thing.)

Closes #6870.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/util_linux_cgo.go | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/shared/util_linux_cgo.go b/shared/util_linux_cgo.go
index 1914ff1002..45f7c03e22 100644
--- a/shared/util_linux_cgo.go
+++ b/shared/util_linux_cgo.go
@@ -325,16 +325,24 @@ func ExecReaderToChannel(r io.Reader, bufferSize int, exited <-chan bool, fd int
 		ret, revents, err := GetPollRevents(fd, 0, (POLLIN | POLLPRI | POLLERR | POLLHUP | POLLRDHUP | POLLNVAL))
 		if ret < 0 {
 			logger.Errorf("Failed to poll(POLLIN | POLLPRI | POLLHUP | POLLRDHUP) on file descriptor: %s.", err)
+			// Something went wrong so let's exited otherwise we
+			// end up in an endless loop.
+			once.Do(closeChannel)
 		} else if ret > 0 {
 			if (revents & POLLERR) > 0 {
 				logger.Warnf("Detected poll(POLLERR) event.")
+				// Read end has likely been closed so again,
+				// avoid an endless loop.
+				once.Do(closeChannel)
 			} else if (revents & POLLNVAL) > 0 {
 				logger.Warnf("Detected poll(POLLNVAL) event.")
+				// Well, someone closed the fd havent they? So
+				// let's go home.
+				once.Do(closeChannel)
 			}
 		} else if ret == 0 {
 			logger.Debugf("No data in stdout: exiting.")
 			once.Do(closeChannel)
-			return
 		}
 	}()
 


More information about the lxc-devel mailing list