moby/daemon/containerd/mount.go
Paweł Gronowski 203bac0ec4
daemon/c8d: Unmount container fs after unclean shutdown
BaseFS is not serialized and is lost after an unclean shutdown. Unmount
method in the containerd image service implementation will not work
correctly in that case.
This patch will allow Unmount to restore the BaseFS if the target is
still mounted.

The reason it works with graphdrivers is that it doesn't directly
operate on BaseFS. It uses RWLayer, which is explicitly restored
immediately as soon as container is loaded.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2023-11-27 12:33:33 +01:00

52 lines
1.5 KiB
Go

package containerd
import (
"context"
"errors"
"fmt"
"github.com/containerd/log"
"github.com/docker/docker/container"
)
// Mount mounts the container filesystem in a temporary location, use defer imageService.Unmount
// to unmount the filesystem when calling this
func (i *ImageService) Mount(ctx context.Context, container *container.Container) error {
snapshotter := i.client.SnapshotService(container.Driver)
mounts, err := snapshotter.Mounts(ctx, container.ID)
if err != nil {
return err
}
var root string
if root, err = i.refCountMounter.Mount(mounts, container.ID); err != nil {
return fmt.Errorf("failed to mount %s: %w", root, err)
}
log.G(ctx).WithField("container", container.ID).Debugf("container mounted via snapshotter: %v", root)
container.BaseFS = root
return nil
}
// Unmount unmounts the container base filesystem
func (i *ImageService) Unmount(ctx context.Context, container *container.Container) error {
baseFS := container.BaseFS
if baseFS == "" {
target, err := i.refCountMounter.Mounted(container.ID)
if err != nil {
log.G(ctx).WithField("containerID", container.ID).Warn("failed to determine if container is already mounted")
}
if target == "" {
return errors.New("BaseFS is empty")
}
baseFS = target
}
if err := i.refCountMounter.Unmount(baseFS); err != nil {
log.G(ctx).WithField("container", container.ID).WithError(err).Error("error unmounting container")
return fmt.Errorf("failed to unmount %s: %w", baseFS, err)
}
return nil
}