From adbe3096e8c8572925dbae5f19ac2ce2dc84fb1c Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 12 May 2014 17:44:57 -0700 Subject: [PATCH] Add cpuset cpus support for docker Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- daemon/container.go | 1 + daemon/execdriver/driver.go | 7 ++++--- daemon/execdriver/lxc/lxc_template.go | 3 +++ daemon/execdriver/native/create.go | 1 + docs/sources/reference/commandline/cli.md | 1 + integration-cli/docker_cli_run_test.go | 11 +++++++++++ runconfig/config.go | 8 +++++--- runconfig/parse.go | 2 ++ 8 files changed, 28 insertions(+), 6 deletions(-) diff --git a/daemon/container.go b/daemon/container.go index 7b6b65494e..b8743f4d08 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -215,6 +215,7 @@ func populateCommand(c *Container, env []string) error { Memory: c.Config.Memory, MemorySwap: c.Config.MemorySwap, CpuShares: c.Config.CpuShares, + Cpuset: c.Config.Cpuset, } c.command = &execdriver.Command{ ID: c.ID, diff --git a/daemon/execdriver/driver.go b/daemon/execdriver/driver.go index 4837a398ea..a3e43e60ac 100644 --- a/daemon/execdriver/driver.go +++ b/daemon/execdriver/driver.go @@ -103,9 +103,10 @@ type NetworkInterface struct { } type Resources struct { - Memory int64 `json:"memory"` - MemorySwap int64 `json:"memory_swap"` - CpuShares int64 `json:"cpu_shares"` + Memory int64 `json:"memory"` + MemorySwap int64 `json:"memory_swap"` + CpuShares int64 `json:"cpu_shares"` + Cpuset string `json:"cpuset"` } type Mount struct { diff --git a/daemon/execdriver/lxc/lxc_template.go b/daemon/execdriver/lxc/lxc_template.go index d40b316768..f2364cb77f 100644 --- a/daemon/execdriver/lxc/lxc_template.go +++ b/daemon/execdriver/lxc/lxc_template.go @@ -127,6 +127,9 @@ lxc.cgroup.memory.memsw.limit_in_bytes = {{$memSwap}} {{if .Resources.CpuShares}} lxc.cgroup.cpu.shares = {{.Resources.CpuShares}} {{end}} +{{if .Resources.Cpuset}} +lxc.cgroup.cpuset.cpus = {{.Resources.Cpuset}} +{{end}} {{end}} {{if .Config.lxc}} diff --git a/daemon/execdriver/native/create.go b/daemon/execdriver/native/create.go index a7b3d9a107..5adae30db5 100644 --- a/daemon/execdriver/native/create.go +++ b/daemon/execdriver/native/create.go @@ -117,6 +117,7 @@ func (d *driver) setupCgroups(container *libcontainer.Container, c *execdriver.C container.Cgroups.Memory = c.Resources.Memory container.Cgroups.MemoryReservation = c.Resources.Memory container.Cgroups.MemorySwap = c.Resources.MemorySwap + container.Cgroups.CpusetCpus = c.Resources.Cpuset } return nil } diff --git a/docs/sources/reference/commandline/cli.md b/docs/sources/reference/commandline/cli.md index 8e0507cbf8..cfa0c284cf 100644 --- a/docs/sources/reference/commandline/cli.md +++ b/docs/sources/reference/commandline/cli.md @@ -811,6 +811,7 @@ Run a command in a new container -a, --attach=[] Attach to stdin, stdout or stderr. -c, --cpu-shares=0 CPU shares (relative weight) + --cpuset="" CPUs in which to allow execution (0-3, 0,1) --cidfile="" Write the container ID to the file -d, --detach=false Detached mode: Run container in the background, print new container id --dns=[] Set custom dns servers diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index b9737feeea..a439c5f387 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -768,3 +768,14 @@ func TestProcWritableInPrivilegedContainers(t *testing.T) { logDone("run - proc writable in privileged container") } + +func TestRunWithCpuset(t *testing.T) { + cmd := exec.Command(dockerBinary, "run", "--cpuset", "0", "busybox", "true") + if code, err := runCommand(cmd); err != nil || code != 0 { + t.Fatalf("container should run successfuly with cpuset of 0: %s", err) + } + + deleteAllContainers() + + logDone("run - cpuset 0") +} diff --git a/runconfig/config.go b/runconfig/config.go index 33a7882b6f..8a069c64c7 100644 --- a/runconfig/config.go +++ b/runconfig/config.go @@ -12,9 +12,10 @@ type Config struct { Hostname string Domainname string User string - Memory int64 // Memory limit (in bytes) - MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap - CpuShares int64 // CPU shares (relative weight vs. other containers) + Memory int64 // Memory limit (in bytes) + MemorySwap int64 // Total memory usage (memory + swap); set `-1' to disable swap + CpuShares int64 // CPU shares (relative weight vs. other containers) + Cpuset string // Cpuset 0-2, 0,1 AttachStdin bool AttachStdout bool AttachStderr bool @@ -41,6 +42,7 @@ func ContainerConfigFromJob(job *engine.Job) *Config { Memory: job.GetenvInt64("Memory"), MemorySwap: job.GetenvInt64("MemorySwap"), CpuShares: job.GetenvInt64("CpuShares"), + Cpuset: job.Getenv("Cpuset"), AttachStdin: job.GetenvBool("AttachStdin"), AttachStdout: job.GetenvBool("AttachStdout"), AttachStderr: job.GetenvBool("AttachStderr"), diff --git a/runconfig/parse.go b/runconfig/parse.go index 5a588c0344..8c4b9dcc14 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -63,6 +63,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf flUser = cmd.String([]string{"u", "-user"}, "", "Username or UID") flWorkingDir = cmd.String([]string{"w", "-workdir"}, "", "Working directory inside the container") flCpuShares = cmd.Int64([]string{"c", "-cpu-shares"}, 0, "CPU shares (relative weight)") + flCpuset = cmd.String([]string{"-cpuset"}, "", "CPUs in which to allow execution (0-3, 0,1)") flNetMode = cmd.String([]string{"-net"}, "bridge", "Set the Network mode for the container\n'bridge': creates a new network stack for the container on the docker bridge\n'none': no networking for this container\n'container:': reuses another container network stack\n'host': use the host network stack inside the contaner") // For documentation purpose _ = cmd.Bool([]string{"#sig-proxy", "-sig-proxy"}, true, "Proxify all received signal to the process (even in non-tty mode)") @@ -219,6 +220,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf OpenStdin: *flStdin, Memory: flMemory, CpuShares: *flCpuShares, + Cpuset: *flCpuset, AttachStdin: flAttach.Get("stdin"), AttachStdout: flAttach.Get("stdout"), AttachStderr: flAttach.Get("stderr"),