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:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user