From d0f7b99c6dfb8dcbdc4a36e765cc8eb7fcde4798 Mon Sep 17 00:00:00 2001 From: Aditya Rajan Date: Mon, 18 Oct 2021 15:47:55 +0530 Subject: rootfs-overlay: fix overlaybase path for cleanups Following commit ensures not dandling mounts are left behind when we are creating an overlay on top of external rootfs. Co-authored-by: Valentin Rothberg Signed-off-by: Aditya Rajan --- libpod/container_internal.go | 29 +++++++++++++++++------------ test/e2e/run_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 3f9738411..4e8074840 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -1690,9 +1690,23 @@ func (c *Container) cleanupStorage() error { var cleanupErr error + markUnmounted := func() { + c.state.Mountpoint = "" + c.state.Mounted = false + + if c.valid { + if err := c.save(); err != nil { + if cleanupErr != nil { + logrus.Errorf("Unmounting container %s: %v", c.ID(), cleanupErr) + } + cleanupErr = err + } + } + } + // umount rootfs overlay if it was created if c.config.RootfsOverlay { - overlayBasePath := c.runtime.store.GraphRoot() + overlayBasePath := filepath.Dir(c.config.StaticDir) overlayBasePath = filepath.Join(overlayBasePath, "rootfs") if err := overlay.Unmount(overlayBasePath); err != nil { // If the container can't remove content report the error @@ -1717,6 +1731,7 @@ func (c *Container) cleanupStorage() error { } if c.config.Rootfs != "" { + markUnmounted() return cleanupErr } @@ -1761,17 +1776,7 @@ func (c *Container) cleanupStorage() error { } } - c.state.Mountpoint = "" - c.state.Mounted = false - - if c.valid { - if err := c.save(); err != nil { - if cleanupErr != nil { - logrus.Errorf("Unmounting container %s: %v", c.ID(), cleanupErr) - } - cleanupErr = err - } - } + markUnmounted() return cleanupErr } diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index b6743f4b7..f40d4a749 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "net" "os" + "os/exec" "path/filepath" "strconv" "strings" @@ -12,6 +13,7 @@ import ( "time" "github.com/containers/podman/v3/pkg/cgroups" + "github.com/containers/podman/v3/pkg/rootless" . "github.com/containers/podman/v3/test/utils" "github.com/containers/storage/pkg/stringid" "github.com/mrunalp/fileutils" @@ -226,6 +228,37 @@ var _ = Describe("Podman run", func() { stdoutLines := session.OutputToStringArray() Expect(stdoutLines).Should(HaveLen(1)) Expect(stdoutLines[0]).Should(Equal(uniqueString)) + + SkipIfRemote("External overlay only work locally") + if os.Getenv("container") != "" { + Skip("Overlay mounts not supported when running in a container") + } + if rootless.IsRootless() { + if _, err := exec.LookPath("fuse-overlayfs"); err != nil { + Skip("Fuse-Overlayfs required for rootless overlay mount test") + } + } + // Test --rootfs with an external overlay + // use --rm to remove container and confirm if we did not leak anything + osession := podmanTest.Podman([]string{"run", "-i", "--rm", "--security-opt", "label=disable", + "--rootfs", rootfs + ":O", "cat", testFilePath}) + osession.WaitWithDefaultTimeout() + Expect(osession).Should(Exit(0)) + + // Test podman start stop with overlay + osession = podmanTest.Podman([]string{"run", "--name", "overlay-foo", "--security-opt", "label=disable", + "--rootfs", rootfs + ":O", "echo", "hello"}) + osession.WaitWithDefaultTimeout() + Expect(osession).Should(Exit(0)) + + osession = podmanTest.Podman([]string{"stop", "overlay-foo"}) + osession.WaitWithDefaultTimeout() + Expect(osession).Should(Exit(0)) + + startsession := podmanTest.Podman([]string{"start", "--attach", "overlay-foo"}) + startsession.WaitWithDefaultTimeout() + Expect(startsession).Should(Exit(0)) + Expect(startsession.OutputToString()).To(Equal("hello")) }) It("podman run a container with --init", func() { -- cgit v1.2.3-54-g00ecf