mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Fixes #29654: take reference to RWLayer while committing/exporting
Take an extra reference to rwlayer while the container is being committed or exported to avoid the removal of that layer. Also add some checks before commit/export. Signed-off-by: Yuanhong Peng <pengyuanhong@huawei.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package daemon
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -133,6 +134,16 @@ func (daemon *Daemon) Commit(name string, c *backend.ContainerCommitConfig) (str
|
||||
return "", errors.Errorf("%+v does not support commit of a running container", runtime.GOOS)
|
||||
}
|
||||
|
||||
if container.IsDead() {
|
||||
err := fmt.Errorf("You cannot commit container %s which is Dead", container.ID)
|
||||
return "", stateConflictError{err}
|
||||
}
|
||||
|
||||
if container.IsRemovalInProgress() {
|
||||
err := fmt.Errorf("You cannot commit container %s which is being removed", container.ID)
|
||||
return "", stateConflictError{err}
|
||||
}
|
||||
|
||||
if c.Pause && !container.IsPaused() {
|
||||
daemon.containerPause(container)
|
||||
defer daemon.containerUnpause(container)
|
||||
@@ -234,19 +245,36 @@ func (daemon *Daemon) Commit(name string, c *backend.ContainerCommitConfig) (str
|
||||
return id.String(), nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) exportContainerRw(container *container.Container) (io.ReadCloser, error) {
|
||||
if err := daemon.Mount(container); err != nil {
|
||||
func (daemon *Daemon) exportContainerRw(container *container.Container) (arch io.ReadCloser, err error) {
|
||||
rwlayer, err := daemon.stores[container.Platform].layerStore.GetRWLayer(container.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
daemon.stores[container.Platform].layerStore.ReleaseRWLayer(rwlayer)
|
||||
}
|
||||
}()
|
||||
|
||||
// TODO: this mount call is not necessary as we assume that TarStream() should
|
||||
// mount the layer if needed. But the Diff() function for windows requests that
|
||||
// the layer should be mounted when calling it. So we reserve this mount call
|
||||
// until windows driver can implement Diff() interface correctly.
|
||||
_, err = rwlayer.Mount(container.GetMountLabel())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
archive, err := container.RWLayer.TarStream()
|
||||
archive, err := rwlayer.TarStream()
|
||||
if err != nil {
|
||||
daemon.Unmount(container) // logging is already handled in the `Unmount` function
|
||||
rwlayer.Unmount()
|
||||
return nil, err
|
||||
}
|
||||
return ioutils.NewReadCloserWrapper(archive, func() error {
|
||||
archive.Close()
|
||||
return container.RWLayer.Unmount()
|
||||
err = rwlayer.Unmount()
|
||||
daemon.stores[container.Platform].layerStore.ReleaseRWLayer(rwlayer)
|
||||
return err
|
||||
}),
|
||||
nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user