diff --git a/archive/tar_unix.go b/archive/tar_unix.go index c7b08e81c..6e89d2fdb 100644 --- a/archive/tar_unix.go +++ b/archive/tar_unix.go @@ -22,7 +22,6 @@ import ( "archive/tar" "os" "strings" - "sync" "syscall" "github.com/containerd/containerd/sys" @@ -84,21 +83,11 @@ func mkdir(path string, perm os.FileMode) error { return os.Chmod(path, perm) } -var ( - inUserNS bool - nsOnce sync.Once -) - -func setInUserNS() { - inUserNS = sys.RunningInUserNS() -} - func skipFile(hdr *tar.Header) bool { switch hdr.Typeflag { case tar.TypeBlock, tar.TypeChar: // cannot create a device if running in user namespace - nsOnce.Do(setInUserNS) - return inUserNS + return sys.RunningInUserNS() default: return false } diff --git a/sys/userns_linux.go b/sys/userns_linux.go index 534253ad8..3cd1a2222 100644 --- a/sys/userns_linux.go +++ b/sys/userns_linux.go @@ -20,34 +20,43 @@ import ( "bufio" "fmt" "os" + "sync" +) + +var ( + inUserNS bool + nsOnce sync.Once ) // RunningInUserNS detects whether we are currently running in a user namespace. // Originally copied from github.com/lxc/lxd/shared/util.go func RunningInUserNS() bool { - file, err := os.Open("/proc/self/uid_map") - if err != nil { - // This kernel-provided file only exists if user namespaces are supported - return false - } - defer file.Close() + nsOnce.Do(func() { + file, err := os.Open("/proc/self/uid_map") + if err != nil { + // This kernel-provided file only exists if user namespaces are supported + return + } + defer file.Close() - buf := bufio.NewReader(file) - l, _, err := buf.ReadLine() - if err != nil { - return false - } + buf := bufio.NewReader(file) + l, _, err := buf.ReadLine() + if err != nil { + return + } - line := string(l) - var a, b, c int64 - fmt.Sscanf(line, "%d %d %d", &a, &b, &c) + line := string(l) + var a, b, c int64 + fmt.Sscanf(line, "%d %d %d", &a, &b, &c) - /* - * We assume we are in the initial user namespace if we have a full - * range - 4294967295 uids starting at uid 0. - */ - if a == 0 && b == 0 && c == 4294967295 { - return false - } - return true + /* + * We assume we are in the initial user namespace if we have a full + * range - 4294967295 uids starting at uid 0. + */ + if a == 0 && b == 0 && c == 4294967295 { + return + } + inUserNS = true + }) + return inUserNS }