33package daemon // import "github.com/docker/docker/daemon"
44
55import (
6+ "context"
67 "fmt"
78 "os"
89 "sort"
910 "strconv"
1011 "strings"
1112
13+ "github.com/containerd/log"
1214 "github.com/docker/docker/api/types/events"
1315 mounttypes "github.com/docker/docker/api/types/mount"
1416 "github.com/docker/docker/container"
17+ "github.com/docker/docker/internal/cleanups"
1518 volumemounts "github.com/docker/docker/volume/mounts"
1619 "github.com/pkg/errors"
1720)
1821
1922// setupMounts iterates through each of the mount points for a container and
2023// calls Setup() on each. It also looks to see if is a network mount such as
2124// /etc/resolv.conf, and if it is not, appends it to the array of mounts.
22- func (daemon * Daemon ) setupMounts (c * container.Container ) ([]container.Mount , error ) {
25+ //
26+ // The cleanup function should be called as soon as the container has been
27+ // started.
28+ func (daemon * Daemon ) setupMounts (c * container.Container ) ([]container.Mount , func () error , error ) {
2329 var mounts []container.Mount
2430 // TODO: tmpfs mounts should be part of Mountpoints
2531 tmpfsMounts := make (map [string ]bool )
2632 tmpfsMountInfo , err := c .TmpfsMounts ()
2733 if err != nil {
28- return nil , err
34+ return nil , nil , err
2935 }
3036 for _ , m := range tmpfsMountInfo {
3137 tmpfsMounts [m .Destination ] = true
3238 }
39+
40+ cleanups := cleanups.Composite {}
41+ defer func () {
42+ if err := cleanups .Call (); err != nil {
43+ log .G (context .TODO ()).WithError (err ).Warn ("failed to cleanup temporary mounts created by MountPoint.Setup" )
44+ }
45+ }()
46+
3347 for _ , m := range c .MountPoints {
3448 if tmpfsMounts [m .Destination ] {
3549 continue
3650 }
3751 if err := daemon .lazyInitializeVolume (c .ID , m ); err != nil {
38- return nil , err
52+ return nil , nil , err
3953 }
4054 // If the daemon is being shutdown, we should not let a container start if it is trying to
4155 // mount the socket the daemon is listening on. During daemon shutdown, the socket
@@ -48,10 +62,12 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
4862 return nil
4963 }
5064
51- path , err := m .Setup (c .MountLabel , daemon .idMapping .RootPair (), checkfunc )
65+ path , clean , err := m .Setup (c .MountLabel , daemon .idMapping .RootPair (), checkfunc )
5266 if err != nil {
53- return nil , err
67+ return nil , nil , err
5468 }
69+ cleanups .Add (clean )
70+
5571 if ! c .TrySetNetworkMount (m .Destination , path ) {
5672 mnt := container.Mount {
5773 Source : path ,
@@ -61,13 +77,13 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
6177 }
6278 if m .Spec .Type == mounttypes .TypeBind && m .Spec .BindOptions != nil {
6379 if ! m .Spec .ReadOnly && m .Spec .BindOptions .ReadOnlyNonRecursive {
64- return nil , errors .New ("mount options conflict: !ReadOnly && BindOptions.ReadOnlyNonRecursive" )
80+ return nil , nil , errors .New ("mount options conflict: !ReadOnly && BindOptions.ReadOnlyNonRecursive" )
6581 }
6682 if ! m .Spec .ReadOnly && m .Spec .BindOptions .ReadOnlyForceRecursive {
67- return nil , errors .New ("mount options conflict: !ReadOnly && BindOptions.ReadOnlyForceRecursive" )
83+ return nil , nil , errors .New ("mount options conflict: !ReadOnly && BindOptions.ReadOnlyForceRecursive" )
6884 }
6985 if m .Spec .BindOptions .ReadOnlyNonRecursive && m .Spec .BindOptions .ReadOnlyForceRecursive {
70- return nil , errors .New ("mount options conflict: ReadOnlyNonRecursive && BindOptions.ReadOnlyForceRecursive" )
86+ return nil , nil , errors .New ("mount options conflict: ReadOnlyNonRecursive && BindOptions.ReadOnlyForceRecursive" )
7187 }
7288 mnt .NonRecursive = m .Spec .BindOptions .NonRecursive
7389 mnt .ReadOnlyNonRecursive = m .Spec .BindOptions .ReadOnlyNonRecursive
@@ -98,11 +114,11 @@ func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, er
98114 // up to the user to make sure the file has proper ownership for userns
99115 if strings .Index (mnt .Source , daemon .repository ) == 0 {
100116 if err := os .Chown (mnt .Source , rootIDs .UID , rootIDs .GID ); err != nil {
101- return nil , err
117+ return nil , nil , err
102118 }
103119 }
104120 }
105- return append (mounts , netMounts ... ), nil
121+ return append (mounts , netMounts ... ), cleanups . Release (), nil
106122}
107123
108124// sortMounts sorts an array of mounts in lexicographic order. This ensure that
0 commit comments