Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 3a49765

Browse files
committed
Decouple daemon and container to mount and unmount filesystems.
Side effects: - Decouple daemon and container to start containers. - Decouple daemon and container to copy files. Signed-off-by: David Calavera <david.calavera@gmail.com>
1 parent 1c94f5f commit 3a49765

File tree

17 files changed

+188
-176
lines changed

17 files changed

+188
-176
lines changed

builder/builder.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ type Docker interface {
130130
Release(sessionID string, activeImages []string)
131131
// Kill stops the container execution abruptly.
132132
Kill(c *daemon.Container) error
133+
// Mount mounts the root filesystem for the container.
134+
Mount(c *daemon.Container) error
135+
// Unmount unmounts the root filesystem for the container.
136+
Unmount(c *daemon.Container) error
137+
// Start starts a new container
138+
Start(c *daemon.Container) error
133139
}
134140

135141
// ImageCache abstracts an image cache store.

builder/dockerfile/dispatchers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,8 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
399399

400400
// Ensure that we keep the container mounted until the commit
401401
// to avoid unmounting and then mounting directly again
402-
c.Mount()
403-
defer c.Unmount()
402+
b.docker.Mount(c)
403+
defer b.docker.Unmount(c)
404404

405405
err = b.run(c)
406406
if err != nil {

builder/dockerfile/internals.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ func (b *Builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin
6767
}
6868
id = container.ID
6969

70-
if err := container.Mount(); err != nil {
70+
if err := b.docker.Mount(container); err != nil {
7171
return err
7272
}
73-
defer container.Unmount()
73+
defer b.docker.Unmount(container)
7474
}
7575

7676
container, err := b.docker.Container(id)
@@ -201,7 +201,7 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD
201201
if err != nil {
202202
return err
203203
}
204-
defer container.Unmount()
204+
defer b.docker.Unmount(container)
205205
b.tmpContainers[container.ID] = struct{}{}
206206

207207
comment := fmt.Sprintf("%s %s in %s", cmdName, origPaths, dest)
@@ -524,7 +524,7 @@ func (b *Builder) create() (*daemon.Container, error) {
524524
if err != nil {
525525
return nil, err
526526
}
527-
defer c.Unmount()
527+
defer b.docker.Unmount(c)
528528
for _, warning := range warnings {
529529
fmt.Fprintf(b.Stdout, " ---> [Warning] %s\n", warning)
530530
}
@@ -549,7 +549,7 @@ func (b *Builder) run(c *daemon.Container) error {
549549
}
550550

551551
//start the container
552-
if err := c.Start(); err != nil {
552+
if err := b.docker.Start(c); err != nil {
553553
return err
554554
}
555555

daemon/archive.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, err
3030
res = res[1:]
3131
}
3232

33-
return container.copy(res)
33+
return daemon.containerCopy(container, res)
3434
}
3535

3636
// ContainerStatPath stats the filesystem resource at the specified path in the
@@ -41,7 +41,7 @@ func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.C
4141
return nil, err
4242
}
4343

44-
return container.StatPath(path)
44+
return daemon.containerStatPath(container, path)
4545
}
4646

4747
// ContainerArchivePath creates an archive of the filesystem resource at the
@@ -53,7 +53,7 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io
5353
return nil, nil, err
5454
}
5555

56-
return container.ArchivePath(path)
56+
return daemon.containerArchivePath(container, path)
5757
}
5858

5959
// ContainerExtractToDir extracts the given archive to the specified location
@@ -68,7 +68,7 @@ func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNon
6868
return err
6969
}
7070

71-
return container.ExtractToDir(path, noOverwriteDirNonDir, content)
71+
return daemon.containerExtractToDir(container, path, noOverwriteDirNonDir, content)
7272
}
7373

7474
// resolvePath resolves the given path in the container to a resource on the
@@ -131,16 +131,16 @@ func (container *Container) statPath(resolvedPath, absPath string) (stat *types.
131131
}, nil
132132
}
133133

