Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -44,6 +44,7 @@ import ( |
| 44 | 44 |
"github.com/docker/docker/pkg/chrootarchive" |
| 45 | 45 |
"github.com/docker/docker/pkg/directory" |
| 46 | 46 |
"github.com/docker/docker/pkg/idtools" |
| 47 |
+ "github.com/docker/docker/pkg/locker" |
|
| 47 | 48 |
mountpk "github.com/docker/docker/pkg/mount" |
| 48 | 49 |
|
| 49 | 50 |
"github.com/opencontainers/runc/libcontainer/label" |
| ... | ... |
@@ -75,6 +76,7 @@ type Driver struct {
|
| 75 | 75 |
pathCacheLock sync.Mutex |
| 76 | 76 |
pathCache map[string]string |
| 77 | 77 |
naiveDiff graphdriver.DiffDriver |
| 78 |
+ locker *locker.Locker |
|
| 78 | 79 |
} |
| 79 | 80 |
|
| 80 | 81 |
// Init returns a new AUFS driver. |
| ... | ... |
@@ -112,6 +114,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap |
| 112 | 112 |
gidMaps: gidMaps, |
| 113 | 113 |
pathCache: make(map[string]string), |
| 114 | 114 |
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicAufs)), |
| 115 |
+ locker: locker.New(), |
|
| 115 | 116 |
} |
| 116 | 117 |
|
| 117 | 118 |
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) |
| ... | ... |
@@ -304,6 +307,8 @@ func debugEBusy(mountPath string) (out []string, err error) {
|
| 304 | 304 |
|
| 305 | 305 |
// Remove will unmount and remove the given id. |
| 306 | 306 |
func (a *Driver) Remove(id string) error {
|
| 307 |
+ a.locker.Lock(id) |
|
| 308 |
+ defer a.locker.Unlock(id) |
|
| 307 | 309 |
a.pathCacheLock.Lock() |
| 308 | 310 |
mountpoint, exists := a.pathCache[id] |
| 309 | 311 |
a.pathCacheLock.Unlock() |
| ... | ... |
@@ -377,6 +382,8 @@ func (a *Driver) Remove(id string) error {
|
| 377 | 377 |
// Get returns the rootfs path for the id. |
| 378 | 378 |
// This will mount the dir at its given path |
| 379 | 379 |
func (a *Driver) Get(id, mountLabel string) (string, error) {
|
| 380 |
+ a.locker.Lock(id) |
|
| 381 |
+ defer a.locker.Unlock(id) |
|
| 380 | 382 |
parents, err := a.getParentLayerPaths(id) |
| 381 | 383 |
if err != nil && !os.IsNotExist(err) {
|
| 382 | 384 |
return "", err |
| ... | ... |
@@ -412,6 +419,8 @@ func (a *Driver) Get(id, mountLabel string) (string, error) {
|
| 412 | 412 |
|
| 413 | 413 |
// Put unmounts and updates list of active mounts. |
| 414 | 414 |
func (a *Driver) Put(id string) error {
|
| 415 |
+ a.locker.Lock(id) |
|
| 416 |
+ defer a.locker.Unlock(id) |
|
| 415 | 417 |
a.pathCacheLock.Lock() |
| 416 | 418 |
m, exists := a.pathCache[id] |
| 417 | 419 |
if !exists {
|
| ... | ... |
@@ -14,8 +14,9 @@ import ( |
| 14 | 14 |
"github.com/docker/docker/daemon/graphdriver" |
| 15 | 15 |
"github.com/docker/docker/pkg/devicemapper" |
| 16 | 16 |
"github.com/docker/docker/pkg/idtools" |
| 17 |
+ "github.com/docker/docker/pkg/locker" |
|
| 17 | 18 |
"github.com/docker/docker/pkg/mount" |
| 18 |
- "github.com/docker/go-units" |
|
| 19 |
+ units "github.com/docker/go-units" |
|
| 19 | 20 |
) |
| 20 | 21 |
|
| 21 | 22 |
func init() {
|
| ... | ... |
@@ -29,6 +30,7 @@ type Driver struct {
|
| 29 | 29 |
uidMaps []idtools.IDMap |
| 30 | 30 |
gidMaps []idtools.IDMap |
| 31 | 31 |
ctr *graphdriver.RefCounter |
| 32 |
+ locker *locker.Locker |
|
| 32 | 33 |
} |
| 33 | 34 |
|
| 34 | 35 |
// 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 |
| 48 | 48 |
uidMaps: uidMaps, |
| 49 | 49 |
gidMaps: gidMaps, |
| 50 | 50 |
ctr: graphdriver.NewRefCounter(graphdriver.NewDefaultChecker()), |
| 51 |
+ locker: locker.New(), |
|
| 51 | 52 |
} |
| 52 | 53 |
|
| 53 | 54 |
return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil |
| ... | ... |
@@ -142,6 +145,8 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
|
| 142 | 142 |
|
| 143 | 143 |
// Remove removes a device with a given id, unmounts the filesystem. |
| 144 | 144 |
func (d *Driver) Remove(id string) error {
|
| 145 |
+ d.locker.Lock(id) |
|
| 146 |
+ defer d.locker.Unlock(id) |
|
| 145 | 147 |
if !d.DeviceSet.HasDevice(id) {
|
| 146 | 148 |
// Consider removing a non-existing device a no-op |
| 147 | 149 |
// This is useful to be able to progress on container removal |
| ... | ... |
@@ -164,6 +169,8 @@ func (d *Driver) Remove(id string) error {
|
| 164 | 164 |
|
| 165 | 165 |
// Get mounts a device with given id into the root filesystem |
| 166 | 166 |
func (d *Driver) Get(id, mountLabel string) (string, error) {
|
| 167 |
+ d.locker.Lock(id) |
|
| 168 |
+ defer d.locker.Unlock(id) |
|
| 167 | 169 |
mp := path.Join(d.home, "mnt", id) |
| 168 | 170 |
rootFs := path.Join(mp, "rootfs") |
| 169 | 171 |
if count := d.ctr.Increment(mp); count > 1 {
|
| ... | ... |
@@ -214,6 +221,8 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
| 214 | 214 |
|
| 215 | 215 |
// Put unmounts a device and removes it. |
| 216 | 216 |
func (d *Driver) Put(id string) error {
|
| 217 |
+ d.locker.Lock(id) |
|
| 218 |
+ defer d.locker.Unlock(id) |
|
| 217 | 219 |
mp := path.Join(d.home, "mnt", id) |
| 218 | 220 |
if count := d.ctr.Decrement(mp); count > 0 {
|
| 219 | 221 |
return nil |
| ... | ... |
@@ -19,6 +19,7 @@ import ( |
| 19 | 19 |
"github.com/docker/docker/pkg/archive" |
| 20 | 20 |
"github.com/docker/docker/pkg/fsutils" |
| 21 | 21 |
"github.com/docker/docker/pkg/idtools" |
| 22 |
+ "github.com/docker/docker/pkg/locker" |
|
| 22 | 23 |
"github.com/docker/docker/pkg/mount" |
| 23 | 24 |
"github.com/opencontainers/runc/libcontainer/label" |
| 24 | 25 |
) |
| ... | ... |
@@ -97,6 +98,7 @@ type Driver struct {
|
| 97 | 97 |
gidMaps []idtools.IDMap |
| 98 | 98 |
ctr *graphdriver.RefCounter |
| 99 | 99 |
supportsDType bool |
| 100 |
+ locker *locker.Locker |
|
| 100 | 101 |
} |
| 101 | 102 |
|
| 102 | 103 |
func init() {
|
| ... | ... |
@@ -154,6 +156,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap |
| 154 | 154 |
gidMaps: gidMaps, |
| 155 | 155 |
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)), |
| 156 | 156 |
supportsDType: supportsDType, |
| 157 |
+ locker: locker.New(), |
|
| 157 | 158 |
} |
| 158 | 159 |
|
| 159 | 160 |
return NaiveDiffDriverWithApply(d, uidMaps, gidMaps), nil |
| ... | ... |
@@ -334,6 +337,8 @@ func (d *Driver) dir(id string) string {
|
| 334 | 334 |
|
| 335 | 335 |
// Remove cleans the directories that are created for this id. |
| 336 | 336 |
func (d *Driver) Remove(id string) error {
|
| 337 |
+ d.locker.Lock(id) |
|
| 338 |
+ defer d.locker.Unlock(id) |
|
| 337 | 339 |
if err := os.RemoveAll(d.dir(id)); err != nil && !os.IsNotExist(err) {
|
| 338 | 340 |
return err |
| 339 | 341 |
} |
| ... | ... |
@@ -342,6 +347,8 @@ func (d *Driver) Remove(id string) error {
|
| 342 | 342 |
|
| 343 | 343 |
// Get creates and mounts the required file system for the given id and returns the mount path. |
| 344 | 344 |
func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
| 345 |
+ d.locker.Lock(id) |
|
| 346 |
+ defer d.locker.Unlock(id) |
|
| 345 | 347 |
dir := d.dir(id) |
| 346 | 348 |
if _, err := os.Stat(dir); err != nil {
|
| 347 | 349 |
return "", err |
| ... | ... |
@@ -389,6 +396,8 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
| 389 | 389 |
|
| 390 | 390 |
// Put unmounts the mount path created for the give id. |
| 391 | 391 |
func (d *Driver) Put(id string) error {
|
| 392 |
+ d.locker.Lock(id) |
|
| 393 |
+ defer d.locker.Unlock(id) |
|
| 392 | 394 |
// If id has a root, just return |
| 393 | 395 |
if _, err := os.Stat(path.Join(d.dir(id), "root")); err == nil {
|
| 394 | 396 |
return nil |
| ... | ... |
@@ -27,6 +27,7 @@ import ( |
| 27 | 27 |
"github.com/docker/docker/pkg/directory" |
| 28 | 28 |
"github.com/docker/docker/pkg/fsutils" |
| 29 | 29 |
"github.com/docker/docker/pkg/idtools" |
| 30 |
+ "github.com/docker/docker/pkg/locker" |
|
| 30 | 31 |
"github.com/docker/docker/pkg/mount" |
| 31 | 32 |
"github.com/docker/docker/pkg/parsers" |
| 32 | 33 |
"github.com/docker/docker/pkg/parsers/kernel" |
| ... | ... |
@@ -98,6 +99,7 @@ type Driver struct {
|
| 98 | 98 |
options overlayOptions |
| 99 | 99 |
naiveDiff graphdriver.DiffDriver |
| 100 | 100 |
supportsDType bool |
| 101 |
+ locker *locker.Locker |
|
| 101 | 102 |
} |
| 102 | 103 |
|
| 103 | 104 |
var ( |
| ... | ... |
@@ -180,6 +182,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap |
| 180 | 180 |
gidMaps: gidMaps, |
| 181 | 181 |
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)), |
| 182 | 182 |
supportsDType: supportsDType, |
| 183 |
+ locker: locker.New(), |
|
| 183 | 184 |
} |
| 184 | 185 |
|
| 185 | 186 |
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps) |
| ... | ... |
@@ -451,6 +454,8 @@ func (d *Driver) getLowerDirs(id string) ([]string, error) {
|
| 451 | 451 |
|
| 452 | 452 |
// Remove cleans the directories that are created for this id. |
| 453 | 453 |
func (d *Driver) Remove(id string) error {
|
| 454 |
+ d.locker.Lock(id) |
|
| 455 |
+ defer d.locker.Unlock(id) |
|
| 454 | 456 |
dir := d.dir(id) |
| 455 | 457 |
lid, err := ioutil.ReadFile(path.Join(dir, "link")) |
| 456 | 458 |
if err == nil {
|
| ... | ... |
@@ -467,6 +472,8 @@ func (d *Driver) Remove(id string) error {
|
| 467 | 467 |
|
| 468 | 468 |
// Get creates and mounts the required file system for the given id and returns the mount path. |
| 469 | 469 |
func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
| 470 |
+ d.locker.Lock(id) |
|
| 471 |
+ defer d.locker.Unlock(id) |
|
| 470 | 472 |
dir := d.dir(id) |
| 471 | 473 |
if _, err := os.Stat(dir); err != nil {
|
| 472 | 474 |
return "", err |
| ... | ... |
@@ -553,6 +560,8 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
| 553 | 553 |
|
| 554 | 554 |
// Put unmounts the mount path created for the give id. |
| 555 | 555 |
func (d *Driver) Put(id string) error {
|
| 556 |
+ d.locker.Lock(id) |
|
| 557 |
+ defer d.locker.Unlock(id) |
|
| 556 | 558 |
dir := d.dir(id) |
| 557 | 559 |
_, err := ioutil.ReadFile(path.Join(dir, lowerFile)) |
| 558 | 560 |
if err != nil {
|