From b52165315d1f987b2e23b3b5f41cb17512bedf3e Mon Sep 17 00:00:00 2001 From: Manu Gupta Date: Tue, 5 Apr 2022 16:56:34 -0700 Subject: [PATCH] Send Unix errors without wrapping them or casting them. While trying to import MountedFast into k8s to detect mount points using openat2, several tests failed because they rely on os.IsErrNotExist / os.IsPermission which do not actually test the underlying error. For a non-existent path, if we return the bare error, this problem is solved. I tested for the following cases to ensure that backward compatibility is not broken: fmt.Println(os.IsNotExist(err)) returns false fmt.Println(os.IsNotExist(&os.PathError{ Op: "lstat", Path: "somepath", Err: err, })) returns false fmt.Println(os.IsNotExist(fmt.Errorf("unable: %w", err))) returns false fmt.Println(errors.Is(fmt.Errorf("unable: %w", err), os.ErrNotExist)) returns true. Signed-off-by: Manu Gupta --- mountinfo/mounted_linux.go | 4 ++-- mountinfo/mounted_unix.go | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/mountinfo/mounted_linux.go b/mountinfo/mounted_linux.go index bf221e68..8f1a672e 100644 --- a/mountinfo/mounted_linux.go +++ b/mountinfo/mounted_linux.go @@ -44,7 +44,7 @@ func mountedByOpenat2(path string) (bool, error) { Flags: unix.O_PATH | unix.O_CLOEXEC, }) if err != nil { - return false, &os.PathError{Op: "openat2", Path: dir, Err: err} + return false, err } fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{ Flags: unix.O_PATH | unix.O_CLOEXEC | unix.O_NOFOLLOW, @@ -59,7 +59,7 @@ func mountedByOpenat2(path string) (bool, error) { return true, nil } // not sure - return false, &os.PathError{Op: "openat2", Path: path, Err: err} + return false, err } // mountedFast is similar to MountedFast, except it expects a normalized path. diff --git a/mountinfo/mounted_unix.go b/mountinfo/mounted_unix.go index 45ddad23..d0294697 100644 --- a/mountinfo/mounted_unix.go +++ b/mountinfo/mounted_unix.go @@ -4,7 +4,6 @@ package mountinfo import ( - "fmt" "os" "path/filepath" @@ -15,12 +14,12 @@ func mountedByStat(path string) (bool, error) { var st unix.Stat_t if err := unix.Lstat(path, &st); err != nil { - return false, &os.PathError{Op: "stat", Path: path, Err: err} + return false, err } dev := st.Dev parent := filepath.Dir(path) if err := unix.Lstat(parent, &st); err != nil { - return false, &os.PathError{Op: "stat", Path: parent, Err: err} + return false, err } if dev != st.Dev { // Device differs from that of parent, @@ -33,13 +32,13 @@ func mountedByStat(path string) (bool, error) { func normalizePath(path string) (realPath string, err error) { if realPath, err = filepath.Abs(path); err != nil { - return "", fmt.Errorf("unable to get absolute path for %q: %w", path, err) + return "", err } if realPath, err = filepath.EvalSymlinks(realPath); err != nil { - return "", fmt.Errorf("failed to canonicalise path for %q: %w", path, err) + return "", err } if _, err := os.Stat(realPath); err != nil { - return "", fmt.Errorf("failed to stat target of %q: %w", path, err) + return "", err } return realPath, nil }