Support >= 128 layers in overlayfs snapshots
Auto-detect longest common dir in lowerdir option and compact it if the option size is hitting one page size. If does, Use chdir + CLONE to do mount thing to avoid hitting one page argument buffer in linux kernel mount. Signed-off-by: Wei Fu <fhfuwei@163.com>
This commit is contained in:
@@ -63,6 +63,8 @@ func SnapshotterSuite(t *testing.T, name string, snapshotterFn func(ctx context.
|
||||
t.Run("StatInWalk", makeTest(name, snapshotterFn, checkStatInWalk))
|
||||
t.Run("CloseTwice", makeTest(name, snapshotterFn, closeTwice))
|
||||
t.Run("RootPermission", makeTest(name, snapshotterFn, checkRootPermission))
|
||||
|
||||
t.Run("128LayersMount", makeTest(name, snapshotterFn, check128LayersMount))
|
||||
}
|
||||
|
||||
func makeTest(name string, snapshotterFn func(ctx context.Context, root string) (snapshots.Snapshotter, func() error, error), fn func(ctx context.Context, t *testing.T, snapshotter snapshots.Snapshotter, work string)) func(t *testing.T) {
|
||||
@@ -860,3 +862,94 @@ func checkRootPermission(ctx context.Context, t *testing.T, snapshotter snapshot
|
||||
t.Fatalf("expected 0755, got 0%o", mode)
|
||||
}
|
||||
}
|
||||
|
||||
func check128LayersMount(ctx context.Context, t *testing.T, snapshotter snapshots.Snapshotter, work string) {
|
||||
lowestApply := fstest.Apply(
|
||||
fstest.CreateFile("/bottom", []byte("way at the bottom\n"), 0777),
|
||||
fstest.CreateFile("/overwriteme", []byte("FIRST!\n"), 0777),
|
||||
fstest.CreateDir("/ADDHERE", 0755),
|
||||
fstest.CreateDir("/ONLYME", 0755),
|
||||
fstest.CreateFile("/ONLYME/bottom", []byte("bye!\n"), 0777),
|
||||
)
|
||||
|
||||
appliers := []fstest.Applier{lowestApply}
|
||||
for i := 1; i <= 127; i++ {
|
||||
appliers = append(appliers, fstest.Apply(
|
||||
fstest.CreateFile("/overwriteme", []byte(fmt.Sprintf("%d WAS HERE!\n", i)), 0777),
|
||||
fstest.CreateFile(fmt.Sprintf("/ADDHERE/file-%d", i), []byte("same\n"), 0755),
|
||||
fstest.RemoveAll("/ONLYME"),
|
||||
fstest.CreateDir("/ONLYME", 0755),
|
||||
fstest.CreateFile(fmt.Sprintf("/ONLYME/file-%d", i), []byte("only me!\n"), 0777),
|
||||
))
|
||||
}
|
||||
|
||||
flat := filepath.Join(work, "flat")
|
||||
if err := os.MkdirAll(flat, 0777); err != nil {
|
||||
t.Fatalf("failed to create flat dir(%s): %+v", flat, err)
|
||||
}
|
||||
|
||||
// NOTE: add gc labels to avoid snapshots get removed by gc...
|
||||
parent := ""
|
||||
for i, applier := range appliers {
|
||||
preparing := filepath.Join(work, fmt.Sprintf("prepare-layer-%d", i))
|
||||
if err := os.MkdirAll(preparing, 0777); err != nil {
|
||||
t.Fatalf("[layer %d] failed to create preparing dir(%s): %+v", i, preparing, err)
|
||||
}
|
||||
|
||||
mounts, err := snapshotter.Prepare(ctx, preparing, parent, opt)
|
||||
if err != nil {
|
||||
t.Fatalf("[layer %d] failed to get mount info: %+v", i, err)
|
||||
}
|
||||
|
||||
if err := mount.All(mounts, preparing); err != nil {
|
||||
t.Fatalf("[layer %d] failed to mount on the target(%s): %+v", i, preparing, err)
|
||||
}
|
||||
|
||||
if err := fstest.CheckDirectoryEqual(preparing, flat); err != nil {
|
||||
testutil.Unmount(t, preparing)
|
||||
t.Fatalf("[layer %d] preparing doesn't equal to flat before apply: %+v", i, err)
|
||||
}
|
||||
|
||||
if err := applier.Apply(flat); err != nil {
|
||||
testutil.Unmount(t, preparing)
|
||||
t.Fatalf("[layer %d] failed to apply on flat dir: %+v", i, err)
|
||||
}
|
||||
|
||||
if err = applier.Apply(preparing); err != nil {
|
||||
testutil.Unmount(t, preparing)
|
||||
t.Fatalf("[layer %d] failed to apply on preparing dir: %+v", i, err)
|
||||
}
|
||||
|
||||
if err := fstest.CheckDirectoryEqual(preparing, flat); err != nil {
|
||||
testutil.Unmount(t, preparing)
|
||||
t.Fatalf("[layer %d] preparing doesn't equal to flat after apply: %+v", i, err)
|
||||
}
|
||||
|
||||
testutil.Unmount(t, preparing)
|
||||
|
||||
parent = filepath.Join(work, fmt.Sprintf("committed-%d", i))
|
||||
if err := snapshotter.Commit(ctx, parent, preparing, opt); err != nil {
|
||||
t.Fatalf("[layer %d] failed to commit the preparing: %+v", i, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
view := filepath.Join(work, "fullview")
|
||||
if err := os.MkdirAll(view, 0777); err != nil {
|
||||
t.Fatalf("failed to create fullview dir(%s): %+v", view, err)
|
||||
}
|
||||
|
||||
mounts, err := snapshotter.View(ctx, view, parent, opt)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get view's mount info: %+v", err)
|
||||
}
|
||||
|
||||
if err := mount.All(mounts, view); err != nil {
|
||||
t.Fatalf("failed to mount on the target(%s): %+v", view, err)
|
||||
}
|
||||
defer testutil.Unmount(t, view)
|
||||
|
||||
if err := fstest.CheckDirectoryEqual(view, flat); err != nil {
|
||||
t.Fatalf("fullview should equal to flat: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user