Browse Source

Add hostConfig check before starting a container

It may happen that host system settings are changed while the daemon is running.
This will cause errors at libcontainer level when starting a container with a
particular hostConfig (e.g. hostConfig with memory swappiness but the memory
cgroup was umounted).
This patch adds an hostConfig check on container start to prevent the daemon
from even calling libcontainer with the wrong configuration as we're already
doing on container's creation).

Signed-off-by: Antonio Murdaca <runcom@linux.com>
(cherry picked from commit 0d2628cdf19783106ae8723f51fae0a7c7f361c6)
Antonio Murdaca 10 years ago
parent
commit
4177b0bae0
3 changed files with 16 additions and 9 deletions
  1. 6 1
      daemon/daemon_unix.go
  2. 6 4
      daemon/start.go
  3. 4 4
      runconfig/parse.go

+ 6 - 1
daemon/daemon_unix.go

@@ -155,6 +155,8 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
 	if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver().Name(), "lxc") {
 		return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver().Name())
 	}
+
+	// memory subsystem checks and adjustments
 	if hostConfig.Memory != 0 && hostConfig.Memory < 4194304 {
 		return warnings, fmt.Errorf("Minimum memory limit allowed is 4MB")
 	}
@@ -162,6 +164,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
 		warnings = append(warnings, "Your kernel does not support memory limit capabilities. Limitation discarded.")
 		logrus.Warnf("Your kernel does not support memory limit capabilities. Limitation discarded.")
 		hostConfig.Memory = 0
+		hostConfig.MemorySwap = -1
 	}
 	if hostConfig.Memory > 0 && hostConfig.MemorySwap != -1 && !sysInfo.SwapLimit {
 		warnings = append(warnings, "Your kernel does not support swap limit capabilities, memory limited without swap.")
@@ -174,7 +177,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
 	if hostConfig.Memory == 0 && hostConfig.MemorySwap > 0 {
 		return warnings, fmt.Errorf("You should always set the Memory limit when using Memoryswap limit, see usage.")
 	}
-	if hostConfig.MemorySwappiness != nil && !sysInfo.MemorySwappiness {
+	if hostConfig.MemorySwappiness != nil && *hostConfig.MemorySwappiness != -1 && !sysInfo.MemorySwappiness {
 		warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, memory swappiness discarded.")
 		logrus.Warnf("Your kernel does not support memory swappiness capabilities, memory swappiness discarded.")
 		hostConfig.MemorySwappiness = nil
@@ -214,10 +217,12 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
 	if hostConfig.BlkioWeight > 0 && (hostConfig.BlkioWeight < 10 || hostConfig.BlkioWeight > 1000) {
 		return warnings, fmt.Errorf("Range of blkio weight is from 10 to 1000.")
 	}
+
 	if hostConfig.OomKillDisable && !sysInfo.OomKillDisable {
 		hostConfig.OomKillDisable = false
 		return warnings, fmt.Errorf("Your kernel does not support oom kill disable.")
 	}
+
 	if sysInfo.IPv4ForwardingDisabled {
 		warnings = append(warnings, "IPv4 forwarding is disabled. Networking will not work.")
 		logrus.Warnf("IPv4 forwarding is disabled. Networking will not work")

+ 6 - 4
daemon/start.go

@@ -21,10 +21,6 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
 		return fmt.Errorf("Container already started")
 	}
 
-	if _, err = daemon.verifyContainerSettings(hostConfig, nil); err != nil {
-		return err
-	}
-
 	// Windows does not have the backwards compatibilty issue here.
 	if runtime.GOOS != "windows" {
 		// This is kept for backward compatibility - hostconfig should be passed when
@@ -40,6 +36,12 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
 		}
 	}
 
+	// check if hostConfig is in line with the current system settings.
+	// It may happen cgroups are umounted or the like.
+	if _, err = daemon.verifyContainerSettings(container.hostConfig, nil); err != nil {
+		return err
+	}
+
 	if err := container.Start(); err != nil {
 		return fmt.Errorf("Cannot start container %s: %s", name, err)
 	}

+ 4 - 4
runconfig/parse.go

@@ -188,16 +188,16 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		flMemory = parsedMemory
 	}
 
-	var MemorySwap int64
+	var memorySwap int64
 	if *flMemorySwap != "" {
 		if *flMemorySwap == "-1" {
-			MemorySwap = -1
+			memorySwap = -1
 		} else {
 			parsedMemorySwap, err := units.RAMInBytes(*flMemorySwap)
 			if err != nil {
 				return nil, nil, cmd, err
 			}
-			MemorySwap = parsedMemorySwap
+			memorySwap = parsedMemorySwap
 		}
 	}
 
@@ -354,7 +354,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		ContainerIDFile:  *flContainerIDFile,
 		LxcConf:          lxcConf,
 		Memory:           flMemory,
-		MemorySwap:       MemorySwap,
+		MemorySwap:       memorySwap,
 		CPUShares:        *flCPUShares,
 		CPUPeriod:        *flCPUPeriod,
 		CpusetCpus:       *flCpusetCpus,