Skip to content

Commit 409f75b

Browse files
hsiangkaok8s-infra-cherrypick-robot
authored andcommitted
diff/walking: enable mount manager
The default walking applier performs a real temporary mount for unpacking, but the mount manager failed to adapt to the walking differ. This fixes the EROFS snapshotter together with the default walking differ, otherwise it reports: ``` ctr: apply layer error for "[]": failed to extract layer sha256:[]: failed to mount /var/lib/containerd/tmpmounts/containerd-mount3992073457: internal mount option "X-containerd.mkfs.fs=ext4" was not consumed by the mount manager ``` Signed-off-by: Gao Xiang <[email protected]>
1 parent 33e9334 commit 409f75b

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

core/diff/apply/apply.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ package apply
1818

1919
import (
2020
"context"
21+
"crypto/rand"
22+
"encoding/base64"
2123
"fmt"
2224
"io"
2325
"time"
2426

2527
"github.com/containerd/containerd/v2/core/content"
2628
"github.com/containerd/containerd/v2/core/diff"
2729
"github.com/containerd/containerd/v2/core/mount"
30+
"github.com/containerd/errdefs"
2831
"github.com/containerd/log"
2932
digest "github.com/opencontainers/go-digest"
3033
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -33,13 +36,22 @@ import (
3336
// NewFileSystemApplier returns an applier which simply mounts
3437
// and applies diff onto the mounted filesystem.
3538
func NewFileSystemApplier(cs content.Provider) diff.Applier {
39+
return NewFileSystemApplierWithMountManager(cs, nil)
40+
}
41+
42+
// NewFileSystemApplierWithMountManager returns an applier which simply mounts and
43+
// applies diff onto the mounted filesystem.
44+
// An optional mount manager can be specified and it will take effect when applying.
45+
func NewFileSystemApplierWithMountManager(cs content.Provider, mm mount.Manager) diff.Applier {
3646
return &fsApplier{
3747
store: cs,
48+
mount: mm,
3849
}
3950
}
4051

4152
type fsApplier struct {
4253
store content.Provider
54+
mount mount.Manager
4355
}
4456

4557
var emptyDesc = ocispec.Descriptor{}
@@ -98,6 +110,23 @@ func (s *fsApplier) Apply(ctx context.Context, desc ocispec.Descriptor, mounts [
98110
r: io.TeeReader(processor, digester.Hash()),
99111
}
100112

113+
// The number of `mounts` that need to be parsed by the mount manager
114+
// will be more than 1 in reality; this is needed to work around some
115+
// overlayfs/bind shortcuts in core/diff/apply/apply_linux.go
116+
if s.mount != nil && len(mounts) > 1 {
117+
var b [3]byte
118+
// Ignore read failures, just decreases uniqueness
119+
rand.Read(b[:])
120+
id := fmt.Sprintf("fs-diffapply-%d-%s", t1.Nanosecond(), base64.URLEncoding.EncodeToString(b[:]))
121+
info, err := s.mount.Activate(ctx, id, mounts)
122+
if err == nil {
123+
defer s.mount.Deactivate(ctx, id)
124+
mounts = info.System
125+
} else if !errdefs.IsNotImplemented(err) {
126+
return emptyDesc, fmt.Errorf("failed to activate mounts: %w", err)
127+
}
128+
}
129+
101130
if err := apply(ctx, mounts, rc, config.SyncFs); err != nil {
102131
return emptyDesc, err
103132
}

plugins/diff/walking/plugin/plugin.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
package plugin
1818

1919
import (
20+
"errors"
21+
2022
"github.com/containerd/containerd/v2/core/diff"
2123
"github.com/containerd/containerd/v2/core/diff/apply"
2224
"github.com/containerd/containerd/v2/core/metadata"
25+
"github.com/containerd/containerd/v2/core/mount"
2326
"github.com/containerd/containerd/v2/plugins"
2427
"github.com/containerd/containerd/v2/plugins/diff/walking"
2528
"github.com/containerd/platforms"
@@ -33,19 +36,27 @@ func init() {
3336
ID: "walking",
3437
Requires: []plugin.Type{
3538
plugins.MetadataPlugin,
39+
plugins.MountManagerPlugin,
3640
},
3741
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
3842
md, err := ic.GetSingle(plugins.MetadataPlugin)
3943
if err != nil {
4044
return nil, err
4145
}
4246

47+
var mm mount.Manager
48+
if mountsI, err := ic.GetSingle(plugins.MountManagerPlugin); err == nil {
49+
mm = mountsI.(mount.Manager)
50+
} else if !errors.Is(err, plugin.ErrPluginNotFound) {
51+
return nil, err
52+
}
53+
4354
ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec())
4455
cs := md.(*metadata.DB).ContentStore()
4556

4657
return diffPlugin{
4758
Comparer: walking.NewWalkingDiff(cs),
48-
Applier: apply.NewFileSystemApplier(cs),
59+
Applier: apply.NewFileSystemApplierWithMountManager(cs, mm),
4960
}, nil
5061
},
5162
})

0 commit comments

Comments
 (0)