134-
// StatPath stats the filesystem resource at the specified path in this
134+
// containerStatPath stats the filesystem resource at the specified path in this
135135
// container. Returns stat info about the resource.
136-
func (container *Container) StatPath(path string) (stat *types.ContainerPathStat, err error) {
136+
func (daemon *Daemon) containerStatPath(container *Container, path string) (stat *types.ContainerPathStat, err error) {
137137
container.Lock()
138138
defer container.Unlock()
139139

140-
if err = container.Mount(); err != nil {
140+
if err = daemon.Mount(container); err != nil {
141141
return nil, err
142142
}
143-
defer container.Unmount()
143+
defer daemon.Unmount(container)
144144

145145
err = container.mountVolumes()
146146
defer container.unmountVolumes(true)
@@ -156,10 +156,10 @@ func (container *Container) StatPath(path string) (stat *types.ContainerPathStat
156156
return container.statPath(resolvedPath, absPath)
157157
}
158158

159-
// ArchivePath creates an archive of the filesystem resource at the specified
159+
// containerArchivePath creates an archive of the filesystem resource at the specified
160160
// path in this container. Returns a tar archive of the resource and stat info
161161
// about the resource.
162-
func (container *Container) ArchivePath(path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
162+
func (daemon *Daemon) containerArchivePath(container *Container, path string) (content io.ReadCloser, stat *types.ContainerPathStat, err error) {
163163
container.Lock()
164164

165165
defer func() {
@@ -171,7 +171,7 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
171171
}
172172
}()
173173

174-
if err = container.Mount(); err != nil {
174+
if err = daemon.Mount(container); err != nil {
175175
return nil, nil, err
176176
}
177177

@@ -180,7 +180,7 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
180180
// unmount any volumes
181181
container.unmountVolumes(true)
182182
// unmount the container's rootfs
183-
container.Unmount()
183+
daemon.Unmount(container)
184184
}
185185
}()
186186

@@ -214,7 +214,7 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
214214
content = ioutils.NewReadCloserWrapper(data, func() error {
215215
err := data.Close()
216216
container.unmountVolumes(true)
217-
container.Unmount()
217+
daemon.Unmount(container)
218218
container.Unlock()
219219
return err
220220
})
@@ -224,20 +224,20 @@ func (container *Container) ArchivePath(path string) (content io.ReadCloser, sta
224224
return content, stat, nil
225225
}
226226

227-
// ExtractToDir extracts the given tar archive to the specified location in the
227+
// containerExtractToDir extracts the given tar archive to the specified location in the
228228
// filesystem of this container. The given path must be of a directory in the
229229
// container. If it is not, the error will be ErrExtractPointNotDirectory. If
230230
// noOverwriteDirNonDir is true then it will be an error if unpacking the
231231
// given content would cause an existing directory to be replaced with a non-
232232
// directory and vice versa.
233-
func (container *Container) ExtractToDir(path string, noOverwriteDirNonDir bool, content io.Reader) (err error) {
233+
func (daemon *Daemon) containerExtractToDir(container *Container, path string, noOverwriteDirNonDir bool, content io.Reader) (err error) {
234234
container.Lock()
235235
defer container.Unlock()
236236

237-
if err = container.Mount(); err != nil {
237+
if err = daemon.Mount(container); err != nil {
238238
return err
239239
}
240-
defer container.Unmount()
240+
defer daemon.Unmount(container)
241241

242242
err = container.mountVolumes()
243243
defer container.unmountVolumes(true)

daemon/container.go

Lines changed: 6 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -225,76 +225,6 @@ func (container *Container) getRootResourcePath(path string) (string, error) {
225225
return symlink.FollowSymlinkInScope(filepath.Join(container.root, cleanPath), container.root)
226226
}
227227

228-
// Start prepares the container to run by setting up everything the
229-
// container needs, such as storage and networking, as well as links
230-
// between containers. The container is left waiting for a signal to
231-
// begin running.
232-
func (container *Container) Start() (err error) {
233-
container.Lock()
234-
defer container.Unlock()
235-
236-
if container.Running {
237-
return nil
238-
}
239-
240-
if container.removalInProgress || container.Dead {
241-
return derr.ErrorCodeContainerBeingRemoved
242-
}
243-
244-
// if we encounter an error during start we need to ensure that any other
245-
// setup has been cleaned up properly
246-
defer func() {
247-
if err != nil {
248-
container.setError(err)
249-
// if no one else has set it, make sure we don't leave it at zero
250-
if container.ExitCode == 0 {
251-
container.ExitCode = 128
252-
}
253-
container.toDisk()
254-
container.cleanup()
255-
container.logEvent("die")
256-
}
257-
}()
258-
259-
if err := container.conditionalMountOnStart(); err != nil {
260-
return err
261-
}
262-
263-
// Make sure NetworkMode has an acceptable value. We do this to ensure
264-
// backwards API compatibility.
265-
container.hostConfig = runconfig.SetDefaultNetModeIfBlank(container.hostConfig)
266-
267-
if err := container.initializeNetworking(); err != nil {
268-
return err
269-
}
270-
linkedEnv, err := container.setupLinkedContainers()
271-
if err != nil {
272-
return err
273-
}
274-
if err := container.setupWorkingDirectory(); err != nil {
275-
return err
276-
}
277-
env := container.createDaemonEnvironment(linkedEnv)
278-
if err := populateCommand(container, env); err != nil {
279-
return err
280-
}
281-
282-
if !container.hostConfig.IpcMode.IsContainer() && !container.hostConfig.IpcMode.IsHost() {
283-
if err := container.setupIpcDirs(); err != nil {
284-
return err
285-
}
286-
}
287-
288-
mounts, err := container.setupMounts()
289-
if err != nil {
290-
return err
291-
}
292-
mounts = append(mounts, container.ipcMounts()...)
293-
294-
container.command.Mounts = mounts
295-
return container.waitForStart()
296-
}
297-
298228
// streamConfig.StdinPipe returns a WriteCloser which can be used to feed data
299229
// to the standard input of the container's active process.
300230
// Container.StdoutPipe and Container.StderrPipe each return a ReadCloser
@@ -326,7 +256,7 @@ func (container *Container) cleanup() {
326256

327257
container.unmountIpcMounts(detachMounted)
328258

329-
container.conditionalUnmountOnCleanup()
259+
container.daemon.conditionalUnmountOnCleanup(container)
330260

331261
for _, eConfig := range container.execCommands.s {
332262
container.daemon.unregisterExecCommand(eConfig)
@@ -356,11 +286,6 @@ func (container *Container) Resize(h, w int) error {
356286
return nil
357287
}
358288

359-
// Mount sets container.basefs
360-
func (container *Container) Mount() error {
361-
return container.daemon.Mount(container)
362-
}
363-
364289
func (container *Container) changes() ([]archive.Change, error) {
365290
container.Lock()
366291
defer container.Unlock()
@@ -374,12 +299,6 @@ func (container *Container) getImage() (*image.Image, error) {
374299
return container.daemon.graph.Get(container.ImageID)
375300
}
376301

377-
// Unmount asks the daemon to release the layered filesystems that are
378-
// mounted by the container.
379-
func (container *Container) Unmount() error {
380-
return container.daemon.unmount(container)
381-
}
382-
383302
func (container *Container) hostConfigPath() (string, error) {
384303
return container.getRootResourcePath("hostconfig.json")
385304
}
@@ -401,7 +320,7 @@ func validateID(id string) error {
401320
return nil
402321
}
403322

404-
func (container *Container) copy(resource string) (rc io.ReadCloser, err error) {
323+
func (daemon *Daemon) containerCopy(container *Container, resource string) (rc io.ReadCloser, err error) {
405324
container.Lock()
406325

407326
defer func() {
@@ -413,7 +332,7 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
413332
}
414333
}()
415334

416-
if err := container.Mount(); err != nil {
335+
if err := daemon.Mount(container); err != nil {
417336
return nil, err
418337
}
419338

@@ -422,7 +341,7 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
422341
// unmount any volumes
423342
container.unmountVolumes(true)
424343
// unmount the container's rootfs
425-
container.Unmount()
344+
daemon.Unmount(container)
426345
}
427346
}()
428347

@@ -458,11 +377,11 @@ func (container *Container) copy(resource string) (rc io.ReadCloser, err error)
458377
reader := ioutils.NewReadCloserWrapper(archive, func() error {
459378
err := archive.Close()
460379
container.unmountVolumes(true)
461-
container.Unmount()
380+
daemon.Unmount(container)
462381
container.Unlock()
463382
return err
464383
})
465-
container.logEvent("copy")
384+
daemon.logContainerEvent(container, "copy")
466385
return reader, nil
467386
}
468387

daemon/container_unix.go

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -379,24 +379,23 @@ func mergeDevices(defaultDevices, userDevices []*configs.Device) []*configs.Devi
379379
return append(devs, userDevices...)
380380
}
381381

382-
// GetSize returns the real size & virtual size of the container.
383-
func (container *Container) getSize() (int64, int64) {
382+
// getSize returns the real size & virtual size of the container.
383+
func (daemon *Daemon) getSize(container *Container) (int64, int64) {
384384
var (
385385
sizeRw, sizeRootfs int64
386386
err error
387-
driver = container.daemon.driver
388387
)
389388

390-
if err := container.Mount(); err != nil {
389+
if err := daemon.Mount(container); err != nil {
391390
logrus.Errorf("Failed to compute size of container rootfs %s: %s", container.ID, err)
392391
return sizeRw, sizeRootfs
393392
}
394-
defer container.Unmount()
393+
defer daemon.Unmount(container)
395394

396395
initID := fmt.Sprintf("%s-init", container.ID)
397-
sizeRw, err = driver.DiffSize(container.ID, initID)
396+
sizeRw, err = daemon.driver.DiffSize(container.ID, initID)
398397
if err != nil {
399-
logrus.Errorf("Driver %s couldn't return diff size of container %s: %s", driver, container.ID, err)
398+
logrus.Errorf("Driver %s couldn't return diff size of container %s: %s", daemon.driver, container.ID, err)
400399
// FIXME: GetSize should return an error. Not changing it now in case
401400
// there is a side-effect.
402401
sizeRw = -1
@@ -1444,20 +1443,3 @@ func (container *Container) ipcMounts() []execdriver.Mount {
14441443
func detachMounted(path string) error {
14451444
return syscall.Unmount(path, syscall.MNT_DETACH)
14461445
}
1447-
1448-
// conditionalMountOnStart is a platform specific helper function during the
1449-
// container start to call mount.
1450-
func (container *Container) conditionalMountOnStart() error {
1451-
if err := container.Mount(); err != nil {
1452-
return err
1453-
}
1454-
return nil
1455-
}
1456-
1457-
// conditionalUnmountOnCleanup is a platform specific helper function called
1458-
// during the cleanup of a container to unmount.
1459-
func (container *Container) conditionalUnmountOnCleanup() {
1460-
if err := container.Unmount(); err != nil {
1461-
logrus.Errorf("%v: Failed to umount filesystem: %v", container.ID, err)
1462-
}
1463-
}

0 commit comments

Comments
 (0)