mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-17 15:50:10 +00:00
Replace stat syscall with statx
statx with AT_STATX_DONT_SYNC will not stuck kubelet syncLoop. Signed-off-by: j4ckstraw <j4ckstraw@foxmail.com> fix remove useless comment Signed-off-by: j4ckstraw <j4ckstraw@foxmail.com>
This commit is contained in:
parent
b51ad13bf7
commit
dbb6927ec2
@ -29,10 +29,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/moby/sys/mountinfo"
|
"github.com/moby/sys/mountinfo"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
utilexec "k8s.io/utils/exec"
|
utilexec "k8s.io/utils/exec"
|
||||||
@ -385,28 +385,55 @@ func (*Mounter) List() ([]MountPoint, error) {
|
|||||||
return ListProcMounts(procMountsPath)
|
return ListProcMounts(procMountsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
|
// statx support since Linux 4.11, glibc 2.28
|
||||||
// It is fast but not necessarily ALWAYS correct. If the path is in fact
|
// refer: https://man7.org/linux/man-pages/man2/statx.2.html
|
||||||
// a bind mount from one part of a mount to another it will not be detected.
|
var errNotSupport = errors.New("The statx syscall is not supported. At least Linux kernel 4.11 is needed")
|
||||||
// It also can not distinguish between mountpoints and symbolic links.
|
|
||||||
// mkdir /tmp/a /tmp/b; mount --bind /tmp/a /tmp/b; IsLikelyNotMountPoint("/tmp/b")
|
func statx(file string) (unix.Statx_t, error) {
|
||||||
// will return true. When in fact /tmp/b is a mount point. If this situation
|
var stat unix.Statx_t
|
||||||
// is of interest to you, don't use this function...
|
if err := unix.Statx(0, file, unix.AT_STATX_DONT_SYNC, 0, &stat); err != nil {
|
||||||
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
if err == unix.ENOSYS {
|
||||||
stat, err := os.Stat(file)
|
return stat, errNotSupport
|
||||||
if err != nil {
|
}
|
||||||
return true, err
|
|
||||||
}
|
return stat, err
|
||||||
rootStat, err := os.Stat(filepath.Dir(strings.TrimSuffix(file, "/")))
|
|
||||||
if err != nil {
|
|
||||||
return true, err
|
|
||||||
}
|
|
||||||
// If the directory has a different device as parent, then it is a mountpoint.
|
|
||||||
if stat.Sys().(*syscall.Stat_t).Dev != rootStat.Sys().(*syscall.Stat_t).Dev {
|
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return stat, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLikelyNotMountPoint determines if a directory is not a mountpoint.
|
||||||
|
// If fast check failed, fall back to slow path. If the path is in fact
|
||||||
|
// a bind mount from one part of a mount to another it will be detected.
|
||||||
|
// It also can distinguish between mountpoints and symbolic links.
|
||||||
|
// mkdir /tmp/a /tmp/b; mount --bind /tmp/a /tmp/b; IsLikelyNotMountPoint("/tmp/b")
|
||||||
|
// will return false. When in fact /tmp/b is a mount point.
|
||||||
|
|
||||||
|
// TODO(j4ckstraw) add test
|
||||||
|
func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
|
||||||
|
var stat, rootStat unix.Statx_t
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if stat, err = statx(file); err != nil {
|
||||||
|
if errors.Is(err, errNotSupport) {
|
||||||
|
// not support statx, go slow path
|
||||||
|
mnt, mntErr := mounter.IsMountPoint(file)
|
||||||
|
return !mnt, mntErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
root := filepath.Dir(strings.TrimSuffix(file, "/"))
|
||||||
|
if rootStat, err = statx(root); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add STATX_ATTR_MOUNT_ROOT support, which can check mountpoint correctly.
|
||||||
|
// Linux 5.8 commit 80340fe3605c0e78cfe496c3b3878be828cfdbfe
|
||||||
|
// stat->attributes |= STATX_ATTR_MOUNT_ROOT;
|
||||||
|
// stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT;
|
||||||
|
return !(stat.Dev_major == rootStat.Dev_major && stat.Dev_minor == rootStat.Dev_minor), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanSafelySkipMountPointCheck relies on the detected behavior of umount when given a target that is not a mount point.
|
// CanSafelySkipMountPointCheck relies on the detected behavior of umount when given a target that is not a mount point.
|
||||||
|
Loading…
Reference in New Issue
Block a user