mirror of
https://github.com/containerd/containerd.git
synced 2026-08-09 01:21:15 +00:00
snapshotter/erofs: avoid using overlay if fsmerge is enabled and no upperdir
If fsmerge is enabled and no write is needed, it can return an overlay
mount with a single lowerdir, which is illegal for overlayfs.
For example, it can cause the following Nerdctl error:
: I'm not sure why ctr works, but the issue is real.
```bash
$ nerdctl run --runtime io.containerd.kata.v2 --snapshotter=erofs -it --rm nginx:latest /bin/bash
FATA[0000] failed to mount {Type:overlay Source:overlay Target: Options:[lowerdir=/run/containerd/
io.containerd.mount-manager.v1.bolt/t/7/1]} on "/tmp/initialC2039543827": mount source: "overlay",
target: "/tmp/initialC2039543827", fstype: overlay, flags: 0, data: "lowerdir=/run/containerd/io.
containerd.mount-manager.v1.bolt/t/7/1", err: invalid argument
```
Switch to using a bind mount instead.
Fixes: 9a7500a974 ("Add support for EROFS fsmerge feature")
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
@@ -389,7 +389,10 @@ func (s *snapshotter) mounts(snap storage.Snapshot, info snapshots.Info) ([]moun
|
||||
}
|
||||
}
|
||||
|
||||
var mounts []mount.Mount
|
||||
var (
|
||||
mounts []mount.Mount
|
||||
writable bool
|
||||
)
|
||||
if snap.Kind == snapshots.KindActive {
|
||||
if s.blockMode {
|
||||
mounts = append(mounts, mount.Mount{
|
||||
@@ -416,6 +419,7 @@ func (s *snapshotter) mounts(snap storage.Snapshot, info snapshots.Info) ([]moun
|
||||
fmt.Sprintf("upperdir=%s", s.upperPath(snap.ID)),
|
||||
)
|
||||
}
|
||||
writable = true
|
||||
} else if len(snap.ParentIDs) == 1 {
|
||||
layerBlob, err := s.lowerPath(snap.ParentIDs[0])
|
||||
if err != nil {
|
||||
@@ -452,11 +456,6 @@ func (s *snapshotter) mounts(snap storage.Snapshot, info snapshots.Info) ([]moun
|
||||
|
||||
mounts = append(mounts, m)
|
||||
}
|
||||
if (len(mounts) - first) == 1 {
|
||||
options = append(options, fmt.Sprintf("lowerdir={{ mount %d }}", first))
|
||||
} else {
|
||||
options = append(options, fmt.Sprintf("lowerdir={{ overlay %d %d }}", first, len(mounts)-1))
|
||||
}
|
||||
|
||||
if s.remapIDs {
|
||||
if v, ok := info.Labels[snapshots.LabelSnapshotUIDMapping]; ok {
|
||||
@@ -467,6 +466,20 @@ func (s *snapshotter) mounts(snap storage.Snapshot, info snapshots.Info) ([]moun
|
||||
}
|
||||
}
|
||||
|
||||
if (len(mounts) - first) == 1 {
|
||||
// End up with one single lowerdir (e.g. fsmerge on):
|
||||
// it's unsupported by overlayfs
|
||||
if !writable {
|
||||
return append(mounts, mount.Mount{
|
||||
Type: "format/bind",
|
||||
Source: fmt.Sprintf("{{ mount %d }}", first),
|
||||
Options: append(options, "ro", "rbind"),
|
||||
}), nil
|
||||
}
|
||||
options = append(options, fmt.Sprintf("lowerdir={{ mount %d }}", first))
|
||||
} else {
|
||||
options = append(options, fmt.Sprintf("lowerdir={{ overlay %d %d }}", first, len(mounts)-1))
|
||||
}
|
||||
options = append(options, s.ovlOptions...)
|
||||
|
||||
return append(mounts, mount.Mount{
|
||||
|
||||
Reference in New Issue
Block a user