aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/moby/sys/mountinfo/mounted_linux.go')
-rw-r--r--vendor/github.com/moby/sys/mountinfo/mounted_linux.go58
1 files changed, 51 insertions, 7 deletions
diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_linux.go b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
index 5c9e3e30e..bf221e687 100644
--- a/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
+++ b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
@@ -7,6 +7,34 @@ import (
"golang.org/x/sys/unix"
)
+// MountedFast is a method of detecting a mount point without reading
+// mountinfo from procfs. A caller can only trust the result if no error
+// and sure == true are returned. Otherwise, other methods (e.g. parsing
+// /proc/mounts) have to be used. If unsure, use Mounted instead (which
+// uses MountedFast, but falls back to parsing mountinfo if needed).
+//
+// If a non-existent path is specified, an appropriate error is returned.
+// In case the caller is not interested in this particular error, it should
+// be handled separately using e.g. errors.Is(err, os.ErrNotExist).
+//
+// This function is only available on Linux. When available (since kernel
+// v5.6), openat2(2) syscall is used to reliably detect all mounts. Otherwise,
+// the implementation falls back to using stat(2), which can reliably detect
+// normal (but not bind) mounts.
+func MountedFast(path string) (mounted, sure bool, err error) {
+ // Root is always mounted.
+ if path == string(os.PathSeparator) {
+ return true, true, nil
+ }
+
+ path, err = normalizePath(path)
+ if err != nil {
+ return false, false, err
+ }
+ mounted, sure, err = mountedFast(path)
+ return
+}
+
// mountedByOpenat2 is a method of detecting a mount that works for all kinds
// of mounts (incl. bind mounts), but requires a recent (v5.6+) linux kernel.
func mountedByOpenat2(path string) (bool, error) {
@@ -34,24 +62,40 @@ func mountedByOpenat2(path string) (bool, error) {
return false, &os.PathError{Op: "openat2", Path: path, Err: err}
}
-func mounted(path string) (bool, error) {
- path, err := normalizePath(path)
- if err != nil {
- return false, err
+// mountedFast is similar to MountedFast, except it expects a normalized path.
+func mountedFast(path string) (mounted, sure bool, err error) {
+ // Root is always mounted.
+ if path == string(os.PathSeparator) {
+ return true, true, nil
}
+
// Try a fast path, using openat2() with RESOLVE_NO_XDEV.
- mounted, err := mountedByOpenat2(path)
+ mounted, err = mountedByOpenat2(path)
if err == nil {
- return mounted, nil
+ return mounted, true, nil
}
+
// Another fast path: compare st.st_dev fields.
mounted, err = mountedByStat(path)
// This does not work for bind mounts, so false negative
// is possible, therefore only trust if return is true.
if mounted && err == nil {
+ return true, true, nil
+ }
+
+ return
+}
+
+func mounted(path string) (bool, error) {
+ path, err := normalizePath(path)
+ if err != nil {
+ return false, err
+ }
+ mounted, sure, err := mountedFast(path)
+ if sure && err == nil {
return mounted, nil
}
- // Fallback to parsing mountinfo
+ // Fallback to parsing mountinfo.
return mountedByMountinfo(path)
}