Merge pull request #106906 from tsmetana/k8s-fix-azure-subpath

mount-utils: Detect potential stale file handle
This commit is contained in:
Kubernetes Prow Robot 2021-12-10 11:05:22 -08:00 committed by GitHub
commit 9629ac6d2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 14 deletions

View File

@ -135,17 +135,3 @@ func removePathIfNotMountPoint(mountPath string, mounter Interface, extensiveMou
} }
return notMnt, nil return notMnt, nil
} }
// PathExists returns true if the specified path exists.
// TODO: clean this up to use pkg/util/file/FileExists
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
} else if os.IsNotExist(err) {
return false, nil
} else if IsCorruptedMnt(err) {
return true, err
}
return false, err
}

View File

@ -20,12 +20,15 @@ limitations under the License.
package mount package mount
import ( import (
"errors"
"fmt" "fmt"
"io/fs"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
"k8s.io/klog/v2"
utilio "k8s.io/utils/io" utilio "k8s.io/utils/io"
) )
@ -51,6 +54,8 @@ func IsCorruptedMnt(err error) bool {
underlyingError = pe.Err underlyingError = pe.Err
case *os.SyscallError: case *os.SyscallError:
underlyingError = pe.Err underlyingError = pe.Err
case syscall.Errno:
underlyingError = err
} }
return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES || underlyingError == syscall.EHOSTDOWN return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES || underlyingError == syscall.EHOSTDOWN
@ -157,3 +162,26 @@ func isMountPointMatch(mp MountPoint, dir string) bool {
deletedDir := fmt.Sprintf("%s\\040(deleted)", dir) deletedDir := fmt.Sprintf("%s\\040(deleted)", dir)
return ((mp.Path == dir) || (mp.Path == deletedDir)) return ((mp.Path == dir) || (mp.Path == deletedDir))
} }
// PathExists returns true if the specified path exists.
// TODO: clean this up to use pkg/util/file/FileExists
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
} else if errors.Is(err, fs.ErrNotExist) {
err = syscall.Access(path, syscall.F_OK)
if err == nil {
// The access syscall says the file exists, the stat syscall says it
// doesn't. This was observed on CIFS when the path was removed at
// the server somehow. POSIX calls this a stale file handle, let's fake
// that error and treat the path as existing but corrupted.
klog.Warningf("Potential stale file handle detected: %s", path)
return true, syscall.ESTALE
}
return false, nil
} else if IsCorruptedMnt(err) {
return true, err
}
return false, err
}

View File

@ -95,3 +95,17 @@ func ValidateDiskNumber(disk string) error {
func isMountPointMatch(mp MountPoint, dir string) bool { func isMountPointMatch(mp MountPoint, dir string) bool {
return mp.Path == dir return mp.Path == dir
} }
// PathExists returns true if the specified path exists.
// TODO: clean this up to use pkg/util/file/FileExists
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
} else if os.IsNotExist(err) {
return false, nil
} else if IsCorruptedMnt(err) {
return true, err
}
return false, err
}