mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 18:31:15 +00:00
Merge pull request #109217 from manugupt1/improve-mount-detection
Improved mount detection using openat2 for kernel 5.10+
This commit is contained in:
commit
c27e82604e
@ -370,7 +370,7 @@ func TestMountUnmount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
// skip this check in windows since the "bind mount" logic is implemented differently in mount_wiondows.go
|
// skip this check in windows since the "bind mount" logic is implemented differently in mount_windows.go
|
||||||
if _, err := os.Stat(path); err != nil {
|
if _, err := os.Stat(path); err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
t.Errorf("SetUp() failed, volume path not created: %s", path)
|
t.Errorf("SetUp() failed, volume path not created: %s", path)
|
||||||
|
@ -70,6 +70,7 @@ require (
|
|||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/mailru/easyjson v0.7.6 // indirect
|
github.com/mailru/easyjson v0.7.6 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||||
|
github.com/moby/sys/mountinfo v0.6.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
2
staging/src/k8s.io/legacy-cloud-providers/go.sum
generated
2
staging/src/k8s.io/legacy-cloud-providers/go.sum
generated
@ -282,6 +282,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
|
|||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo=
|
||||||
|
github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
@ -222,6 +222,14 @@ func (f *FakeMounter) canSafelySkipMountPointCheck() bool {
|
|||||||
return f.skipMountPointCheck
|
return f.skipMountPointCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FakeMounter) IsMountPoint(file string) (bool, error) {
|
||||||
|
notMnt, err := f.IsLikelyNotMountPoint(file)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return !notMnt, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetMountRefs finds all mount references to the path, returns a
|
// GetMountRefs finds all mount references to the path, returns a
|
||||||
// list of paths.
|
// list of paths.
|
||||||
func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
|
func (f *FakeMounter) GetMountRefs(pathname string) ([]string, error) {
|
||||||
|
@ -5,6 +5,7 @@ module k8s.io/mount-utils
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/moby/sys/mountinfo v0.6.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
k8s.io/klog/v2 v2.70.1
|
k8s.io/klog/v2 v2.70.1
|
||||||
k8s.io/utils v0.0.0-20220725171434-9bab9ef40391
|
k8s.io/utils v0.0.0-20220725171434-9bab9ef40391
|
||||||
@ -16,6 +17,7 @@ require (
|
|||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
5
staging/src/k8s.io/mount-utils/go.sum
generated
5
staging/src/k8s.io/mount-utils/go.sum
generated
@ -10,6 +10,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo=
|
||||||
|
github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
@ -19,6 +21,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
|
||||||
|
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||||
|
@ -21,7 +21,6 @@ package mount
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -70,6 +69,14 @@ type Interface interface {
|
|||||||
// operations for targets that are not mount points. If this returns true, no such
|
// operations for targets that are not mount points. If this returns true, no such
|
||||||
// errors will be returned.
|
// errors will be returned.
|
||||||
canSafelySkipMountPointCheck() bool
|
canSafelySkipMountPointCheck() bool
|
||||||
|
// IsMountPoint determines if a directory is a mountpoint.
|
||||||
|
// It should return ErrNotExist when the directory does not exist.
|
||||||
|
// IsMountPoint is more expensive than IsLikelyNotMountPoint.
|
||||||
|
// IsMountPoint detects bind mounts in linux.
|
||||||
|
// IsMountPoint may enumerate all the mountpoints using List() and
|
||||||
|
// the list of mountpoints may be large, then it uses
|
||||||
|
// isMountPointMatch to evaluate whether the directory is a mountpoint.
|
||||||
|
IsMountPoint(file string) (bool, error)
|
||||||
// GetMountRefs finds all mount references to pathname, returning a slice of
|
// GetMountRefs finds all mount references to pathname, returning a slice of
|
||||||
// paths. Pathname can be a mountpoint path or a normal directory
|
// paths. Pathname can be a mountpoint path or a normal directory
|
||||||
// (for bind mount). On Linux, pathname is excluded from the slice.
|
// (for bind mount). On Linux, pathname is excluded from the slice.
|
||||||
@ -191,6 +198,24 @@ func getMountRefsByDev(mounter Interface, mountPath string) ([]string, error) {
|
|||||||
return refs, nil
|
return refs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNotMountPoint determines if a directory is a mountpoint.
|
||||||
|
// It should return ErrNotExist when the directory does not exist.
|
||||||
|
// IsNotMountPoint is more expensive than IsLikelyNotMountPoint
|
||||||
|
// and depends on IsMountPoint.
|
||||||
|
//
|
||||||
|
// If an error occurs, it returns true (assuming it is not a mountpoint)
|
||||||
|
// when ErrNotExist is returned for callers similar to IsLikelyNotMountPoint.
|
||||||
|
//
|
||||||
|
// Deprecated: This function is kept to keep changes backward compatible with
|
||||||
|
// previous library version. Callers should prefer mounter.IsMountPoint.
|
||||||
|
func IsNotMountPoint(mounter Interface, file string) (bool, error) {
|
||||||
|
isMnt, err := mounter.IsMountPoint(file)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
return !isMnt, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetDeviceNameFromMount given a mnt point, find the device from /proc/mounts
|
// GetDeviceNameFromMount given a mnt point, find the device from /proc/mounts
|
||||||
// returns the device name, reference count, and error code.
|
// returns the device name, reference count, and error code.
|
||||||
func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, error) {
|
func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, error) {
|
||||||
@ -224,52 +249,6 @@ func GetDeviceNameFromMount(mounter Interface, mountPath string) (string, int, e
|
|||||||
return device, refCount, nil
|
return device, refCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsNotMountPoint determines if a directory is a mountpoint.
|
|
||||||
// It should return ErrNotExist when the directory does not exist.
|
|
||||||
// IsNotMountPoint is more expensive than IsLikelyNotMountPoint.
|
|
||||||
// IsNotMountPoint detects bind mounts in linux.
|
|
||||||
// IsNotMountPoint enumerates all the mountpoints using List() and
|
|
||||||
// the list of mountpoints may be large, then it uses
|
|
||||||
// isMountPointMatch to evaluate whether the directory is a mountpoint.
|
|
||||||
func IsNotMountPoint(mounter Interface, file string) (bool, error) {
|
|
||||||
// IsLikelyNotMountPoint provides a quick check
|
|
||||||
// to determine whether file IS A mountpoint.
|
|
||||||
notMnt, notMntErr := mounter.IsLikelyNotMountPoint(file)
|
|
||||||
if notMntErr != nil && os.IsPermission(notMntErr) {
|
|
||||||
// We were not allowed to do the simple stat() check, e.g. on NFS with
|
|
||||||
// root_squash. Fall back to /proc/mounts check below.
|
|
||||||
notMnt = true
|
|
||||||
notMntErr = nil
|
|
||||||
}
|
|
||||||
if notMntErr != nil {
|
|
||||||
return notMnt, notMntErr
|
|
||||||
}
|
|
||||||
// identified as mountpoint, so return this fact.
|
|
||||||
if notMnt == false {
|
|
||||||
return notMnt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts.
|
|
||||||
resolvedFile, err := filepath.EvalSymlinks(file)
|
|
||||||
if err != nil {
|
|
||||||
return true, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check all mountpoints since IsLikelyNotMountPoint
|
|
||||||
// is not reliable for some mountpoint types.
|
|
||||||
mountPoints, mountPointsErr := mounter.List()
|
|
||||||
if mountPointsErr != nil {
|
|
||||||
return notMnt, mountPointsErr
|
|
||||||
}
|
|
||||||
for _, mp := range mountPoints {
|
|
||||||
if isMountPointMatch(mp, resolvedFile) {
|
|
||||||
notMnt = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return notMnt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeBindOpts detects whether a bind mount is being requested and makes the remount options to
|
// MakeBindOpts detects whether a bind mount is being requested and makes the remount options to
|
||||||
// use in case of bind mount, due to the fact that bind mount doesn't respect mount options.
|
// use in case of bind mount, due to the fact that bind mount doesn't respect mount options.
|
||||||
// The list equals:
|
// The list equals:
|
||||||
|
@ -55,12 +55,16 @@ func TestDoCleanupMountPoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return MountPoint{Device: "/dev/sdb", Path: path}, nil, nil
|
return MountPoint{Device: "/dev/sdb", Path: path}, nil, nil
|
||||||
},
|
},
|
||||||
|
corruptedMnt: false,
|
||||||
|
expectErr: false,
|
||||||
},
|
},
|
||||||
"path-not-exist": {
|
"path-not-exist": {
|
||||||
prepareMnt: func(base string) (MountPoint, error, error) {
|
prepareMnt: func(base string) (MountPoint, error, error) {
|
||||||
path := filepath.Join(base, testMount)
|
path := filepath.Join(base, testMount)
|
||||||
return MountPoint{Device: "/dev/sdb", Path: path}, nil, nil
|
return MountPoint{Device: "/dev/sdb", Path: path}, nil, nil
|
||||||
},
|
},
|
||||||
|
corruptedMnt: false,
|
||||||
|
expectErr: false,
|
||||||
},
|
},
|
||||||
"mount-corrupted": {
|
"mount-corrupted": {
|
||||||
prepareMnt: func(base string) (MountPoint, error, error) {
|
prepareMnt: func(base string) (MountPoint, error, error) {
|
||||||
@ -71,6 +75,7 @@ func TestDoCleanupMountPoint(t *testing.T) {
|
|||||||
return MountPoint{Device: "/dev/sdb", Path: path}, os.NewSyscallError("fake", syscall.ESTALE), nil
|
return MountPoint{Device: "/dev/sdb", Path: path}, os.NewSyscallError("fake", syscall.ESTALE), nil
|
||||||
},
|
},
|
||||||
corruptedMnt: true,
|
corruptedMnt: true,
|
||||||
|
expectErr: false,
|
||||||
},
|
},
|
||||||
"mount-err-not-corrupted": {
|
"mount-err-not-corrupted": {
|
||||||
prepareMnt: func(base string) (MountPoint, error, error) {
|
prepareMnt: func(base string) (MountPoint, error, error) {
|
||||||
@ -80,7 +85,8 @@ func TestDoCleanupMountPoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return MountPoint{Device: "/dev/sdb", Path: path}, os.NewSyscallError("fake", syscall.ETIMEDOUT), nil
|
return MountPoint{Device: "/dev/sdb", Path: path}, os.NewSyscallError("fake", syscall.ETIMEDOUT), nil
|
||||||
},
|
},
|
||||||
expectErr: true,
|
corruptedMnt: false,
|
||||||
|
expectErr: true,
|
||||||
},
|
},
|
||||||
"skip-mount-point-check": {
|
"skip-mount-point-check": {
|
||||||
prepareMnt: func(base string) (MountPoint, error, error) {
|
prepareMnt: func(base string) (MountPoint, error, error) {
|
||||||
|
@ -21,7 +21,10 @@ package mount
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/moby/sys/mountinfo"
|
||||||
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -692,6 +695,63 @@ func SearchMountPoints(hostSource, mountInfoPath string) ([]string, error) {
|
|||||||
return refs, nil
|
return refs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsMountPoint determines if a file is a mountpoint.
|
||||||
|
// It first detects bind & any other mountpoints using
|
||||||
|
// MountedFast function. If the MountedFast function returns
|
||||||
|
// sure as true and err as nil, then a mountpoint is detected
|
||||||
|
// successfully. When an error is returned by MountedFast, the
|
||||||
|
// following is true:
|
||||||
|
// 1. All errors are returned with IsMountPoint as false
|
||||||
|
// except os.IsPermission.
|
||||||
|
// 2. When os.IsPermission is returned by MountedFast, List()
|
||||||
|
// is called to confirm if the given file is a mountpoint are not.
|
||||||
|
//
|
||||||
|
// os.ErrNotExist should always be returned if a file does not exist
|
||||||
|
// as callers have in past relied on this error and not fallback.
|
||||||
|
//
|
||||||
|
// When MountedFast returns sure as false and err as nil (eg: in
|
||||||
|
// case of bindmounts on kernel version 5.10- ); mounter.List()
|
||||||
|
// endpoint is called to enumerate all the mountpoints and check if
|
||||||
|
// it is mountpoint match or not.
|
||||||
|
func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
|
||||||
|
isMnt, sure, isMntErr := mountinfo.MountedFast(file)
|
||||||
|
if sure && isMntErr == nil {
|
||||||
|
return isMnt, nil
|
||||||
|
}
|
||||||
|
if isMntErr != nil {
|
||||||
|
if errors.Is(isMntErr, fs.ErrNotExist) {
|
||||||
|
return false, fs.ErrNotExist
|
||||||
|
}
|
||||||
|
// We were not allowed to do the simple stat() check, e.g. on NFS with
|
||||||
|
// root_squash. Fall back to /proc/mounts check below when
|
||||||
|
// fs.ErrPermission is returned.
|
||||||
|
if !errors.Is(isMntErr, fs.ErrPermission) {
|
||||||
|
return false, isMntErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Resolve any symlinks in file, kernel would do the same and use the resolved path in /proc/mounts.
|
||||||
|
resolvedFile, err := filepath.EvalSymlinks(file)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(isMntErr, fs.ErrNotExist) {
|
||||||
|
return false, fs.ErrNotExist
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check all mountpoints since MountedFast is not sure.
|
||||||
|
// is not reliable for some mountpoint types.
|
||||||
|
mountPoints, mountPointsErr := mounter.List()
|
||||||
|
if mountPointsErr != nil {
|
||||||
|
return false, mountPointsErr
|
||||||
|
}
|
||||||
|
for _, mp := range mountPoints {
|
||||||
|
if isMountPointMatch(mp, resolvedFile) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// tryUnmount calls plain "umount" and waits for unmountTimeout for it to finish.
|
// tryUnmount calls plain "umount" and waits for unmountTimeout for it to finish.
|
||||||
func tryUnmount(path string, unmountTimeout time.Duration) error {
|
func tryUnmount(path string, unmountTimeout time.Duration) error {
|
||||||
klog.V(4).Infof("Unmounting %s", path)
|
klog.V(4).Infof("Unmounting %s", path)
|
||||||
|
@ -79,6 +79,12 @@ func (mounter *Mounter) canSafelySkipMountPointCheck() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsMountPoint determines if a directory is a mountpoint.
|
||||||
|
// It always returns an error on unsupported platforms.
|
||||||
|
func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
|
||||||
|
return false, errUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
// GetMountRefs always returns an error on unsupported platforms
|
// GetMountRefs always returns an error on unsupported platforms
|
||||||
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
||||||
return nil, errUnsupported
|
return nil, errUnsupported
|
||||||
@ -91,3 +97,9 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target
|
|||||||
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
|
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
|
||||||
return true, errUnsupported
|
return true, errUnsupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsMountPoint determines if a directory is a mountpoint.
|
||||||
|
// It always returns an error on unsupported platforms.
|
||||||
|
func (mounter *SafeFormatAndMount) IsMountPoint(file string) (bool, error) {
|
||||||
|
return false, errUnsupported
|
||||||
|
}
|
||||||
|
@ -249,6 +249,15 @@ func (mounter *Mounter) canSafelySkipMountPointCheck() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsMountPoint: determines if a directory is a mountpoint.
|
||||||
|
func (mounter *Mounter) IsMountPoint(file string) (bool, error) {
|
||||||
|
isNotMnt, err := mounter.IsLikelyNotMountPoint(file)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return !isNotMnt, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows
|
// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows
|
||||||
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
|
||||||
windowsPath := NormalizeWindowsPath(pathname)
|
windowsPath := NormalizeWindowsPath(pathname)
|
||||||
|
Loading…
Reference in New Issue
Block a user