Skip to content

Commit 3f01d17

Browse files
manugupt1thaJeztah
andcommitted
Add test for RecursiveUnmount when a submount fails to unmount.
Uses shadow mounts to get ENOENT for deeper level mounts. #45 Co-authored-by: Sebastiaan van Stijn <thaJeztah@users.noreply.github.com> Signed-off-by: Manu Gupta <manugupt1@gmail.com>
1 parent 0335593 commit 3f01d17

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

mount/mount_unix_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
package mount
55

66
import (
7+
"errors"
78
"os"
89
"path"
910
"strings"
1011
"testing"
1112

1213
"github.com/moby/sys/mountinfo"
14+
"golang.org/x/sys/unix"
1315
)
1416

1517
func TestMountOptionsParsing(t *testing.T) {
@@ -230,3 +232,45 @@ func TestRecursiveUnmountTooGreedy(t *testing.T) {
230232
t.Fatal("expected dir-other to be mounted, but it's not")
231233
}
232234
}
235+
236+
func TestRecursiveUnmount_SubMountFailsToUnmount(t *testing.T) {
237+
if os.Getuid() != 0 {
238+
t.Skip("root required")
239+
}
240+
241+
var (
242+
tmp = t.TempDir()
243+
parent = tmp + "/sub1"
244+
child = tmp + "/sub1/sub2"
245+
grandChild = tmp + "/sub1/sub2/sub3"
246+
)
247+
248+
err := os.MkdirAll(grandChild, 0o700)
249+
if err != nil {
250+
t.Fatal(err)
251+
}
252+
253+
// Create a set of mounts that should result in RecursiveUnmount failure,
254+
// caused by the fact that the grandchild mount is shadowed by the child mount,
255+
// and the child mount is shadowed by the parent mount. So. these two mounts
256+
// are listed in mountinfo, but since they are unreachable, unmount will fail.
257+
toMount := []string{grandChild, child, parent}
258+
for _, dir := range toMount {
259+
dir := dir
260+
if err := Mount("tmpfs", dir, "tmpfs", ""); err != nil {
261+
t.Fatal(err)
262+
}
263+
defer Unmount(dir) //nolint:errcheck
264+
}
265+
266+
// unmount shadowed mounts
267+
shadowedMounts := []string{child, grandChild}
268+
for _, shadowedMount := range shadowedMounts {
269+
t.Run(shadowedMount, func(t *testing.T) {
270+
err := RecursiveUnmount(shadowedMount)
271+
if !errors.Is(err, unix.ENOENT) {
272+
t.Fatalf("expected submount(shadowed) %s to return unix.ENOENT, got %v", shadowedMount, err)
273+
}
274+
})
275+
}
276+
}

0 commit comments

Comments
 (0)