Refactor RWLayer to use referenced object instead of string

RWLayer will now have more operations and be protected through a referenced type rather than always looked up by string in the layer store.
Separates creation of RWLayer (write capture layer) from mounting of the layer.
This allows mount labels to be applied after creation and allowing RWLayer objects to have the same lifespan as a container without performance regressions from requiring mount.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Upstream-commit: d04fa49a0dec89d2f71a813ce8eaa182184139c5
Component: engine
This commit is contained in:
Derek McGowan
2015-12-23 11:19:17 -08:00
parent 60c9e9b1c7
commit 64820f351d
18 changed files with 427 additions and 275 deletions
+1 -1
View File
@@ -145,7 +145,7 @@ func (daemon *Daemon) exportContainerRw(container *container.Container) (archive
}
return ioutils.NewReadCloserWrapper(archive, func() error {
archive.Close()
return daemon.layerStore.Unmount(container.ID)
return container.RWLayer.Unmount()
}),
nil
}
@@ -98,7 +98,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
}
}
m, err := daemon.layerStore.Metadata(c.ID)
m, err := c.RWLayer.Metadata()
if err != nil {
return derr.ErrorCodeGetLayerMetadata.WithArgs(err)
}
+24
View File
@@ -7,6 +7,7 @@ import (
"github.com/docker/docker/container"
derr "github.com/docker/docker/errors"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/volume"
@@ -95,6 +96,11 @@ 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
}
@@ -126,6 +132,24 @@ func (daemon *Daemon) generateSecurityOpt(ipcMode containertypes.IpcMode, pidMod
return nil, nil
}
func (daemon *Daemon) setRWLayer(container *container.Container) error {
var layerID layer.ChainID
if container.ImageID != "" {
img, err := daemon.imageStore.Get(container.ImageID)
if err != nil {
return err
}
layerID = img.RootFS.ChainID()
}
rwLayer, err := daemon.layerStore.CreateRWLayer(container.ID, layerID, container.MountLabel, daemon.setupInitLayer)
if err != nil {
return err
}
container.RWLayer = rwLayer
return nil
}
// VolumeCreate creates a volume with the specified name, driver, and opts
// This is called directly from the remote API
func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]string) (*types.Volume, error) {
+10 -16
View File
@@ -323,6 +323,13 @@ func (daemon *Daemon) restore() error {
continue
}
rwlayer, err := daemon.layerStore.GetRWLayer(container.ID)
if err != nil {
logrus.Errorf("Failed to load container mount %v: %v", id, err)
continue
}
container.RWLayer = rwlayer
// Ignore the container if it does not support the current driver being used by the graph
if (container.Driver == "" && currentDriver == "aufs") || container.Driver == currentDriver {
logrus.Debugf("Loaded container %v", container.ID)
@@ -961,19 +968,7 @@ func (daemon *Daemon) Shutdown() error {
// Mount sets container.BaseFS
// (is it not set coming in? why is it unset?)
func (daemon *Daemon) Mount(container *container.Container) error {
var layerID layer.ChainID
if container.ImageID != "" {
img, err := daemon.imageStore.Get(container.ImageID)
if err != nil {
return err
}
layerID = img.RootFS.ChainID()
}
rwlayer, err := daemon.layerStore.Mount(container.ID, layerID, container.GetMountLabel(), daemon.setupInitLayer)
if err != nil {
return err
}
dir, err := rwlayer.Path()
dir, err := container.RWLayer.Mount(container.GetMountLabel())
if err != nil {
return err
}
@@ -990,13 +985,12 @@ func (daemon *Daemon) Mount(container *container.Container) error {
}
}
container.BaseFS = dir // TODO: combine these fields
container.RWLayer = rwlayer
return nil
}
// Unmount unsets the container base filesystem
func (daemon *Daemon) Unmount(container *container.Container) {
if err := daemon.layerStore.Unmount(container.ID); err != nil {
if err := container.RWLayer.Unmount(); err != nil {
logrus.Errorf("Error unmounting container %s: %s", container.ID, err)
}
}
@@ -1029,7 +1023,7 @@ func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch cha
}
func (daemon *Daemon) changes(container *container.Container) ([]archive.Change, error) {
return daemon.layerStore.Changes(container.ID)
return container.RWLayer.Changes()
}
// TagImage creates a tag in the repository reponame, pointing to the image named
+1 -1
View File
@@ -130,7 +130,7 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
return derr.ErrorCodeRmFS.WithArgs(container.ID, err)
}
metadata, err := daemon.layerStore.DeleteMount(container.ID)
metadata, err := daemon.layerStore.ReleaseRWLayer(container.RWLayer)
layer.LogReleaseMetadata(metadata)
if err != nil && err != layer.ErrMountDoesNotExist {
return derr.ErrorCodeRmDriverFS.WithArgs(daemon.driver, container.ID, err)
+1 -1
View File
@@ -163,7 +163,7 @@ func (daemon *Daemon) getInspectData(container *container.Container, size bool)
contJSONBase.GraphDriver.Name = container.Driver
graphDriverData, err := daemon.layerStore.Metadata(container.ID)
graphDriverData, err := container.RWLayer.Metadata()
if err != nil {
return nil, err
}