Browse code

Move sysinfo out of daemon struct

sysinfo struct was initialized at daemon startup to make sure
kernel configs such as device cgroup are present and error out if not.
The struct was embedded in daemon struct making impossible to detect
if some system config is changed at daemon runtime (i.e. someone
umount the memory cgroup). This leads to container's starts failure if
some config is changed at daemon runtime.
This patch moves sysinfo out of daemon and initilize and check it when
needed (daemon startup, containers creation, contaienrs startup for
now).

Signed-off-by: Antonio Murdaca <runcom@linux.com>
(cherry picked from commit 472b6f66e03f9a85fe8d23098dac6f55a87456d8)

Antonio Murdaca authored on 2015/08/06 20:54:48
Showing 4 changed files
... ...
@@ -92,7 +92,6 @@ type Daemon struct {
92 92
 	graph            *graph.Graph
93 93
 	repositories     *graph.TagStore
94 94
 	idIndex          *truncindex.TruncIndex
95
-	sysInfo          *sysinfo.SysInfo
96 95
 	config           *Config
97 96
 	containerGraph   *graphdb.Database
98 97
 	driver           graphdriver.Driver
... ...
@@ -725,7 +724,6 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
725 725
 	d.graph = g
726 726
 	d.repositories = repositories
727 727
 	d.idIndex = truncindex.NewTruncIndex([]string{})
728
-	d.sysInfo = sysInfo
729 728
 	d.config = config
730 729
 	d.sysInitPath = sysInitPath
731 730
 	d.execDriver = ed
... ...
@@ -858,10 +856,6 @@ func (daemon *Daemon) Config() *Config {
858 858
 	return daemon.config
859 859
 }
860 860
 
861
-func (daemon *Daemon) SystemConfig() *sysinfo.SysInfo {
862
-	return daemon.sysInfo
863
-}
864
-
865 861
 func (daemon *Daemon) SystemInitPath() string {
866 862
 	return daemon.sysInitPath
867 863
 }
... ...
@@ -18,6 +18,7 @@ import (
18 18
 	"github.com/docker/docker/pkg/fileutils"
19 19
 	"github.com/docker/docker/pkg/parsers"
20 20
 	"github.com/docker/docker/pkg/parsers/kernel"
21
+	"github.com/docker/docker/pkg/sysinfo"
21 22
 	"github.com/docker/docker/pkg/system"
22 23
 	"github.com/docker/docker/runconfig"
23 24
 	"github.com/docker/docker/utils"
... ...
@@ -148,7 +149,8 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *runconfig.HostConfig, a
148 148
 // verifyPlatformContainerSettings performs platform-specific validation of the
149 149
 // hostconfig and config structures.
150 150
 func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
151
-	var warnings []string
151
+	warnings := []string{}
152
+	sysInfo := sysinfo.New(false)
152 153
 
153 154
 	if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver().Name(), "lxc") {
154 155
 		return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver().Name())
... ...
@@ -156,12 +158,12 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
156 156
 	if hostConfig.Memory != 0 && hostConfig.Memory < 4194304 {
157 157
 		return warnings, fmt.Errorf("Minimum memory limit allowed is 4MB")
158 158
 	}
159
-	if hostConfig.Memory > 0 && !daemon.SystemConfig().MemoryLimit {
159
+	if hostConfig.Memory > 0 && !sysInfo.MemoryLimit {
160 160
 		warnings = append(warnings, "Your kernel does not support memory limit capabilities. Limitation discarded.")
161 161
 		logrus.Warnf("Your kernel does not support memory limit capabilities. Limitation discarded.")
162 162
 		hostConfig.Memory = 0
163 163
 	}
164
-	if hostConfig.Memory > 0 && hostConfig.MemorySwap != -1 && !daemon.SystemConfig().SwapLimit {
164
+	if hostConfig.Memory > 0 && hostConfig.MemorySwap != -1 && !sysInfo.SwapLimit {
165 165
 		warnings = append(warnings, "Your kernel does not support swap limit capabilities, memory limited without swap.")
166 166
 		logrus.Warnf("Your kernel does not support swap limit capabilities, memory limited without swap.")
167 167
 		hostConfig.MemorySwap = -1
... ...
@@ -172,7 +174,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
172 172
 	if hostConfig.Memory == 0 && hostConfig.MemorySwap > 0 {
173 173
 		return warnings, fmt.Errorf("You should always set the Memory limit when using Memoryswap limit, see usage.")
174 174
 	}
175
-	if hostConfig.MemorySwappiness != nil && !daemon.SystemConfig().MemorySwappiness {
175
+	if hostConfig.MemorySwappiness != nil && !sysInfo.MemorySwappiness {
176 176
 		warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, memory swappiness discarded.")
177 177
 		logrus.Warnf("Your kernel does not support memory swappiness capabilities, memory swappiness discarded.")
178 178
 		hostConfig.MemorySwappiness = nil
... ...
@@ -183,28 +185,28 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
183 183
 			return warnings, fmt.Errorf("Invalid value: %v, valid memory swappiness range is 0-100.", swappiness)
184 184
 		}
185 185
 	}
186
-	if hostConfig.CPUShares > 0 && !daemon.SystemConfig().CPUShares {
186
+	if hostConfig.CPUShares > 0 && !sysInfo.CPUShares {
187 187
 		warnings = append(warnings, "Your kernel does not support CPU shares. Shares discarded.")
188 188
 		logrus.Warnf("Your kernel does not support CPU shares. Shares discarded.")
189 189
 		hostConfig.CPUShares = 0
190 190
 	}
191
-	if hostConfig.CPUPeriod > 0 && !daemon.SystemConfig().CPUCfsPeriod {
191
+	if hostConfig.CPUPeriod > 0 && !sysInfo.CPUCfsPeriod {
192 192
 		warnings = append(warnings, "Your kernel does not support CPU cfs period. Period discarded.")
193 193
 		logrus.Warnf("Your kernel does not support CPU cfs period. Period discarded.")
194 194
 		hostConfig.CPUPeriod = 0
195 195
 	}
196
-	if hostConfig.CPUQuota > 0 && !daemon.SystemConfig().CPUCfsQuota {
196
+	if hostConfig.CPUQuota > 0 && !sysInfo.CPUCfsQuota {
197 197
 		warnings = append(warnings, "Your kernel does not support CPU cfs quota. Quota discarded.")
198 198
 		logrus.Warnf("Your kernel does not support CPU cfs quota. Quota discarded.")
199 199
 		hostConfig.CPUQuota = 0
200 200
 	}
201
-	if (hostConfig.CpusetCpus != "" || hostConfig.CpusetMems != "") && !daemon.SystemConfig().Cpuset {
201
+	if (hostConfig.CpusetCpus != "" || hostConfig.CpusetMems != "") && !sysInfo.Cpuset {
202 202
 		warnings = append(warnings, "Your kernel does not support cpuset. Cpuset discarded.")
203 203
 		logrus.Warnf("Your kernel does not support cpuset. Cpuset discarded.")
204 204
 		hostConfig.CpusetCpus = ""
205 205
 		hostConfig.CpusetMems = ""
206 206
 	}
207
-	if hostConfig.BlkioWeight > 0 && !daemon.SystemConfig().BlkioWeight {
207
+	if hostConfig.BlkioWeight > 0 && !sysInfo.BlkioWeight {
208 208
 		warnings = append(warnings, "Your kernel does not support Block I/O weight. Weight discarded.")
209 209
 		logrus.Warnf("Your kernel does not support Block I/O weight. Weight discarded.")
210 210
 		hostConfig.BlkioWeight = 0
... ...
@@ -212,11 +214,11 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
212 212
 	if hostConfig.BlkioWeight > 0 && (hostConfig.BlkioWeight < 10 || hostConfig.BlkioWeight > 1000) {
213 213
 		return warnings, fmt.Errorf("Range of blkio weight is from 10 to 1000.")
214 214
 	}
215
-	if hostConfig.OomKillDisable && !daemon.SystemConfig().OomKillDisable {
215
+	if hostConfig.OomKillDisable && !sysInfo.OomKillDisable {
216 216
 		hostConfig.OomKillDisable = false
217 217
 		return warnings, fmt.Errorf("Your kernel does not support oom kill disable.")
218 218
 	}
219
-	if daemon.SystemConfig().IPv4ForwardingDisabled {
219
+	if sysInfo.IPv4ForwardingDisabled {
220 220
 		warnings = append(warnings, "IPv4 forwarding is disabled. Networking will not work.")
221 221
 		logrus.Warnf("IPv4 forwarding is disabled. Networking will not work")
222 222
 	}
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"github.com/docker/docker/pkg/fileutils"
12 12
 	"github.com/docker/docker/pkg/parsers/kernel"
13 13
 	"github.com/docker/docker/pkg/parsers/operatingsystem"
14
+	"github.com/docker/docker/pkg/sysinfo"
14 15
 	"github.com/docker/docker/pkg/system"
15 16
 	"github.com/docker/docker/registry"
16 17
 	"github.com/docker/docker/utils"
... ...
@@ -56,15 +57,17 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
56 56
 		initPath = daemon.SystemInitPath()
57 57
 	}
58 58
 
59
+	sysInfo := sysinfo.New(false)
60
+
59 61
 	v := &types.Info{
60 62
 		ID:                 daemon.ID,
61 63
 		Containers:         len(daemon.List()),
62 64
 		Images:             imgcount,
63 65
 		Driver:             daemon.GraphDriver().String(),
64 66
 		DriverStatus:       daemon.GraphDriver().Status(),
65
-		IPv4Forwarding:     !daemon.SystemConfig().IPv4ForwardingDisabled,
66
-		BridgeNfIptables:   !daemon.SystemConfig().BridgeNfCallIptablesDisabled,
67
-		BridgeNfIp6tables:  !daemon.SystemConfig().BridgeNfCallIP6tablesDisabled,
67
+		IPv4Forwarding:     !sysInfo.IPv4ForwardingDisabled,
68
+		BridgeNfIptables:   !sysInfo.BridgeNfCallIptablesDisabled,
69
+		BridgeNfIp6tables:  !sysInfo.BridgeNfCallIP6tablesDisabled,
68 70
 		Debug:              os.Getenv("DEBUG") != "",
69 71
 		NFd:                fileutils.GetTotalUsedFds(),
70 72
 		NGoroutines:        runtime.NumGoroutine(),
... ...
@@ -90,11 +93,11 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
90 90
 	// sysinfo.cgroupCpuInfo will be nil otherwise and cause a SIGSEGV if
91 91
 	// an attempt is made to access through them.
92 92
 	if runtime.GOOS != "windows" {
93
-		v.MemoryLimit = daemon.SystemConfig().MemoryLimit
94
-		v.SwapLimit = daemon.SystemConfig().SwapLimit
95
-		v.OomKillDisable = daemon.SystemConfig().OomKillDisable
96
-		v.CpuCfsPeriod = daemon.SystemConfig().CPUCfsPeriod
97
-		v.CpuCfsQuota = daemon.SystemConfig().CPUCfsQuota
93
+		v.MemoryLimit = sysInfo.MemoryLimit
94
+		v.SwapLimit = sysInfo.SwapLimit
95
+		v.OomKillDisable = sysInfo.OomKillDisable
96
+		v.CpuCfsPeriod = sysInfo.CPUCfsPeriod
97
+		v.CpuCfsQuota = sysInfo.CPUCfsQuota
98 98
 	}
99 99
 
100 100
 	if httpProxy := os.Getenv("http_proxy"); httpProxy != "" {
... ...
@@ -10,7 +10,9 @@ import (
10 10
 	"github.com/opencontainers/runc/libcontainer/cgroups"
11 11
 )
12 12
 
13
-// New returns a new SysInfo, using the filesystem to detect which features the kernel supports.
13
+// New returns a new SysInfo, using the filesystem to detect which features
14
+// the kernel supports. If `quiet` is `false` warnings are printed in logs
15
+// whenever an error occurs or misconfigurations are present.
14 16
 func New(quiet bool) *SysInfo {
15 17
 	sysInfo := &SysInfo{}
16 18
 	sysInfo.cgroupMemInfo = checkCgroupMem(quiet)