Skip to content

Commit 58618bb

Browse files
committed
DockerIM in CO deletes volume only once for concurrent host deletions.
1 parent 1df6aa0 commit 58618bb

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

pkg/app/instances/docker.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"log"
2222
"net/url"
2323
"strings"
24+
"sync"
2425
"time"
2526

2627
apiv1 "github.com/google/cloud-android-orchestration/api/v1"
@@ -53,8 +54,9 @@ const uaMountTarget = "/var/lib/cuttlefish-common/userartifacts"
5354

5455
// Docker implementation of the instance manager.
5556
type DockerInstanceManager struct {
56-
Config Config
57-
Client *client.Client
57+
Config Config
58+
Client *client.Client
59+
mutexes sync.Map
5860
}
5961

6062
type OPType string
@@ -83,6 +85,9 @@ func (m *DockerInstanceManager) CreateHost(zone string, _ *apiv1.CreateHostReque
8385
if zone != "local" {
8486
return nil, errors.NewBadRequestError("Invalid zone. It should be 'local'.", nil)
8587
}
88+
mu := m.getRWMutex(user)
89+
mu.RLock()
90+
defer mu.RUnlock()
8691
ctx := context.TODO()
8792
if err := m.downloadDockerImageIfNeeded(ctx); err != nil {
8893
return nil, fmt.Errorf("failed to retrieve docker image name: %w", err)
@@ -423,6 +428,15 @@ func (m *DockerInstanceManager) deleteDockerVolumeIfNeeded(ctx context.Context,
423428
if len(listRes) > 0 {
424429
return nil
425430
}
431+
432+
mu := m.getRWMutex(user)
433+
if locked := mu.TryLock(); !locked {
434+
// If it can't acquire lock on this mutex, there's ongoing host
435+
// creation with this volume or deletion of this volume. For these
436+
// cases, it doesn't need to delete docker volume here.
437+
return nil
438+
}
439+
defer mu.Unlock()
426440
listOpts := volume.ListOptions{Filters: dockerFilter(user)}
427441
volumeListRes, err := m.Client.VolumeList(ctx, listOpts)
428442
if err != nil {
@@ -435,3 +449,8 @@ func (m *DockerInstanceManager) deleteDockerVolumeIfNeeded(ctx context.Context,
435449
}
436450
return nil
437451
}
452+
453+
func (m *DockerInstanceManager) getRWMutex(user accounts.User) *sync.RWMutex {
454+
mu, _ := m.mutexes.LoadOrStore(user.Username(), &sync.RWMutex{})
455+
return mu.(*sync.RWMutex)
456+
}

0 commit comments

Comments
 (0)