Browse code

Add capabilities check to allow docker to run on kernel that does not have all options

Guillaume J. Charmes authored on 2013/04/19 12:55:41
Showing 3 changed files
... ...
@@ -907,7 +907,7 @@ func (srv *Server) CmdTag(stdin io.ReadCloser, stdout io.Writer, args ...string)
907 907
 }
908 908
 
909 909
 func (srv *Server) CmdRun(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
910
-	config, err := ParseRun(args, stdout)
910
+	config, err := ParseRun(args, stdout, srv.runtime.capabilities)
911 911
 	if err != nil {
912 912
 		return err
913 913
 	}
... ...
@@ -66,7 +66,7 @@ type Config struct {
66 66
 	Image        string // Name of the image as it was passed by the operator (eg. could be symbolic)
67 67
 }
68 68
 
69
-func ParseRun(args []string, stdout io.Writer) (*Config, error) {
69
+func ParseRun(args []string, stdout io.Writer, capabilities *Capabilities) (*Config, error) {
70 70
 	cmd := rcli.Subcmd(stdout, "run", "[OPTIONS] IMAGE COMMAND [ARG...]", "Run a command in a new container")
71 71
 	if len(args) > 0 && args[0] != "--help" {
72 72
 		cmd.SetOutput(ioutil.Discard)
... ...
@@ -81,8 +81,8 @@ func ParseRun(args []string, stdout io.Writer) (*Config, error) {
81 81
 	flTty := cmd.Bool("t", false, "Allocate a pseudo-tty")
82 82
 	flMemory := cmd.Int64("m", 0, "Memory limit (in bytes)")
83 83
 
84
-	if *flMemory > 0 && NO_MEMORY_LIMIT {
85
-		fmt.Fprintf(stdout, "WARNING: This version of docker has been compiled without memory limit support. Discarding -m.")
84
+	if *flMemory > 0 && !capabilities.MemoryLimit {
85
+		fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n")
86 86
 		*flMemory = 0
87 87
 	}
88 88
 
... ...
@@ -135,6 +135,12 @@ func ParseRun(args []string, stdout io.Writer) (*Config, error) {
135 135
 		Dns:          flDns,
136 136
 		Image:        image,
137 137
 	}
138
+
139
+	if *flMemory > 0 && !capabilities.SwapLimit {
140
+		fmt.Fprintf(stdout, "WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.\n")
141
+		config.MemorySwap = -1
142
+	}
143
+
138 144
 	// When allocating stdin in attached mode, close stdin at client disconnect
139 145
 	if config.OpenStdin && config.AttachStdin {
140 146
 		config.StdinOnce = true
... ...
@@ -15,6 +15,11 @@ import (
15 15
 	"time"
16 16
 )
17 17
 
18
+type Capabilities struct {
19
+	MemoryLimit bool
20
+	SwapLimit   bool
21
+}
22
+
18 23
 type Runtime struct {
19 24
 	root           string
20 25
 	repository     string
... ...
@@ -24,6 +29,7 @@ type Runtime struct {
24 24
 	repositories   *TagStore
25 25
 	authConfig     *auth.AuthConfig
26 26
 	idIndex        *TruncIndex
27
+	capabilities   *Capabilities
27 28
 	kernelVersion  *KernelVersionInfo
28 29
 }
29 30
 
... ...
@@ -299,6 +305,13 @@ func NewRuntime() (*Runtime, error) {
299 299
 		log.Printf("WARNING: You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
300 300
 	}
301 301
 
302
+	_, err1 := ioutil.ReadFile("/sys/fs/cgroup/memory/memory.limit_in_bytes")
303
+	_, err2 := ioutil.ReadFile("/sys/fs/cgroup/memory/memory.soft_limit_in_bytes")
304
+	runtime.capabilities.MemoryLimit = err1 == nil && err2 == nil
305
+
306
+	_, err = ioutil.ReadFile("/sys/fs/cgroup/memory/memeory.memsw.limit_in_bytes")
307
+	runtime.capabilities.SwapLimit = err == nil
308
+
302 309
 	return runtime, nil
303 310
 }
304 311
 
... ...
@@ -338,6 +351,7 @@ func NewRuntimeFromDirectory(root string) (*Runtime, error) {
338 338
 		repositories:   repositories,
339 339
 		authConfig:     authConfig,
340 340
 		idIndex:        NewTruncIndex(),
341
+		capabilities:   &Capabilities{},
341 342
 	}
342 343
 
343 344
 	if err := runtime.restore(); err != nil {