mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Don’t hold container lock for size calculation
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
parent
cf5fe9ed0b
commit
bd33a99acf
6 changed files with 39 additions and 33 deletions
|
@ -12,7 +12,7 @@ func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]s
|
|||
}
|
||||
|
||||
// getSize returns real size & virtual size
|
||||
func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
||||
func (daemon *Daemon) getSize(containerID string) (int64, int64) {
|
||||
// TODO Windows
|
||||
return 0, 0
|
||||
}
|
||||
|
|
|
@ -4,32 +4,32 @@ package daemon
|
|||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/container"
|
||||
)
|
||||
|
||||
// getSize returns the real size & virtual size of the container.
|
||||
func (daemon *Daemon) getSize(container *container.Container) (int64, int64) {
|
||||
func (daemon *Daemon) getSize(containerID string) (int64, int64) {
|
||||
var (
|
||||
sizeRw, sizeRootfs int64
|
||||
err error
|
||||
)
|
||||
|
||||
if err := daemon.Mount(container); err != nil {
|
||||
logrus.Errorf("Failed to compute size of container rootfs %s: %s", container.ID, err)
|
||||
rwlayer, err := daemon.layerStore.GetRWLayer(containerID)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to compute size of container rootfs %v: %v", containerID, err)
|
||||
return sizeRw, sizeRootfs
|
||||
}
|
||||
defer daemon.Unmount(container)
|
||||
defer daemon.layerStore.ReleaseRWLayer(rwlayer)
|
||||
|
||||
sizeRw, err = container.RWLayer.Size()
|
||||
sizeRw, err = rwlayer.Size()
|
||||
if err != nil {
|
||||
logrus.Errorf("Driver %s couldn't return diff size of container %s: %s",
|
||||
daemon.GraphDriverName(), container.ID, err)
|
||||
daemon.GraphDriverName(), containerID, err)
|
||||
// FIXME: GetSize should return an error. Not changing it now in case
|
||||
// there is a side-effect.
|
||||
sizeRw = -1
|
||||
}
|
||||
|
||||
if parent := container.RWLayer.Parent(); parent != nil {
|
||||
if parent := rwlayer.Parent(); parent != nil {
|
||||
sizeRootfs, err = parent.Size()
|
||||
if err != nil {
|
||||
sizeRootfs = -1
|
||||
|
|
|
@ -36,10 +36,10 @@ func (daemon *Daemon) ContainerInspectCurrent(name string, size bool) (*types.Co
|
|||
}
|
||||
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
base, err := daemon.getInspectData(container, size)
|
||||
base, err := daemon.getInspectData(container)
|
||||
if err != nil {
|
||||
container.Unlock()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,14 @@ func (daemon *Daemon) ContainerInspectCurrent(name string, size bool) (*types.Co
|
|||
}
|
||||
networkSettings.NetworkSettingsBase.Ports = ports
|
||||
|
||||
container.Unlock()
|
||||
|
||||
if size {
|
||||
sizeRw, sizeRootFs := daemon.getSize(base.ID)
|
||||
base.SizeRw = &sizeRw
|
||||
base.SizeRootFs = &sizeRootFs
|
||||
}
|
||||
|
||||
return &types.ContainerJSON{
|
||||
ContainerJSONBase: base,
|
||||
Mounts: mountPoints,
|
||||
|
@ -91,7 +99,7 @@ func (daemon *Daemon) containerInspect120(name string) (*v1p20.ContainerJSON, er
|
|||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
base, err := daemon.getInspectData(container, false)
|
||||
base, err := daemon.getInspectData(container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -114,7 +122,7 @@ func (daemon *Daemon) containerInspect120(name string) (*v1p20.ContainerJSON, er
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) getInspectData(container *container.Container, size bool) (*types.ContainerJSONBase, error) {
|
||||
func (daemon *Daemon) getInspectData(container *container.Container) (*types.ContainerJSONBase, error) {
|
||||
// make a copy to play with
|
||||
hostConfig := *container.HostConfig
|
||||
|
||||
|
@ -168,16 +176,6 @@ func (daemon *Daemon) getInspectData(container *container.Container, size bool)
|
|||
HostConfig: &hostConfig,
|
||||
}
|
||||
|
||||
var (
|
||||
sizeRw int64
|
||||
sizeRootFs int64
|
||||
)
|
||||
if size {
|
||||
sizeRw, sizeRootFs = daemon.getSize(container)
|
||||
contJSONBase.SizeRw = &sizeRw
|
||||
contJSONBase.SizeRootFs = &sizeRootFs
|
||||
}
|
||||
|
||||
// Now set any platform-specific fields
|
||||
contJSONBase = setPlatformSpecificContainerFields(container, contJSONBase)
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ func (daemon *Daemon) containerInspectPre120(name string) (*v1p19.ContainerJSON,
|
|||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
base, err := daemon.getInspectData(container, false)
|
||||
base, err := daemon.getInspectData(container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -208,19 +208,32 @@ func (daemon *Daemon) reduceContainers(config *types.ContainerListOptions, reduc
|
|||
// reducePsContainer is the basic representation for a container as expected by the ps command.
|
||||
func (daemon *Daemon) reducePsContainer(container *container.Container, ctx *listContext, reducer containerReducer) (*types.Container, error) {
|
||||
container.Lock()
|
||||
defer container.Unlock()
|
||||
|
||||
// filter containers to return
|
||||
action := includeContainerInList(container, ctx)
|
||||
switch action {
|
||||
case excludeContainer:
|
||||
container.Unlock()
|
||||
return nil, nil
|
||||
case stopIteration:
|
||||
container.Unlock()
|
||||
return nil, errStopIteration
|
||||
}
|
||||
|
||||
// transform internal container struct into api structs
|
||||
return reducer(container, ctx)
|
||||
newC, err := reducer(container, ctx)
|
||||
container.Unlock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// release lock because size calculation is slow
|
||||
if ctx.Size {
|
||||
sizeRw, sizeRootFs := daemon.getSize(newC.ID)
|
||||
newC.SizeRw = sizeRw
|
||||
newC.SizeRootFs = sizeRootFs
|
||||
}
|
||||
return newC, nil
|
||||
}
|
||||
|
||||
// foldFilter generates the container filter based on the user's filtering options.
|
||||
|
@ -642,11 +655,6 @@ func (daemon *Daemon) transformContainer(container *container.Container, ctx *li
|
|||
}
|
||||
}
|
||||
|
||||
if ctx.Size {
|
||||
sizeRw, sizeRootFs := daemon.getSize(container)
|
||||
newC.SizeRw = sizeRw
|
||||
newC.SizeRootFs = sizeRootFs
|
||||
}
|
||||
newC.Labels = container.Config.Labels
|
||||
newC.Mounts = addMountPoints(container)
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/docker/docker/runconfig"
|
||||
"github.com/docker/docker/volume"
|
||||
"github.com/docker/libnetwork"
|
||||
"github.com/opencontainers/go-digest"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// ContainersPrune removes unused containers
|
||||
|
@ -34,7 +34,7 @@ func (daemon *Daemon) ContainersPrune(pruneFilters filters.Args) (*types.Contain
|
|||
if !until.IsZero() && c.Created.After(until) {
|
||||
continue
|
||||
}
|
||||
cSize, _ := daemon.getSize(c)
|
||||
cSize, _ := daemon.getSize(c.ID)
|
||||
// TODO: sets RmLink to true?
|
||||
err := daemon.ContainerRm(c.ID, &types.ContainerRmConfig{})
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue