1// +build !windows
2
3package main
4
5import (
6	"bytes"
7	"io/ioutil"
8	"os/exec"
9	"strings"
10
11	"github.com/docker/docker/pkg/parsers/kernel"
12	"github.com/docker/docker/pkg/sysinfo"
13)
14
15var (
16	// SysInfo stores information about which features a kernel supports.
17	SysInfo *sysinfo.SysInfo
18)
19
20func cpuCfsPeriod() bool {
21	return testEnv.DaemonInfo.CPUCfsPeriod
22}
23
24func cpuCfsQuota() bool {
25	return testEnv.DaemonInfo.CPUCfsQuota
26}
27
28func cpuShare() bool {
29	return testEnv.DaemonInfo.CPUShares
30}
31
32func oomControl() bool {
33	return testEnv.DaemonInfo.OomKillDisable
34}
35
36func pidsLimit() bool {
37	return SysInfo.PidsLimit
38}
39
40func kernelMemorySupport() bool {
41	// TODO remove this once kmem support in RHEL kernels is fixed. See https://github.com/opencontainers/runc/pull/1921
42	daemonV, err := kernel.ParseRelease(testEnv.DaemonInfo.KernelVersion)
43	if err != nil {
44		return false
45	}
46	requiredV := kernel.VersionInfo{Kernel: 3, Major: 10}
47	if kernel.CompareKernelVersion(*daemonV, requiredV) < 1 {
48		// On Kernel 3.10 and under, don't consider kernel memory to be supported,
49		// even if the kernel (and thus the daemon) reports it as being supported
50		return false
51	}
52	return testEnv.DaemonInfo.KernelMemory
53}
54
55func memoryLimitSupport() bool {
56	return testEnv.DaemonInfo.MemoryLimit
57}
58
59func memoryReservationSupport() bool {
60	return SysInfo.MemoryReservation
61}
62
63func swapMemorySupport() bool {
64	return testEnv.DaemonInfo.SwapLimit
65}
66
67func memorySwappinessSupport() bool {
68	return SameHostDaemon() && SysInfo.MemorySwappiness
69}
70
71func blkioWeight() bool {
72	return SameHostDaemon() && SysInfo.BlkioWeight
73}
74
75func cgroupCpuset() bool {
76	return testEnv.DaemonInfo.CPUSet
77}
78
79func seccompEnabled() bool {
80	return supportsSeccomp && SysInfo.Seccomp
81}
82
83func bridgeNfIptables() bool {
84	return !SysInfo.BridgeNFCallIPTablesDisabled
85}
86
87func bridgeNfIP6tables() bool {
88	return !SysInfo.BridgeNFCallIP6TablesDisabled
89}
90
91func unprivilegedUsernsClone() bool {
92	content, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone")
93	return err != nil || !strings.Contains(string(content), "0")
94}
95
96func ambientCapabilities() bool {
97	content, err := ioutil.ReadFile("/proc/self/status")
98	return err != nil || strings.Contains(string(content), "CapAmb:")
99}
100
101func overlayFSSupported() bool {
102	cmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "/bin/sh", "-c", "cat /proc/filesystems")
103	out, err := cmd.CombinedOutput()
104	if err != nil {
105		return false
106	}
107	return bytes.Contains(out, []byte("overlay\n"))
108}
109
110func overlay2Supported() bool {
111	if !overlayFSSupported() {
112		return false
113	}
114
115	daemonV, err := kernel.ParseRelease(testEnv.DaemonInfo.KernelVersion)
116	if err != nil {
117		return false
118	}
119	requiredV := kernel.VersionInfo{Kernel: 4}
120	return kernel.CompareKernelVersion(*daemonV, requiredV) > -1
121
122}
123
124func init() {
125	if SameHostDaemon() {
126		SysInfo = sysinfo.New(true)
127	}
128}
129