File: mount.go

package info (click to toggle)
docker.io 20.10.24%2Bdfsg1-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-proposed-updates
  • size: 60,824 kB
  • sloc: sh: 5,621; makefile: 593; ansic: 179; python: 162; asm: 7
file content (56 lines) | stat: -rw-r--r-- 1,392 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//go:build linux
// +build linux

package aufs // import "github.com/docker/docker/daemon/graphdriver/aufs"

import (
	"os/exec"
	"syscall"
	"time"

	"github.com/moby/sys/mount"
	"github.com/pkg/errors"
	"golang.org/x/sys/unix"
)

// Unmount the target specified.
func Unmount(target string) error {
	const retries = 5

	// auplink flush
	for i := 0; ; i++ {
		out, err := exec.Command("auplink", target, "flush").CombinedOutput()
		if err == nil {
			break
		}
		rc := 0
		if exiterr, ok := err.(*exec.ExitError); ok {
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				rc = status.ExitStatus()
			}
		}
		if i >= retries || rc != int(unix.EINVAL) {
			logger.WithError(err).WithField("method", "Unmount").Warnf("auplink flush failed: %s", out)
			break
		}
		// auplink failed to find target in /proc/self/mounts because
		// kernel can't guarantee continuity while reading from it
		// while mounts table is being changed
		logger.Debugf("auplink flush error (retrying %d/%d): %s", i+1, retries, out)
	}

	// unmount
	var err error
	for i := 0; i < retries; i++ {
		err = mount.Unmount(target)
		if err != nil && errors.Is(err, unix.EBUSY) {
			logger.Debugf("aufs unmount %s failed with EBUSY (retrying %d/%d)", target, i+1, retries)
			time.Sleep(100 * time.Millisecond)
			continue // try again
		}
		break
	}

	// either no error occurred, or another error
	return err
}