Skip to content

Commit

Permalink
Merge pull request kubernetes#119968 from j4ckstraw/replace-stat-with…
Browse files Browse the repository at this point in the history
…-statx

Replace stat syscall with statx
  • Loading branch information
k8s-ci-robot authored Jan 8, 2024
2 parents 6274163 + d566427 commit 9e0ecca
Showing 1 changed file with 65 additions and 8 deletions.
73 changes: 65 additions & 8 deletions staging/src/k8s.io/mount-utils/mount_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"time"

"github.com/moby/sys/mountinfo"
"golang.org/x/sys/unix"

"k8s.io/klog/v2"
utilexec "k8s.io/utils/exec"
Expand All @@ -55,6 +56,11 @@ const (
errNotMounted = "not mounted"
)

var (
// Error statx support since Linux 4.11, https://man7.org/linux/man-pages/man2/statx.2.html
errStatxNotSupport = errors.New("the statx syscall is not supported. At least Linux kernel 4.11 is needed")
)

// Mounter provides the default implementation of mount.Interface
// for the linux platform. This implementation assumes that the
// kubelet is running in the host's root mount namespace.
Expand Down Expand Up @@ -385,14 +391,20 @@ func (*Mounter) List() ([]MountPoint, error) {
return ListProcMounts(procMountsPath)
}

// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
// It is fast but not necessarily ALWAYS correct. If the path is in fact
// a bind mount from one part of a mount to another it will not be detected.
// It also can not distinguish between mountpoints and symbolic links.
// mkdir /tmp/a /tmp/b; mount --bind /tmp/a /tmp/b; IsLikelyNotMountPoint("/tmp/b")
// will return true. When in fact /tmp/b is a mount point. If this situation
// is of interest to you, don't use this function...
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
func statx(file string) (unix.Statx_t, error) {
var stat unix.Statx_t
if err := unix.Statx(0, file, unix.AT_STATX_DONT_SYNC, 0, &stat); err != nil {
if err == unix.ENOSYS {
return stat, errStatxNotSupport
}

return stat, err
}

return stat, nil
}

func (mounter *Mounter) isLikelyNotMountPointStat(file string) (bool, error) {
stat, err := os.Stat(file)
if err != nil {
return true, err
Expand All @@ -409,6 +421,51 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
return true, nil
}

func (mounter *Mounter) isLikelyNotMountPointStatx(file string) (bool, error) {
var stat, rootStat unix.Statx_t
var err error

if stat, err = statx(file); err != nil {
return true, err
}

if stat.Attributes_mask != 0 {
if stat.Attributes_mask&unix.STATX_ATTR_MOUNT_ROOT != 0 {
if stat.Attributes&unix.STATX_ATTR_MOUNT_ROOT != 0 {
// file is a mountpoint
return false, nil
} else {
// no need to check rootStat if unix.STATX_ATTR_MOUNT_ROOT supported
return true, nil
}
}
}

root := filepath.Dir(strings.TrimSuffix(file, "/"))
if rootStat, err = statx(root); err != nil {
return true, err
}

return (stat.Dev_major == rootStat.Dev_major && stat.Dev_minor == rootStat.Dev_minor), nil
}

// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
// It is fast but not necessarily ALWAYS correct. If the path is in fact
// a bind mount from one part of a mount to another it will not be detected.
// It also can not distinguish between mountpoints and symbolic links.
// mkdir /tmp/a /tmp/b; mount --bind /tmp/a /tmp/b; IsLikelyNotMountPoint("/tmp/b")
// will return true. When in fact /tmp/b is a mount point. If this situation
// is of interest to you, don't use this function...
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
notMountPoint, err := mounter.isLikelyNotMountPointStatx(file)
if errors.Is(err, errStatxNotSupport) {
// fall back to isLikelyNotMountPointStat
return mounter.isLikelyNotMountPointStat(file)
}

return notMountPoint, err
}

// CanSafelySkipMountPointCheck relies on the detected behavior of umount when given a target that is not a mount point.
func (mounter *Mounter) CanSafelySkipMountPointCheck() bool {
return mounter.withSafeNotMountedBehavior
Expand Down

0 comments on commit 9e0ecca

Please sign in to comment.