Merge pull request #13186 from erofs/walking_differ

diff/walking: enable mount manager
This commit is contained in:
Derek McGowan
2026-04-09 15:35:08 +00:00
committed by GitHub
2 changed files with 41 additions and 1 deletions

View File

@@ -18,6 +18,8 @@ package apply
import (
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"time"
@@ -25,6 +27,7 @@ import (
"github.com/containerd/containerd/v2/core/content"
"github.com/containerd/containerd/v2/core/diff"
"github.com/containerd/containerd/v2/core/mount"
"github.com/containerd/errdefs"
"github.com/containerd/log"
digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -33,13 +36,22 @@ import (
// NewFileSystemApplier returns an applier which simply mounts
// and applies diff onto the mounted filesystem.
func NewFileSystemApplier(cs content.Provider) diff.Applier {
return NewFileSystemApplierWithMountManager(cs, nil)
}
// NewFileSystemApplierWithMountManager returns an applier which simply mounts and
// applies diff onto the mounted filesystem.
// An optional mount manager can be specified and it will take effect when applying.
func NewFileSystemApplierWithMountManager(cs content.Provider, mm mount.Manager) diff.Applier {
return &fsApplier{
store: cs,
mount: mm,
}
}
type fsApplier struct {
store content.Provider
mount mount.Manager
}
var emptyDesc = ocispec.Descriptor{}
@@ -98,6 +110,23 @@ func (s *fsApplier) Apply(ctx context.Context, desc ocispec.Descriptor, mounts [
r: io.TeeReader(processor, digester.Hash()),
}
// The number of `mounts` that need to be parsed by the mount manager
// will be more than 1 in reality; this is needed to work around some
// overlayfs/bind shortcuts in core/diff/apply/apply_linux.go
if s.mount != nil && len(mounts) > 1 {
var b [3]byte
// Ignore read failures, just decreases uniqueness
rand.Read(b[:])
id := fmt.Sprintf("fs-diffapply-%d-%s", t1.Nanosecond(), base64.URLEncoding.EncodeToString(b[:]))
info, err := s.mount.Activate(ctx, id, mounts)
if err == nil {
defer s.mount.Deactivate(ctx, id)
mounts = info.System
} else if !errdefs.IsNotImplemented(err) {
return emptyDesc, fmt.Errorf("failed to activate mounts: %w", err)
}
}
if err := apply(ctx, mounts, rc, config.SyncFs); err != nil {
return emptyDesc, err
}