diff --git a/components/engine/daemon/build.go b/components/engine/daemon/build.go index 63006235f7..dd77e8c6f2 100644 --- a/components/engine/daemon/build.go +++ b/components/engine/daemon/build.go @@ -23,33 +23,58 @@ type releaseableLayer struct { } func (rl *releaseableLayer) Mount() (string, error) { + var err error + var mountPath string if rl.roLayer == nil { return "", errors.New("can not mount an image with no root FS") } - var err error mountID := stringid.GenerateRandomID() rl.rwLayer, err = rl.layerStore.CreateRWLayer(mountID, rl.roLayer.ChainID(), nil) if err != nil { return "", errors.Wrap(err, "failed to create rwlayer") } - return rl.rwLayer.Mount("") + mountPath, err = rl.rwLayer.Mount("") + if err != nil { + // Clean up the layer if we fail to mount it here. + metadata, err := rl.layerStore.ReleaseRWLayer(rl.rwLayer) + layer.LogReleaseMetadata(metadata) + if err != nil { + logrus.Errorf("Failed to release RWLayer: %s", err) + } + rl.rwLayer = nil + return "", err + } + + return mountPath, nil } func (rl *releaseableLayer) Release() error { - rl.releaseRWLayer() - return rl.releaseROLayer() + if err := rl.releaseRWLayer(); err != nil { + // Best effort attempt at releasing read-only layer before returning original error. + rl.releaseROLayer() + return err + } + if err := rl.releaseROLayer(); err != nil { + return err + } + return nil } func (rl *releaseableLayer) releaseRWLayer() error { if rl.rwLayer == nil { return nil } + if err := rl.rwLayer.Unmount(); err != nil { + logrus.Errorf("Failed to unmount RWLayer: %s", err) + return err + } metadata, err := rl.layerStore.ReleaseRWLayer(rl.rwLayer) layer.LogReleaseMetadata(metadata) if err != nil { logrus.Errorf("Failed to release RWLayer: %s", err) } + rl.rwLayer = nil return err } @@ -59,6 +84,10 @@ func (rl *releaseableLayer) releaseROLayer() error { } metadata, err := rl.layerStore.Release(rl.roLayer) layer.LogReleaseMetadata(metadata) + if err != nil { + logrus.Errorf("Failed to release ROLayer: %s", err) + } + rl.roLayer = nil return err }