Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

[18.06] Fix bindmount autocreate race #11

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions daemon/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
}
}

if mp.Type == mounttypes.TypeBind {
mp.SkipMountpointCreation = true
}

binds[mp.Destination] = true
dereferenceIfExists(mp.Destination)
mountPoints[mp.Destination] = mp
Expand Down
11 changes: 11 additions & 0 deletions volume/mounts/mounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ type MountPoint struct {
// Sepc is a copy of the API request that created this mount.
Spec mounttypes.Mount

// Some bind mounts should not be automatically created.
// (Some are auto-created for backwards-compatability)
// This is checked on the API but setting this here prevents race conditions.
// where a bind dir existed during validation was removed before reaching the setup code.
SkipMountpointCreation bool

// Track usage of this mountpoint
// Specifically needed for containers which are running and calls to `docker cp`
// because both these actions require mounting the volumes.
Expand Down Expand Up @@ -90,6 +96,10 @@ func (m *MountPoint) Cleanup() error {
// The, optional, checkFun parameter allows doing additional checking
// before creating the source directory on the host.
func (m *MountPoint) Setup(mountLabel string, rootIDs idtools.IDPair, checkFun func(m *MountPoint) error) (path string, err error) {
if m.SkipMountpointCreation {
return m.Source, nil
}

defer func() {
if err != nil || !label.RelabelNeeded(m.Mode) {
return
Expand Down Expand Up @@ -140,6 +150,7 @@ func (m *MountPoint) Setup(mountLabel string, rootIDs idtools.IDPair, checkFun f
return "", err
}
}

// idtools.MkdirAllNewAs() produces an error if m.Source exists and is a file (not a directory)
// also, makes sure that if the directory is created, the correct remapped rootUID/rootGID will own it
if err := idtools.MkdirAllAndChownNew(m.Source, 0755, rootIDs); err != nil {
Expand Down