Переглянути джерело

Add cpuset.cpus to cgroups and native driver options
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby 11 роки тому
батько
коміт
9a7be1b015
2 змінених файлів з 57 додано та 10 видалено
  1. 28 4
      pkg/cgroups/cgroups.go
  2. 29 6
      runtime/execdriver/native/configuration/parse.go

+ 28 - 4
pkg/cgroups/cgroups.go

@@ -16,10 +16,11 @@ type Cgroup struct {
 	Name   string `json:"name,omitempty"`
 	Name   string `json:"name,omitempty"`
 	Parent string `json:"parent,omitempty"`
 	Parent string `json:"parent,omitempty"`
 
 
-	DeviceAccess bool  `json:"device_access,omitempty"` // name of parent cgroup or slice
-	Memory       int64 `json:"memory,omitempty"`        // Memory limit (in bytes)
-	MemorySwap   int64 `json:"memory_swap,omitempty"`   // Total memory usage (memory + swap); set `-1' to disable swap
-	CpuShares    int64 `json:"cpu_shares,omitempty"`    // CPU shares (relative weight vs. other containers)
+	DeviceAccess bool   `json:"device_access,omitempty"` // name of parent cgroup or slice
+	Memory       int64  `json:"memory,omitempty"`        // Memory limit (in bytes)
+	MemorySwap   int64  `json:"memory_swap,omitempty"`   // Total memory usage (memory + swap); set `-1' to disable swap
+	CpuShares    int64  `json:"cpu_shares,omitempty"`    // CPU shares (relative weight vs. other containers)
+	CpusetCpus   string `json:"cpuset_cpus,omitempty"`   // CPU to use
 }
 }
 
 
 // https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
 // https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
@@ -98,6 +99,7 @@ func (c *Cgroup) Cleanup(root string) error {
 		get("memory"),
 		get("memory"),
 		get("devices"),
 		get("devices"),
 		get("cpu"),
 		get("cpu"),
+		get("cpuset"),
 	} {
 	} {
 		os.RemoveAll(path)
 		os.RemoveAll(path)
 	}
 	}
@@ -150,6 +152,9 @@ func (c *Cgroup) Apply(pid int) error {
 	if err := c.setupCpu(cgroupRoot, pid); err != nil {
 	if err := c.setupCpu(cgroupRoot, pid); err != nil {
 		return err
 		return err
 	}
 	}
+	if err := c.setupCpuset(cgroupRoot, pid); err != nil {
+		return err
+	}
 	return nil
 	return nil
 }
 }
 
 
@@ -248,3 +253,22 @@ func (c *Cgroup) setupCpu(cgroupRoot string, pid int) (err error) {
 	}
 	}
 	return nil
 	return nil
 }
 }
+
+func (c *Cgroup) setupCpuset(cgroupRoot string, pid int) (err error) {
+	if c.CpusetCpus != "" {
+		dir, err := c.Join(cgroupRoot, "cpuset", pid)
+		if err != nil {
+			return err
+		}
+		defer func() {
+			if err != nil {
+				os.RemoveAll(dir)
+			}
+		}()
+
+		if err := writeFile(dir, "cpuset.cpus", c.CpusetCpus); err != nil {
+			return err
+		}
+	}
+	return nil
+}

+ 29 - 6
runtime/execdriver/native/configuration/parse.go

@@ -3,6 +3,7 @@ package configuration
 import (
 import (
 	"fmt"
 	"fmt"
 	"github.com/dotcloud/docker/pkg/libcontainer"
 	"github.com/dotcloud/docker/pkg/libcontainer"
+	"github.com/dotcloud/docker/utils"
 	"os/exec"
 	"os/exec"
 	"path/filepath"
 	"path/filepath"
 	"strconv"
 	"strconv"
@@ -19,17 +20,40 @@ var actions = map[string]Action{
 	"ns.drop": dropNamespace, // drop a namespace when cloning
 	"ns.drop": dropNamespace, // drop a namespace when cloning
 
 
 	"net.join": joinNetNamespace, // join another containers net namespace
 	"net.join": joinNetNamespace, // join another containers net namespace
-	//	"net.veth.mac": vethMacAddress,   // set the mac address for the veth
 
 
 	"cgroups.cpu_shares":  cpuShares,  // set the cpu shares
 	"cgroups.cpu_shares":  cpuShares,  // set the cpu shares
 	"cgroups.memory":      memory,     // set the memory limit
 	"cgroups.memory":      memory,     // set the memory limit
 	"cgroups.memory_swap": memorySwap, // set the memory swap limit
 	"cgroups.memory_swap": memorySwap, // set the memory swap limit
+	"cgroups.cpuset.cpus": cpusetCpus, // set the cpus used
 
 
 	"apparmor_profile": apparmorProfile, // set the apparmor profile to apply
 	"apparmor_profile": apparmorProfile, // set the apparmor profile to apply
 
 
 	"fs.readonly": readonlyFs, // make the rootfs of the container read only
 	"fs.readonly": readonlyFs, // make the rootfs of the container read only
 }
 }
 
 
+// GetSupportedActions returns a list of all the avaliable actions supported by the driver
+// TODO: this should return a description also
+func GetSupportedActions() []string {
+	var (
+		i   int
+		out = make([]string, len(actions))
+	)
+	for k := range actions {
+		out[i] = k
+		i++
+	}
+	return out
+}
+
+func cpusetCpus(container *libcontainer.Container, context interface{}, value string) error {
+	if container.Cgroups == nil {
+		return fmt.Errorf("cannot set cgroups when they are disabled")
+	}
+	container.Cgroups.CpusetCpus = value
+
+	return nil
+}
+
 func apparmorProfile(container *libcontainer.Container, context interface{}, value string) error {
 func apparmorProfile(container *libcontainer.Container, context interface{}, value string) error {
 	container.Context["apparmor_profile"] = value
 	container.Context["apparmor_profile"] = value
 	return nil
 	return nil
@@ -39,7 +63,7 @@ func cpuShares(container *libcontainer.Container, context interface{}, value str
 	if container.Cgroups == nil {
 	if container.Cgroups == nil {
 		return fmt.Errorf("cannot set cgroups when they are disabled")
 		return fmt.Errorf("cannot set cgroups when they are disabled")
 	}
 	}
-	v, err := strconv.ParseInt(value, 0, 64)
+	v, err := strconv.ParseInt(value, 10, 0)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -51,7 +75,8 @@ func memory(container *libcontainer.Container, context interface{}, value string
 	if container.Cgroups == nil {
 	if container.Cgroups == nil {
 		return fmt.Errorf("cannot set cgroups when they are disabled")
 		return fmt.Errorf("cannot set cgroups when they are disabled")
 	}
 	}
-	v, err := strconv.ParseInt(value, 0, 64)
+
+	v, err := utils.RAMInBytes(value)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -138,7 +163,6 @@ func joinNetNamespace(container *libcontainer.Container, context interface{}, va
 
 
 func vethMacAddress(container *libcontainer.Container, context interface{}, value string) error {
 func vethMacAddress(container *libcontainer.Container, context interface{}, value string) error {
 	var veth *libcontainer.Network
 	var veth *libcontainer.Network
-
 	for _, network := range container.Networks {
 	for _, network := range container.Networks {
 		if network.Type == "veth" {
 		if network.Type == "veth" {
 			veth = network
 			veth = network
@@ -155,8 +179,7 @@ func vethMacAddress(container *libcontainer.Container, context interface{}, valu
 // configureCustomOptions takes string commands from the user and allows modification of the
 // configureCustomOptions takes string commands from the user and allows modification of the
 // container's default configuration.
 // container's default configuration.
 //
 //
-// format: <key> <...value>
-// i.e: cgroup devices.allow *:*
+// TODO: this can be moved to a general utils or parser in pkg
 func ParseConfiguration(container *libcontainer.Container, running map[string]*exec.Cmd, opts []string) error {
 func ParseConfiguration(container *libcontainer.Container, running map[string]*exec.Cmd, opts []string) error {
 	for _, opt := range opts {
 	for _, opt := range opts {
 		kv := strings.SplitN(opt, "=", 2)
 		kv := strings.SplitN(opt, "=", 2)