Explorar el Código

Merge pull request #46770 from vvoland/c8d-unmount-empty-basefs

daemon/c8d: Unmount container fs after unclean shutdown
Paweł Gronowski hace 1 año
padre
commit
4cd2654a9d
Se han modificado 2 ficheros con 44 adiciones y 3 borrados
  1. 14 3
      daemon/containerd/mount.go
  2. 30 0
      daemon/snapshotter/mount.go

+ 14 - 3
daemon/containerd/mount.go

@@ -2,6 +2,7 @@ package containerd
 
 import (
 	"context"
+	"errors"
 	"fmt"
 
 	"github.com/containerd/log"
@@ -30,11 +31,21 @@ func (i *ImageService) Mount(ctx context.Context, container *container.Container
 
 // Unmount unmounts the container base filesystem
 func (i *ImageService) Unmount(ctx context.Context, container *container.Container) error {
-	root := container.BaseFS
+	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(root); err != nil {
+	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", root, err)
+		return fmt.Errorf("failed to unmount %s: %w", baseFS, err)
 	}
 
 	return nil

+ 30 - 0
daemon/snapshotter/mount.go

@@ -10,6 +10,7 @@ import (
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/moby/locker"
+	"github.com/moby/sys/mountinfo"
 )
 
 // List of known filesystems that can't be re-mounted or have shared layers
@@ -22,6 +23,8 @@ type Mounter interface {
 	Mount(mounts []mount.Mount, containerID string) (string, error)
 	// Unmount unmounts the container rootfs
 	Unmount(target string) error
+	// Mounted returns a target mountpoint if it's already mounted
+	Mounted(containerID string) (string, error)
 }
 
 // inSlice tests whether a string is contained in a slice of strings or not.
@@ -110,6 +113,23 @@ func (m *refCountMounter) Unmount(target string) error {
 	return nil
 }
 
+func (m *refCountMounter) Mounted(containerID string) (string, error) {
+	mounted, err := m.base.Mounted(containerID)
+	if err != nil || mounted == "" {
+		return mounted, err
+	}
+
+	target := m.base.target(containerID)
+
+	// Check if the refcount is non-zero.
+	m.rc.Increment(target)
+	if m.rc.Decrement(target) > 0 {
+		return mounted, nil
+	}
+
+	return "", nil
+}
+
 type mounter struct {
 	home        string
 	snapshotter string
@@ -137,6 +157,16 @@ func (m mounter) Unmount(target string) error {
 	return unmount(target)
 }
 
+func (m mounter) Mounted(containerID string) (string, error) {
+	target := m.target(containerID)
+
+	mounted, err := mountinfo.Mounted(target)
+	if err != nil || !mounted {
+		return "", err
+	}
+	return target, nil
+}
+
 func (m mounter) target(containerID string) string {
 	return filepath.Join(m.home, "rootfs", m.snapshotter, containerID)
 }