The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7736
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) === Allows the `basic_usage` test to complete successfully with the Go race detector enabled.
From 35640baf87ad7ef9c566b939a6e03798c2f00c27 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 6 Aug 2020 17:10:54 +0100 Subject: [PATCH 1/4] Makefile: Correctly builds lxd-p2c and lxd-agent in debug and nocache targets Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 18cfb4eff9..c4f605a6b2 100644 --- a/Makefile +++ b/Makefile @@ -134,6 +134,8 @@ endif go get -t -v -d ./... CC=$(CC) go install -v -tags "$(TAG_SQLITE3) logdebug" $(DEBUG) ./... + CGO_ENABLED=0 go install -v -tags "netgo,logdebug" ./lxd-p2c + CGO_ENABLED=0 go install -v -tags "agent,netgo,logdebug" ./lxd-agent @echo "LXD built successfully" .PHONY: nocache @@ -145,6 +147,8 @@ endif go get -t -v -d ./... CC=$(CC) go install -a -v -tags "$(TAG_SQLITE3)" $(DEBUG) ./... + CGO_ENABLED=0 go install -a -v -tags netgo ./lxd-p2c + CGO_ENABLED=0 go install -a -v -tags agent,netgo ./lxd-agent @echo "LXD built successfully" race: From dccd1afa7c89c173d610afcc94375cb3a57788a0 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 6 Aug 2020 17:11:20 +0100 Subject: [PATCH 2/4] client/operations: Race fix Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- client/operations.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/operations.go b/client/operations.go index b0bdf91be7..e99145098f 100644 --- a/client/operations.go +++ b/client/operations.go @@ -106,8 +106,9 @@ func (op *operation) Wait() error { // Check if not done already if op.StatusCode.IsFinal() { if op.Err != "" { + err := op.Err op.handlerLock.Unlock() - return fmt.Errorf(op.Err) + return fmt.Errorf(err) } op.handlerLock.Unlock() From 1deea91f2518789f6d000dd377f4a4588d4de257 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 6 Aug 2020 17:11:52 +0100 Subject: [PATCH 3/4] lxd/db: Adds mutex to fix races Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/db/db.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lxd/db/db.go b/lxd/db/db.go index e1ef3a1f68..c0519e8e31 100644 --- a/lxd/db/db.go +++ b/lxd/db/db.go @@ -131,11 +131,12 @@ func (n *Node) Begin() (*sql.Tx, error) { // Cluster mediates access to LXD's data stored in the cluster dqlite database. type Cluster struct { - db *sql.DB // Handle to the cluster dqlite database, gated behind gRPC SQL. - nodeID int64 // Node ID of this LXD instance. - mu sync.RWMutex - stmts map[int]*sql.Stmt // Prepared statements by code. - closing bool // True when daemon is shutting down, prevents retries + db *sql.DB // Handle to the cluster dqlite database, gated behind gRPC SQL. + nodeID int64 // Node ID of this LXD instance. + mu sync.RWMutex + stmts map[int]*sql.Stmt // Prepared statements by code. + closing bool // True when daemon is shutting down, prevents retries + clusterMu sync.Mutex } // OpenCluster creates a new Cluster object for interacting with the dqlite @@ -327,7 +328,9 @@ func ForLocalInspectionWithPreparedStmts(db *sql.DB) (*Cluster, error) { // Kill should be called upon shutdown, it will prevent retrying failed // database queries. func (c *Cluster) Kill() { + c.clusterMu.Lock() c.closing = true + c.clusterMu.Unlock() } // GetNodeID returns the current nodeID (0 if not set) @@ -391,7 +394,11 @@ func (c *Cluster) transaction(f func(*ClusterTx) error) error { } func (c *Cluster) retry(f func() error) error { - if c.closing { + c.clusterMu.Lock() + closing := c.closing + c.clusterMu.Unlock() + + if closing { return f() } return query.Retry(f) From c9b85e0bdf78c73676df49b532b56a5ad8d79c23 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Thu, 6 Aug 2020 17:12:13 +0100 Subject: [PATCH 4/4] lxd/operations: Fixes races Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/operations/operations.go | 41 ++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/lxd/operations/operations.go b/lxd/operations/operations.go index 8b7208103f..7067bcebb1 100644 --- a/lxd/operations/operations.go +++ b/lxd/operations/operations.go @@ -186,7 +186,10 @@ func OperationCreate(s *state.State, project string, opClass operationClass, opT logger.Debugf("New %s Operation: %s", op.class.String(), op.id) _, md, _ := op.Render() + + operationsLock.Lock() op.sendEvent(md) + operationsLock.Unlock() return &op, nil } @@ -255,9 +258,12 @@ func (op *Operation) Run() (chan error, error) { chanRun <- err logger.Debugf("Failure for %s operation: %s: %s", op.class.String(), op.id, err) - _, md, _ := op.Render() + + op.lock.Lock() op.sendEvent(md) + op.lock.Unlock() + return } @@ -267,18 +273,24 @@ func (op *Operation) Run() (chan error, error) { op.done() chanRun <- nil - op.lock.Lock() logger.Debugf("Success for %s operation: %s", op.class.String(), op.id) _, md, _ := op.Render() + + op.lock.Lock() op.sendEvent(md) op.lock.Unlock() }(op, chanRun) } + op.lock.Unlock() logger.Debugf("Started %s operation: %s", op.class.String(), op.id) _, md, _ := op.Render() + + op.lock.Lock() op.sendEvent(md) + op.lock.Unlock() + return chanRun, nil } @@ -313,7 +325,11 @@ func (op *Operation) Cancel() (chan error, error) { logger.Debugf("Failed to cancel %s Operation: %s: %s", op.class.String(), op.id, err) _, md, _ := op.Render() + + op.lock.Lock() op.sendEvent(md) + op.lock.Unlock() + return } @@ -325,7 +341,11 @@ func (op *Operation) Cancel() (chan error, error) { logger.Debugf("Cancelled %s Operation: %s", op.class.String(), op.id) _, md, _ := op.Render() + + op.lock.Lock() op.sendEvent(md) + op.lock.Unlock() + }(op, oldStatus, chanCancel) } @@ -350,7 +370,10 @@ func (op *Operation) Cancel() (chan error, error) { logger.Debugf("Cancelled %s Operation: %s", op.class.String(), op.id) _, md, _ = op.Render() + + op.lock.Lock() op.sendEvent(md) + op.lock.Unlock() return chanCancel, nil } @@ -429,7 +452,8 @@ func (op *Operation) Render() (string, *api.Operation, error) { return "", nil, err } - return op.url, &api.Operation{ + op.lock.Lock() + retOp := &api.Operation{ ID: op.id, Class: op.class.String(), Description: op.description, @@ -442,7 +466,10 @@ func (op *Operation) Render() (string, *api.Operation, error) { MayCancel: op.mayCancel(), Err: op.err, Location: serverName, - }, nil + } + op.lock.Unlock() + + return op.url, retOp, nil } // WaitFinal waits for the operation to be done. If timeout is -1, it will wait @@ -495,7 +522,10 @@ func (op *Operation) UpdateResources(opResources map[string][]string) error { logger.Debugf("Updated resources for %s Operation: %s", op.class.String(), op.id) _, md, _ := op.Render() + + op.lock.Lock() op.sendEvent(md) + op.lock.Unlock() return nil } @@ -523,7 +553,10 @@ func (op *Operation) UpdateMetadata(opMetadata interface{}) error { logger.Debugf("Updated metadata for %s Operation: %s", op.class.String(), op.id) _, md, _ := op.Render() + + op.lock.Lock() op.sendEvent(md) + op.lock.Unlock() return nil }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel