Skip to content

Commit fc1cf19

Browse files
committed
Add more locking to storage drivers
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
1 parent b1debf1 commit fc1cf19

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

daemon/graphdriver/aufs/aufs.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
"github.com/docker/docker/pkg/chrootarchive"
4545
"github.com/docker/docker/pkg/directory"
4646
"github.com/docker/docker/pkg/idtools"
47+
"github.com/docker/docker/pkg/locker"
4748
mountpk "github.com/docker/docker/pkg/mount"
4849

4950
"github.com/opencontainers/runc/libcontainer/label"
@@ -75,6 +76,7 @@ type Driver struct {
7576
pathCacheLock sync.Mutex
7677
pathCache map[string]string
7778
naiveDiff graphdriver.DiffDriver
79+
locker *locker.Locker
7880
}
7981

8082
// Init returns a new AUFS driver.
@@ -112,6 +114,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
112114
gidMaps: gidMaps,
113115
pathCache: make(map[string]string),
114116
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicAufs)),
117+
locker: locker.New(),
115118
}
116119

117120
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
@@ -304,6 +307,8 @@ func debugEBusy(mountPath string) (out []string, err error) {
304307

305308
// Remove will unmount and remove the given id.
306309
func (a *Driver) Remove(id string) error {
310+
a.locker.Lock(id)
311+
defer a.locker.Unlock(id)
307312
a.pathCacheLock.Lock()
308313
mountpoint, exists := a.pathCache[id]
309314
a.pathCacheLock.Unlock()
@@ -377,6 +382,8 @@ func (a *Driver) Remove(id string) error {
377382
// Get returns the rootfs path for the id.
378383
// This will mount the dir at its given path
379384
func (a *Driver) Get(id, mountLabel string) (string, error) {
385+
a.locker.Lock(id)
386+
defer a.locker.Unlock(id)
380387
parents, err := a.getParentLayerPaths(id)
381388
if err != nil && !os.IsNotExist(err) {
382389
return "", err
@@ -412,6 +419,8 @@ func (a *Driver) Get(id, mountLabel string) (string, error) {
412419

413420
// Put unmounts and updates list of active mounts.
414421
func (a *Driver) Put(id string) error {
422+
a.locker.Lock(id)
423+
defer a.locker.Unlock(id)
415424
a.pathCacheLock.Lock()
416425
m, exists := a.pathCache[id]
417426
if !exists {

daemon/graphdriver/devmapper/driver.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ import (
1414
"github.com/docker/docker/daemon/graphdriver"
1515
"github.com/docker/docker/pkg/devicemapper"
1616
"github.com/docker/docker/pkg/idtools"
17+
"github.com/docker/docker/pkg/locker"
1718
"github.com/docker/docker/pkg/mount"
18-
"github.com/docker/go-units"
19+
units "github.com/docker/go-units"
1920
)
2021

2122
func init() {
@@ -29,6 +30,7 @@ type Driver struct {
2930
uidMaps []idtools.IDMap
3031
gidMaps []idtools.IDMap
3132
ctr *graphdriver.RefCounter
33+
locker *locker.Locker
3234
}
3335

3436
// Init creates a driver with the given home and the set of options.
@@ -48,6 +50,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
4850
uidMaps: uidMaps,
4951
gidMaps: gidMaps,
5052
ctr: graphdriver.NewRefCounter(graphdriver.NewDefaultChecker()),
53+
locker: locker.New(),
5154
}
5255

5356
return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil
@@ -142,6 +145,8 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
142145

143146
// Remove removes a device with a given id, unmounts the filesystem.
144147
func (d *Driver) Remove(id string) error {
148+
d.locker.Lock(id)
149+
defer d.locker.Unlock(id)
145150
if !d.DeviceSet.HasDevice(id) {
146151
// Consider removing a non-existing device a no-op
147152
// This is useful to be able to progress on container removal
@@ -164,6 +169,8 @@ func (d *Driver) Remove(id string) error {
164169

165170
// Get mounts a device with given id into the root filesystem
166171
func (d *Driver) Get(id, mountLabel string) (string, error) {
172+
d.locker.Lock(id)
173+
defer d.locker.Unlock(id)
167174
mp := path.Join(d.home, "mnt", id)
168175
rootFs := path.Join(mp, "rootfs")
169176
if count := d.ctr.Increment(mp); count > 1 {
@@ -214,6 +221,8 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
214221

215222
// Put unmounts a device and removes it.
216223
func (d *Driver) Put(id string) error {
224+
d.locker.Lock(id)
225+
defer d.locker.Unlock(id)
217226
mp := path.Join(d.home, "mnt", id)
218227
if count := d.ctr.Decrement(mp); count > 0 {
219228
return nil

daemon/graphdriver/overlay/overlay.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/docker/docker/pkg/archive"
2020
"github.com/docker/docker/pkg/fsutils"
2121
"github.com/docker/docker/pkg/idtools"
22+
"github.com/docker/docker/pkg/locker"
2223
"github.com/docker/docker/pkg/mount"
2324
"github.com/opencontainers/runc/libcontainer/label"
2425
)
@@ -97,6 +98,7 @@ type Driver struct {
9798
gidMaps []idtools.IDMap
9899
ctr *graphdriver.RefCounter
99100
supportsDType bool
101+
locker *locker.Locker
100102
}
101103

102104
func init() {
@@ -154,6 +156,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
154156
gidMaps: gidMaps,
155157
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
156158
supportsDType: supportsDType,
159+
locker: locker.New(),
157160
}
158161

159162
return NaiveDiffDriverWithApply(d, uidMaps, gidMaps), nil
@@ -334,6 +337,8 @@ func (d *Driver) dir(id string) string {
334337

335338
// Remove cleans the directories that are created for this id.
336339
func (d *Driver) Remove(id string) error {
340+
d.locker.Lock(id)
341+
defer d.locker.Unlock(id)
337342
if err := os.RemoveAll(d.dir(id)); err != nil && !os.IsNotExist(err) {
338343
return err
339344
}
@@ -342,6 +347,8 @@ func (d *Driver) Remove(id string) error {
342347

343348
// Get creates and mounts the required file system for the given id and returns the mount path.
344349
func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
350+
d.locker.Lock(id)
351+
defer d.locker.Unlock(id)
345352
dir := d.dir(id)
346353
if _, err := os.Stat(dir); err != nil {
347354
return "", err
@@ -389,6 +396,8 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
389396

390397
// Put unmounts the mount path created for the give id.
391398
func (d *Driver) Put(id string) error {
399+
d.locker.Lock(id)
400+
defer d.locker.Unlock(id)
392401
// If id has a root, just return
393402
if _, err := os.Stat(path.Join(d.dir(id), "root")); err == nil {
394403
return nil

daemon/graphdriver/overlay2/overlay.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/docker/docker/pkg/directory"
2828
"github.com/docker/docker/pkg/fsutils"
2929
"github.com/docker/docker/pkg/idtools"
30+
"github.com/docker/docker/pkg/locker"
3031
"github.com/docker/docker/pkg/mount"
3132
"github.com/docker/docker/pkg/parsers"
3233
"github.com/docker/docker/pkg/parsers/kernel"
@@ -98,6 +99,7 @@ type Driver struct {
9899
options overlayOptions
99100
naiveDiff graphdriver.DiffDriver
100101
supportsDType bool
102+
locker *locker.Locker
101103
}
102104

103105
var (
@@ -180,6 +182,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
180182
gidMaps: gidMaps,
181183
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
182184
supportsDType: supportsDType,
185+
locker: locker.New(),
183186
}
184187

185188
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps)
@@ -451,6 +454,8 @@ func (d *Driver) getLowerDirs(id string) ([]string, error) {
451454

452455
// Remove cleans the directories that are created for this id.
453456
func (d *Driver) Remove(id string) error {
457+
d.locker.Lock(id)
458+
defer d.locker.Unlock(id)
454459
dir := d.dir(id)
455460
lid, err := ioutil.ReadFile(path.Join(dir, "link"))
456461
if err == nil {
@@ -467,6 +472,8 @@ func (d *Driver) Remove(id string) error {
467472

468473
// Get creates and mounts the required file system for the given id and returns the mount path.
469474
func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
475+
d.locker.Lock(id)
476+
defer d.locker.Unlock(id)
470477
dir := d.dir(id)
471478
if _, err := os.Stat(dir); err != nil {
472479
return "", err
@@ -553,6 +560,8 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
553560

554561
// Put unmounts the mount path created for the give id.
555562
func (d *Driver) Put(id string) error {
563+
d.locker.Lock(id)
564+
defer d.locker.Unlock(id)
556565
dir := d.dir(id)
557566
_, err := ioutil.ReadFile(path.Join(dir, lowerFile))
558567
if err != nil {

0 commit comments

Comments
 (0)