mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #31136 from tonistiigi/more-locks
Add more locking to storage drivers
This commit is contained in:
commit
1ad165dba1
4 changed files with 37 additions and 1 deletions
|
@ -44,6 +44,7 @@ import (
|
|||
"github.com/docker/docker/pkg/chrootarchive"
|
||||
"github.com/docker/docker/pkg/directory"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/locker"
|
||||
mountpk "github.com/docker/docker/pkg/mount"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
|
@ -75,6 +76,7 @@ type Driver struct {
|
|||
pathCacheLock sync.Mutex
|
||||
pathCache map[string]string
|
||||
naiveDiff graphdriver.DiffDriver
|
||||
locker *locker.Locker
|
||||
}
|
||||
|
||||
// Init returns a new AUFS driver.
|
||||
|
@ -112,6 +114,7 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|||
gidMaps: gidMaps,
|
||||
pathCache: make(map[string]string),
|
||||
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicAufs)),
|
||||
locker: locker.New(),
|
||||
}
|
||||
|
||||
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
|
||||
|
@ -304,6 +307,8 @@ func debugEBusy(mountPath string) (out []string, err error) {
|
|||
|
||||
// Remove will unmount and remove the given id.
|
||||
func (a *Driver) Remove(id string) error {
|
||||
a.locker.Lock(id)
|
||||
defer a.locker.Unlock(id)
|
||||
a.pathCacheLock.Lock()
|
||||
mountpoint, exists := a.pathCache[id]
|
||||
a.pathCacheLock.Unlock()
|
||||
|
@ -377,6 +382,8 @@ func (a *Driver) Remove(id string) error {
|
|||
// Get returns the rootfs path for the id.
|
||||
// This will mount the dir at its given path
|
||||
func (a *Driver) Get(id, mountLabel string) (string, error) {
|
||||
a.locker.Lock(id)
|
||||
defer a.locker.Unlock(id)
|
||||
parents, err := a.getParentLayerPaths(id)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return "", err
|
||||
|
@ -412,6 +419,8 @@ func (a *Driver) Get(id, mountLabel string) (string, error) {
|
|||
|
||||
// Put unmounts and updates list of active mounts.
|
||||
func (a *Driver) Put(id string) error {
|
||||
a.locker.Lock(id)
|
||||
defer a.locker.Unlock(id)
|
||||
a.pathCacheLock.Lock()
|
||||
m, exists := a.pathCache[id]
|
||||
if !exists {
|
||||
|
|
|
@ -14,8 +14,9 @@ import (
|
|||
"github.com/docker/docker/daemon/graphdriver"
|
||||
"github.com/docker/docker/pkg/devicemapper"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/locker"
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/docker/go-units"
|
||||
units "github.com/docker/go-units"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -29,6 +30,7 @@ type Driver struct {
|
|||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
ctr *graphdriver.RefCounter
|
||||
locker *locker.Locker
|
||||
}
|
||||
|
||||
// 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
|
|||
uidMaps: uidMaps,
|
||||
gidMaps: gidMaps,
|
||||
ctr: graphdriver.NewRefCounter(graphdriver.NewDefaultChecker()),
|
||||
locker: locker.New(),
|
||||
}
|
||||
|
||||
return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil
|
||||
|
@ -142,6 +145,8 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
|
|||
|
||||
// Remove removes a device with a given id, unmounts the filesystem.
|
||||
func (d *Driver) Remove(id string) error {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
if !d.DeviceSet.HasDevice(id) {
|
||||
// Consider removing a non-existing device a no-op
|
||||
// This is useful to be able to progress on container removal
|
||||
|
@ -164,6 +169,8 @@ func (d *Driver) Remove(id string) error {
|
|||
|
||||
// Get mounts a device with given id into the root filesystem
|
||||
func (d *Driver) Get(id, mountLabel string) (string, error) {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
mp := path.Join(d.home, "mnt", id)
|
||||
rootFs := path.Join(mp, "rootfs")
|
||||
if count := d.ctr.Increment(mp); count > 1 {
|
||||
|
@ -214,6 +221,8 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
|
|||
|
||||
// Put unmounts a device and removes it.
|
||||
func (d *Driver) Put(id string) error {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
mp := path.Join(d.home, "mnt", id)
|
||||
if count := d.ctr.Decrement(mp); count > 0 {
|
||||
return nil
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/fsutils"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/locker"
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/opencontainers/runc/libcontainer/label"
|
||||
)
|
||||
|
@ -97,6 +98,7 @@ type Driver struct {
|
|||
gidMaps []idtools.IDMap
|
||||
ctr *graphdriver.RefCounter
|
||||
supportsDType bool
|
||||
locker *locker.Locker
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -154,6 +156,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|||
gidMaps: gidMaps,
|
||||
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
|
||||
supportsDType: supportsDType,
|
||||
locker: locker.New(),
|
||||
}
|
||||
|
||||
return NaiveDiffDriverWithApply(d, uidMaps, gidMaps), nil
|
||||
|
@ -334,6 +337,8 @@ func (d *Driver) dir(id string) string {
|
|||
|
||||
// Remove cleans the directories that are created for this id.
|
||||
func (d *Driver) Remove(id string) error {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
if err := os.RemoveAll(d.dir(id)); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
@ -342,6 +347,8 @@ func (d *Driver) Remove(id string) error {
|
|||
|
||||
// Get creates and mounts the required file system for the given id and returns the mount path.
|
||||
func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
dir := d.dir(id)
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return "", err
|
||||
|
@ -389,6 +396,8 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
|||
|
||||
// Put unmounts the mount path created for the give id.
|
||||
func (d *Driver) Put(id string) error {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
// If id has a root, just return
|
||||
if _, err := os.Stat(path.Join(d.dir(id), "root")); err == nil {
|
||||
return nil
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/docker/docker/pkg/directory"
|
||||
"github.com/docker/docker/pkg/fsutils"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/locker"
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
"github.com/docker/docker/pkg/parsers/kernel"
|
||||
|
@ -98,6 +99,7 @@ type Driver struct {
|
|||
options overlayOptions
|
||||
naiveDiff graphdriver.DiffDriver
|
||||
supportsDType bool
|
||||
locker *locker.Locker
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -180,6 +182,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|||
gidMaps: gidMaps,
|
||||
ctr: graphdriver.NewRefCounter(graphdriver.NewFsChecker(graphdriver.FsMagicOverlay)),
|
||||
supportsDType: supportsDType,
|
||||
locker: locker.New(),
|
||||
}
|
||||
|
||||
d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps)
|
||||
|
@ -451,6 +454,8 @@ func (d *Driver) getLowerDirs(id string) ([]string, error) {
|
|||
|
||||
// Remove cleans the directories that are created for this id.
|
||||
func (d *Driver) Remove(id string) error {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
dir := d.dir(id)
|
||||
lid, err := ioutil.ReadFile(path.Join(dir, "link"))
|
||||
if err == nil {
|
||||
|
@ -467,6 +472,8 @@ func (d *Driver) Remove(id string) error {
|
|||
|
||||
// Get creates and mounts the required file system for the given id and returns the mount path.
|
||||
func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
dir := d.dir(id)
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return "", err
|
||||
|
@ -553,6 +560,8 @@ func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
|
|||
|
||||
// Put unmounts the mount path created for the give id.
|
||||
func (d *Driver) Put(id string) error {
|
||||
d.locker.Lock(id)
|
||||
defer d.locker.Unlock(id)
|
||||
dir := d.dir(id)
|
||||
_, err := ioutil.ReadFile(path.Join(dir, lowerFile))
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue