From eeb88554ac9262eea2b96d0071fec00fc7e269fb Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Mon, 27 Feb 2017 13:21:20 -0800 Subject: [PATCH] snapshot/overlay: use readonly bindmount for single parent view Signed-off-by: Derek McGowan (github: dmcgowan) --- snapshot/overlay/overlay.go | 11 +++++++++ snapshot/overlay/overlay_test.go | 41 +++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/snapshot/overlay/overlay.go b/snapshot/overlay/overlay.go index 588aec2..533824a 100644 --- a/snapshot/overlay/overlay.go +++ b/snapshot/overlay/overlay.go @@ -330,6 +330,17 @@ func (a *activeDir) mounts(c *cache) ([]containerd.Mount, error) { ) } else if !os.IsNotExist(err) { return nil, err + } else if len(parents) == 1 { + return []containerd.Mount{ + { + Source: parents[0], + Type: "bind", + Options: []string{ + "ro", + "rbind", + }, + }, + }, nil } options = append(options, fmt.Sprintf("lowerdir=%s", strings.Join(parents, ":"))) diff --git a/snapshot/overlay/overlay_test.go b/snapshot/overlay/overlay_test.go index 3a19d68..4bd594a 100644 --- a/snapshot/overlay/overlay_test.go +++ b/snapshot/overlay/overlay_test.go @@ -209,7 +209,7 @@ func TestOverlayView(t *testing.T) { if err != nil { t.Fatal(err) } - key := "/tmp/test" + key := "/tmp/base" mounts, err := o.Prepare(ctx, key, "") if err != nil { t.Fatal(err) @@ -221,7 +221,42 @@ func TestOverlayView(t *testing.T) { if err := o.Commit(ctx, "base", key); err != nil { t.Fatal(err) } - mounts, err = o.View(ctx, "/tmp/test2", "base") + + key = "/tmp/top" + _, err = o.Prepare(ctx, key, "base") + if err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(root, "active", hash(key), "fs", "foo"), []byte("hi, again"), 0660); err != nil { + t.Fatal(err) + } + if err := o.Commit(ctx, "top", key); err != nil { + t.Fatal(err) + } + + mounts, err = o.View(ctx, "/tmp/view1", "base") + if err != nil { + t.Fatal(err) + } + if len(mounts) != 1 { + t.Fatalf("should only have 1 mount but received %d", len(mounts)) + } + m = mounts[0] + if m.Type != "bind" { + t.Errorf("mount type should be bind but received %q", m.Type) + } + expected := filepath.Join(root, "committed", hash("base"), "fs") + if m.Source != expected { + t.Errorf("expected source %q but received %q", expected, m.Source) + } + if m.Options[0] != "ro" { + t.Errorf("expected mount option ro but received %q", m.Options[0]) + } + if m.Options[1] != "rbind" { + t.Errorf("expected mount option rbind but received %q", m.Options[1]) + } + + mounts, err = o.View(ctx, "/tmp/view2", "top") if err != nil { t.Fatal(err) } @@ -238,7 +273,7 @@ func TestOverlayView(t *testing.T) { if len(m.Options) != 1 { t.Errorf("expected 1 mount option but got %d", len(m.Options)) } - expected := fmt.Sprintf("lowerdir=%s", filepath.Join(root, "committed", hash("base"), "fs")) + expected = fmt.Sprintf("lowerdir=%s:%s", filepath.Join(root, "committed", hash("top"), "fs"), filepath.Join(root, "committed", hash("base"), "fs")) if m.Options[0] != expected { t.Errorf("expected option %q but received %q", expected, m.Options[0]) }