mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Fix race condition between container register and mount
When a container is created it is registered before the mount is created. This can lead to mount does not exist errors when inspecting between create and mount. Fixes #18753 Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
parent
d04fa49a0d
commit
d8e090669e
3 changed files with 37 additions and 30 deletions
|
@ -74,6 +74,15 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig) (*container.Con
|
|||
}
|
||||
}()
|
||||
|
||||
if err := daemon.setSecurityOptions(container, params.HostConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set RWLayer for container after mount labels have been set
|
||||
if err := daemon.setRWLayer(container); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := daemon.Register(container); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -96,11 +105,6 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig) (*container.Con
|
|||
}
|
||||
}()
|
||||
|
||||
// Set RWLayer for container after mount labels have been set
|
||||
if err := daemon.setRWLayer(container); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := daemon.createContainerPlatformSpecificSettings(container, params.Config, params.HostConfig, img); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -226,18 +226,30 @@ func (daemon *Daemon) load(id string) (*container.Container, error) {
|
|||
return container, nil
|
||||
}
|
||||
|
||||
// Register makes a container object usable by the daemon as <container.ID>
|
||||
func (daemon *Daemon) Register(container *container.Container) error {
|
||||
func (daemon *Daemon) registerName(container *container.Container) error {
|
||||
if daemon.Exists(container.ID) {
|
||||
return fmt.Errorf("Container is already loaded")
|
||||
}
|
||||
if err := validateID(container.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := daemon.ensureName(container); err != nil {
|
||||
return err
|
||||
if container.Name == "" {
|
||||
name, err := daemon.generateNewName(container.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
container.Name = name
|
||||
|
||||
if err := container.ToDiskLocking(); err != nil {
|
||||
logrus.Errorf("Error saving container name to disk: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Register makes a container object usable by the daemon as <container.ID>
|
||||
func (daemon *Daemon) Register(container *container.Container) error {
|
||||
// Attach to stdout and stderr
|
||||
if container.Config.OpenStdin {
|
||||
container.NewInputPipes()
|
||||
|
@ -277,21 +289,6 @@ func (daemon *Daemon) Register(container *container.Container) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) ensureName(container *container.Container) error {
|
||||
if container.Name == "" {
|
||||
name, err := daemon.generateNewName(container.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
container.Name = name
|
||||
|
||||
if err := container.ToDiskLocking(); err != nil {
|
||||
logrus.Errorf("Error saving container name to disk: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) restore() error {
|
||||
type cr struct {
|
||||
container *container.Container
|
||||
|
@ -368,6 +365,10 @@ func (daemon *Daemon) restore() error {
|
|||
logrus.Debugf("Setting default id - %s", err)
|
||||
}
|
||||
}
|
||||
if err := daemon.registerName(container); err != nil {
|
||||
logrus.Errorf("Failed to register container %s: %s", container.ID, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := daemon.Register(container); err != nil {
|
||||
logrus.Errorf("Failed to register container %s: %s", container.ID, err)
|
||||
|
@ -1392,14 +1393,13 @@ func tempDir(rootDir string, rootUID, rootGID int) (string, error) {
|
|||
return tmpDir, idtools.MkdirAllAs(tmpDir, 0700, rootUID, rootGID)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error {
|
||||
func (daemon *Daemon) setSecurityOptions(container *container.Container, hostConfig *containertypes.HostConfig) error {
|
||||
container.Lock()
|
||||
if err := parseSecurityOpt(container, hostConfig); err != nil {
|
||||
container.Unlock()
|
||||
return err
|
||||
}
|
||||
container.Unlock()
|
||||
defer container.Unlock()
|
||||
return parseSecurityOpt(container, hostConfig)
|
||||
}
|
||||
|
||||
func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig *containertypes.HostConfig) error {
|
||||
// Do not lock while creating volumes since this could be calling out to external plugins
|
||||
// Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
|
||||
if err := daemon.registerMountPoints(container, hostConfig); err != nil {
|
||||
|
|
|
@ -31,6 +31,9 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos
|
|||
// creating a container, not during start.
|
||||
if hostConfig != nil {
|
||||
logrus.Warn("DEPRECATED: Setting host configuration options when the container starts is deprecated and will be removed in Docker 1.12")
|
||||
if err := daemon.setSecurityOptions(container, hostConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := daemon.setHostConfig(container, hostConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue