[lxc-devel] [lxd/master] Instance: Fix deadlock in instance operationlock package

tomponline on Github lxc-bot at linuxcontainers.org
Tue Dec 15 16:27:40 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 446 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20201215/e3cf3a4b/attachment.bin>
-------------- next part --------------
From 678cfbde4804df2c7d50f73b66c03b0be4491fb6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 15 Dec 2020 16:22:56 +0000
Subject: [PATCH 1/3] lxd/instance/operationlock: Fixes deadlock caused by call
 to Reset in Create

Both try to aquire lock and so can deadlock each other.

By pushing to the reset channel directly from Create we avoid the deadlock.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/instance/operationlock/operationlock.go | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lxd/instance/operationlock/operationlock.go b/lxd/instance/operationlock/operationlock.go
index faab4c5982..a3bbd74e04 100644
--- a/lxd/instance/operationlock/operationlock.go
+++ b/lxd/instance/operationlock/operationlock.go
@@ -37,7 +37,8 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance
 	op := instanceOperations[instanceID]
 	if op != nil {
 		if op.reusable && reuse {
-			op.Reset()
+			// Reset operation timeout without releasing lock or deadlocking using Reset() function.
+			op.chanReset <- true
 			return op, nil
 		}
 

From b8d7f56488219f0dfd3cb0e6076ea9b3b506863e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 15 Dec 2020 16:23:45 +0000
Subject: [PATCH 2/3] lxd/instance/operationlock: Store operation in
 instanceOperations before calling go routine

As the go routine can call functions on the operation (such as op.Done) which rely on the instanceOperations map being populated it seems appropriate to ensure it has been populated with the new operation before starting the go routine.

Even though the only current use of the operation inside the go routine is after 30s.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/instance/operationlock/operationlock.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/instance/operationlock/operationlock.go b/lxd/instance/operationlock/operationlock.go
index a3bbd74e04..b7e6504961 100644
--- a/lxd/instance/operationlock/operationlock.go
+++ b/lxd/instance/operationlock/operationlock.go
@@ -52,6 +52,8 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance
 	op.chanDone = make(chan error, 0)
 	op.chanReset = make(chan bool, 0)
 
+	instanceOperations[instanceID] = op
+
 	go func(op *InstanceOperation) {
 		for {
 			select {
@@ -64,8 +66,6 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance
 		}
 	}(op)
 
-	instanceOperations[instanceID] = op
-
 	return op, nil
 }
 

From 18ace0e0607b0b0f15bf9dc28c6355f57bb66fde Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 15 Dec 2020 16:25:13 +0000
Subject: [PATCH 3/3] lxd/instance/operationlock: Exit go routine started in
 Create when the operation is done

Otherwise I have observed that go routines can hang around for up to 30s after operation is completed.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/instance/operationlock/operationlock.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lxd/instance/operationlock/operationlock.go b/lxd/instance/operationlock/operationlock.go
index b7e6504961..49dab48b1a 100644
--- a/lxd/instance/operationlock/operationlock.go
+++ b/lxd/instance/operationlock/operationlock.go
@@ -57,6 +57,8 @@ func Create(instanceID int, action string, reusable bool, reuse bool) (*Instance
 	go func(op *InstanceOperation) {
 		for {
 			select {
+			case <-op.chanDone:
+				return
 			case <-op.chanReset:
 				continue
 			case <-time.After(time.Second * 30):


More information about the lxc-devel mailing list