sys: RunningInUserNS(): use sync.Once

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2020-05-04 15:35:13 +02:00
parent 76c62f2722
commit 0088c2de80
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
2 changed files with 32 additions and 34 deletions

View File

@ -22,7 +22,6 @@ import (
"archive/tar" "archive/tar"
"os" "os"
"strings" "strings"
"sync"
"syscall" "syscall"
"github.com/containerd/containerd/sys" "github.com/containerd/containerd/sys"
@ -84,21 +83,11 @@ func mkdir(path string, perm os.FileMode) error {
return os.Chmod(path, perm) return os.Chmod(path, perm)
} }
var (
inUserNS bool
nsOnce sync.Once
)
func setInUserNS() {
inUserNS = sys.RunningInUserNS()
}
func skipFile(hdr *tar.Header) bool { func skipFile(hdr *tar.Header) bool {
switch hdr.Typeflag { switch hdr.Typeflag {
case tar.TypeBlock, tar.TypeChar: case tar.TypeBlock, tar.TypeChar:
// cannot create a device if running in user namespace // cannot create a device if running in user namespace
nsOnce.Do(setInUserNS) return sys.RunningInUserNS()
return inUserNS
default: default:
return false return false
} }

View File

@ -20,34 +20,43 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"os" "os"
"sync"
)
var (
inUserNS bool
nsOnce sync.Once
) )
// RunningInUserNS detects whether we are currently running in a user namespace. // RunningInUserNS detects whether we are currently running in a user namespace.
// Originally copied from github.com/lxc/lxd/shared/util.go // Originally copied from github.com/lxc/lxd/shared/util.go
func RunningInUserNS() bool { func RunningInUserNS() bool {
file, err := os.Open("/proc/self/uid_map") nsOnce.Do(func() {
if err != nil { file, err := os.Open("/proc/self/uid_map")
// This kernel-provided file only exists if user namespaces are supported if err != nil {
return false // This kernel-provided file only exists if user namespaces are supported
} return
defer file.Close() }
defer file.Close()
buf := bufio.NewReader(file) buf := bufio.NewReader(file)
l, _, err := buf.ReadLine() l, _, err := buf.ReadLine()
if err != nil { if err != nil {
return false return
} }
line := string(l) line := string(l)
var a, b, c int64 var a, b, c int64
fmt.Sscanf(line, "%d %d %d", &a, &b, &c) fmt.Sscanf(line, "%d %d %d", &a, &b, &c)
/* /*
* We assume we are in the initial user namespace if we have a full * We assume we are in the initial user namespace if we have a full
* range - 4294967295 uids starting at uid 0. * range - 4294967295 uids starting at uid 0.
*/ */
if a == 0 && b == 0 && c == 4294967295 { if a == 0 && b == 0 && c == 4294967295 {
return false return
} }
return true inUserNS = true
})
return inUserNS
} }