| ... | ... |
@@ -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 {
|