kubernetes/vendor/github.com/moby/sys/mountinfo/mounted_linux.go
David Porter b5dd78da3d vendor: cadvisor v0.39.0
Main upgrades:
- github.com/opencontainers/runc v1.0.0-rc93
- github.com/containerd/containerd v1.4.4
- github.com/docker/docker v20.10.2
- github.com/mrunalp/fileutils v0.5.0
- github.com/opencontainers/selinux v1.8.0
- github.com/cilium/ebpf v0.2.0
2021-03-08 22:10:29 -08:00

59 lines
1.5 KiB
Go

package mountinfo
import (
"os"
"path/filepath"
"golang.org/x/sys/unix"
)
// 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) {
dir, last := filepath.Split(path)
dirfd, err := unix.Openat2(unix.AT_FDCWD, dir, &unix.OpenHow{
Flags: unix.O_PATH | unix.O_CLOEXEC,
})
if err != nil {
if err == unix.ENOENT { // not a mount
return false, nil
}
return false, &os.PathError{Op: "openat2", Path: dir, Err: err}
}
fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{
Flags: unix.O_PATH | unix.O_CLOEXEC | unix.O_NOFOLLOW,
Resolve: unix.RESOLVE_NO_XDEV,
})
_ = unix.Close(dirfd)
switch err {
case nil: // definitely not a mount
_ = unix.Close(fd)
return false, nil
case unix.EXDEV: // definitely a mount
return true, nil
case unix.ENOENT: // not a mount
return false, nil
}
// not sure
return false, &os.PathError{Op: "openat2", Path: path, Err: err}
}
func mounted(path string) (bool, error) {
// Try a fast path, using openat2() with RESOLVE_NO_XDEV.
mounted, err := mountedByOpenat2(path)
if err == nil {
return mounted, 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 mounted, nil
}
// Fallback to parsing mountinfo
return mountedByMountinfo(path)
}