X Tutup
Skip to content

Commit d42cb88

Browse files
author
Ian Campbell
committed
Loop umount'ing rootfs until there are no more mounts
This is simpler than trying to count how many successful mounts we made. Signed-off-by: Ian Campbell <ian.campbell@docker.com>
1 parent d63d2ec commit d42cb88

File tree

5 files changed

+42
-35
lines changed

5 files changed

+42
-35
lines changed

linux/shim/init.go

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,18 @@ type initProcess struct {
3939
// the reaper interface.
4040
mu sync.Mutex
4141

42-
id string
43-
bundle string
44-
console console.Console
45-
io runc.IO
46-
runtime *runc.Runc
47-
status int
48-
exited time.Time
49-
pid int
50-
closers []io.Closer
51-
stdin io.Closer
52-
stdio stdio
53-
rootfs string
54-
nrRootMounts int // Number of rootfs overmounts
42+
id string
43+
bundle string
44+
console console.Console
45+
io runc.IO
46+
runtime *runc.Runc
47+
status int
48+
exited time.Time
49+
pid int
50+
closers []io.Closer
51+
stdin io.Closer
52+
stdio stdio
53+
rootfs string
5554
}
5655

5756
func newInitProcess(context context.Context, path, namespace string, r *shimapi.CreateTaskRequest) (*initProcess, error) {
@@ -73,12 +72,11 @@ func newInitProcess(context context.Context, path, namespace string, r *shimapi.
7372
// count the number of successful mounts so we can undo
7473
// what was actually done rather than what should have been
7574
// done.
76-
nrRootMounts := 0
7775
defer func() {
7876
if success {
7977
return
8078
}
81-
if err2 := mount.UnmountN(rootfs, 0, nrRootMounts); err2 != nil {
79+
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
8280
log.G(context).WithError(err2).Warn("Failed to cleanup rootfs mount")
8381
}
8482
}()
@@ -91,7 +89,6 @@ func newInitProcess(context context.Context, path, namespace string, r *shimapi.
9189
if err := m.Mount(rootfs); err != nil {
9290
return nil, errors.Wrapf(err, "failed to mount rootfs component %v", m)
9391
}
94-
nrRootMounts++
9592
}
9693
runtime := &runc.Runc{
9794
Command: r.Runtime,
@@ -110,8 +107,7 @@ func newInitProcess(context context.Context, path, namespace string, r *shimapi.
110107
stderr: r.Stderr,
111108
terminal: r.Terminal,
112109
},
113-
rootfs: rootfs,
114-
nrRootMounts: nrRootMounts,
110+
rootfs: rootfs,
115111
}
116112
var (
117113
err error
@@ -253,7 +249,7 @@ func (p *initProcess) Delete(context context.Context) error {
253249
}
254250
err = p.runtimeError(err, "OCI runtime delete failed")
255251

256-
if err2 := mount.UnmountN(p.rootfs, 0, p.nrRootMounts); err2 != nil {
252+
if err2 := mount.UnmountAll(p.rootfs, 0); err2 != nil {
257253
log.G(context).WithError(err2).Warn("Failed to cleanup rootfs mount")
258254
if err == nil {
259255
err = errors.Wrap(err2, "Failed rootfs umount")

mount/mount.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,3 @@ func MountAll(mounts []Mount, target string) error {
2222
}
2323
return nil
2424
}
25-
26-
// UnmountN tries to unmount the given mount point nr times, which is
27-
// useful for undoing a stack of mounts on the same mount
28-
// point. Returns the first error encountered, but always attempts the
29-
// full nr umounts.
30-
func UnmountN(mount string, flags, nr int) error {
31-
var err error
32-
for i := 0; i < nr; i++ {
33-
if err2 := Unmount(mount, flags); err2 != nil {
34-
if err == nil {
35-
err = err2
36-
}
37-
}
38-
}
39-
return err
40-
}

mount/mount_linux.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@ func Unmount(mount string, flags int) error {
1515
return unix.Unmount(mount, flags)
1616
}
1717

18+
// UnmountAll repeatedly unmounts the given mount point until there
19+
// are no mounts remaining (EINVAL is returned by mount), which is
20+
// useful for undoing a stack of mounts on the same mount point.
21+
func UnmountAll(mount string, flags int) error {
22+
for {
23+
if err := Unmount(mount, flags); err != nil {
24+
// EINVAL is returned if the target is not a
25+
// mount point, indicating that we are
26+
// done. It can also indicate a few other
27+
// things (such as invalid flags) which we
28+
// unfortunately end up squelching here too.
29+
if err == unix.EINVAL {
30+
return nil
31+
}
32+
return err
33+
}
34+
}
35+
}
36+
1837
// parseMountOptions takes fstab style mount options and parses them for
1938
// use with a standard mount() syscall
2039
func parseMountOptions(options []string) (int, string) {

mount/mount_unix.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ func (m *Mount) Mount(target string) error {
1515
func Unmount(mount string, flags int) error {
1616
return ErrNotImplementOnUnix
1717
}
18+
19+
func UnmountAll(mount string, flags int) error {
20+
return ErrNotImplementOnUnix
21+
}

mount/mount_windows.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ func (m *Mount) Mount(target string) error {
1313
func Unmount(mount string, flags int) error {
1414
return ErrNotImplementOnWindows
1515
}
16+
17+
func UnmountAll(mount string, flags int) error {
18+
return ErrNotImplementOnWindows
19+
}

0 commit comments

Comments
 (0)
X Tutup