Add support for blkio.weight_device

Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
This commit is contained in:
Ma Shimiao 2015-06-12 08:34:20 +08:00
parent 2a7b5f6657
commit 0fbfa1449d
21 changed files with 230 additions and 30 deletions

View File

@ -1355,6 +1355,7 @@ _docker_run() {
--add-host
--attach -a
--blkio-weight
--blkio-weight-device
--cap-add
--cap-drop
--cgroup-parent

View File

@ -418,6 +418,7 @@ __docker_subcommand() {
"($help -a --attach)"{-a=,--attach=}"[Attach to stdin, stdout or stderr]:device:(STDIN STDOUT STDERR)"
"($help)*--add-host=[Add a custom host-to-IP mapping]:host\:ip mapping: "
"($help)--blkio-weight=[Block IO (relative weight), between 10 and 1000]:Block IO weight:(10 100 500 1000)"
"($help)--blkio-weight-device=-[Block IO (relative device weight)]:device:Block IO weight: "
"($help)*--cap-add=[Add Linux capabilities]:capability: "
"($help)*--cap-drop=[Drop Linux capabilities]:capability: "
"($help)--cidfile=[Write the container ID to the file]:CID file:_files"

View File

@ -269,6 +269,11 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
}
}
weightDevices, err := getBlkioWeightDevices(c.hostConfig)
if err != nil {
return err
}
for _, limit := range ulimits {
rl, err := limit.GetRlimit()
if err != nil {
@ -284,15 +289,16 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
CPUShares: c.hostConfig.CPUShares,
BlkioWeight: c.hostConfig.BlkioWeight,
},
MemorySwap: c.hostConfig.MemorySwap,
KernelMemory: c.hostConfig.KernelMemory,
CpusetCpus: c.hostConfig.CpusetCpus,
CpusetMems: c.hostConfig.CpusetMems,
CPUPeriod: c.hostConfig.CPUPeriod,
CPUQuota: c.hostConfig.CPUQuota,
Rlimits: rlimits,
OomKillDisable: c.hostConfig.OomKillDisable,
MemorySwappiness: -1,
MemorySwap: c.hostConfig.MemorySwap,
KernelMemory: c.hostConfig.KernelMemory,
CpusetCpus: c.hostConfig.CpusetCpus,
CpusetMems: c.hostConfig.CpusetMems,
CPUPeriod: c.hostConfig.CPUPeriod,
CPUQuota: c.hostConfig.CPUQuota,
Rlimits: rlimits,
BlkioWeightDevice: weightDevices,
OomKillDisable: c.hostConfig.OomKillDisable,
MemorySwappiness: -1,
}
if c.hostConfig.MemorySwappiness != nil {

View File

@ -1202,6 +1202,7 @@ func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.
container.Lock()
defer container.Unlock()
// Register any links from the host config before starting the container
if err := daemon.registerLinks(container, hostConfig); err != nil {
return err

View File

@ -15,6 +15,7 @@ import (
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/dockerversion"
derr "github.com/docker/docker/errors"
pblkiodev "github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/parsers"
@ -30,6 +31,7 @@ import (
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
blkiodev "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/label"
"github.com/vishvananda/netlink"
)
@ -41,6 +43,21 @@ const (
platformSupported = true
)
func getBlkioWeightDevices(config *runconfig.HostConfig) ([]*blkiodev.WeightDevice, error) {
var stat syscall.Stat_t
var BlkioWeightDevices []*blkiodev.WeightDevice
for _, weightDevice := range config.BlkioWeightDevice {
if err := syscall.Stat(weightDevice.Path, &stat); err != nil {
return nil, err
}
WeightDevice := blkiodev.NewWeightDevice(int64(stat.Rdev/256), int64(stat.Rdev%256), weightDevice.Weight, 0)
BlkioWeightDevices = append(BlkioWeightDevices, WeightDevice)
}
return BlkioWeightDevices, nil
}
func parseSecurityOpt(container *Container, config *runconfig.HostConfig) error {
var (
labelOpts []string
@ -220,6 +237,11 @@ 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 len(hostConfig.BlkioWeightDevice) > 0 && !sysInfo.BlkioWeightDevice {
warnings = append(warnings, "Your kernel does not support Block I/O weight_device.")
logrus.Warnf("Your kernel does not support Block I/O weight_device. Weight-device discarded.")
hostConfig.BlkioWeightDevice = []*pblkiodev.WeightDevice{}
}
if hostConfig.OomKillDisable && !sysInfo.OomKillDisable {
hostConfig.OomKillDisable = false
return warnings, fmt.Errorf("Your kernel does not support oom kill disable.")

View File

@ -12,6 +12,7 @@ import (
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/runconfig"
"github.com/docker/libnetwork"
blkiodev "github.com/opencontainers/runc/libcontainer/configs"
)
const (
@ -21,6 +22,10 @@ const (
windowsMaxCPUShares = 9
)
func getBlkioWeightDevices(config *runconfig.HostConfig) ([]*blkiodev.WeightDevice, error) {
return nil, nil
}
func parseSecurityOpt(container *Container, config *runconfig.HostConfig) error {
return nil
}

View File

@ -18,6 +18,7 @@ import (
"github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/cgroups/fs"
"github.com/opencontainers/runc/libcontainer/configs"
blkiodev "github.com/opencontainers/runc/libcontainer/configs"
)
// Mount contains information for a mount operation.
@ -36,15 +37,16 @@ type Resources struct {
// Fields below here are platform specific
MemorySwap int64 `json:"memory_swap"`
KernelMemory int64 `json:"kernel_memory"`
CPUQuota int64 `json:"cpu_quota"`
CpusetCpus string `json:"cpuset_cpus"`
CpusetMems string `json:"cpuset_mems"`
CPUPeriod int64 `json:"cpu_period"`
Rlimits []*ulimit.Rlimit `json:"rlimits"`
OomKillDisable bool `json:"oom_kill_disable"`
MemorySwappiness int64 `json:"memory_swappiness"`
BlkioWeightDevice []*blkiodev.WeightDevice `json:"blkio_weight_device"`
MemorySwap int64 `json:"memory_swap"`
KernelMemory int64 `json:"kernel_memory"`
CPUQuota int64 `json:"cpu_quota"`
CpusetCpus string `json:"cpuset_cpus"`
CpusetMems string `json:"cpuset_mems"`
CPUPeriod int64 `json:"cpu_period"`
Rlimits []*ulimit.Rlimit `json:"rlimits"`
OomKillDisable bool `json:"oom_kill_disable"`
MemorySwappiness int64 `json:"memory_swappiness"`
}
// Ipc settings of the container
@ -153,6 +155,7 @@ func SetupCgroups(container *configs.Config, c *Command) error {
container.Cgroups.CpuPeriod = c.Resources.CPUPeriod
container.Cgroups.CpuQuota = c.Resources.CPUQuota
container.Cgroups.BlkioWeight = c.Resources.BlkioWeight
container.Cgroups.BlkioWeightDevice = c.Resources.BlkioWeightDevice
container.Cgroups.OomKillDisable = c.Resources.OomKillDisable
container.Cgroups.MemorySwappiness = c.Resources.MemorySwappiness
}

View File

@ -187,6 +187,7 @@ Create a container
"CpusetCpus": "0,1",
"CpusetMems": "0,1",
"BlkioWeight": 300,
"BlkioWeightDevice": [{}],
"MemorySwappiness": 60,
"OomKillDisable": false,
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
@ -241,6 +242,7 @@ Json Parameters:
- **CpusetCpus** - String value containing the `cgroups CpusetCpus` to use.
- **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
- **BlkioWeight** - Block IO weight (relative weight) accepts a weight value between 10 and 1000.
- **BlkioWeightDevice** - Block IO weight (relative device weight) in the form of: `"BlkioWeightDevice": [{"Path": "device_path", "Weight": weight}]`
- **MemorySwappiness** - Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
- **OomKillDisable** - Boolean value, whether to disable OOM Killer for the container or not.
- **AttachStdin** - Boolean value, attaches to `stdin`.
@ -391,6 +393,7 @@ Return low-level information on the container `id`
"HostConfig": {
"Binds": null,
"BlkioWeight": 0,
"BlkioWeightDevice": [{}],
"CapAdd": null,
"CapDrop": null,
"ContainerIDFile": "",

View File

@ -19,6 +19,7 @@ Creates a new container.
-a, --attach=[] Attach to STDIN, STDOUT or STDERR
--add-host=[] Add a custom host-to-IP mapping (host:ip)
--blkio-weight=0 Block IO weight (relative weight)
--blkio-weight-device="" Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)
--cpu-shares=0 CPU shares (relative weight)
--cap-add=[] Add Linux capabilities
--cap-drop=[] Drop Linux capabilities

View File

@ -17,6 +17,7 @@ parent = "smn_cli"
-a, --attach=[] Attach to STDIN, STDOUT or STDERR
--add-host=[] Add a custom host-to-IP mapping (host:ip)
--blkio-weight=0 Block IO weight (relative weight)
--blkio-weight-device="" Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)
--cpu-shares=0 CPU shares (relative weight)
--cap-add=[] Add Linux capabilities
--cap-drop=[] Drop Linux capabilities

View File

@ -623,6 +623,7 @@ container:
| `--cpuset-mems=""` | Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. |
| `--cpu-quota=0` | Limit the CPU CFS (Completely Fair Scheduler) quota |
| `--blkio-weight=0` | Block IO weight (relative weight) accepts a weight value between 10 and 1000. |
| `--blkio-weight-device=""` | Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`) |
| `--oom-kill-disable=false` | Whether to disable OOM Killer for the container or not. |
| `--memory-swappiness="" ` | Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. |
@ -937,6 +938,9 @@ By default, all containers get the same proportion of block IO bandwidth
container's blkio weight relative to the weighting of all other running
containers using the `--blkio-weight` flag.
> **Note:** The blkio weight setting is only available for direct IO. Buffered IO
> is not currently supported.
The `--blkio-weight` flag can set the weighting to a value between 10 to 1000.
For example, the commands below create two containers with different blkio
weight:
@ -951,8 +955,24 @@ If you do block IO in the two containers at the same time, by, for example:
You'll find that the proportion of time is the same as the proportion of blkio
weights of the two containers.
> **Note:** The blkio weight setting is only available for direct IO. Buffered IO
> is not currently supported.
The `--blkio-weight-device="DEVICE_NAME:WEIGHT"` flag sets a specific device weight.
The `DEVICE_NAME:WEIGHT` is a string containing a colon-separated device name and weight.
For example, to set `/dev/sda` device weight to `200`:
$ docker run -it \
--blkio-weight-device "/dev/sda:200" \
ubuntu
If you specify both the `--blkio-weight` and `--blkio-weight-device`, Docker
uses the `--blkio-weight` as the default weight and uses `--blkio-weight-device`
to override this default with a new value on a specific device.
The following example uses a default weight of `300` and overrides this default
on `/dev/sda` setting that weight to `200`:
$ docker run -it \
--blkio-weight 300 \
--blkio-weight-device "/dev/sda:200" \
ubuntu
## Additional groups
--group-add: Add Linux capabilities

View File

@ -217,6 +217,12 @@ func (s *DockerSuite) TestRunWithBlkioInvalidWeight(c *check.C) {
c.Assert(out, checker.Contains, expected)
}
func (s *DockerSuite) TestRunWithBlkioInvalidWeightDevice(c *check.C) {
testRequires(c, blkioWeight)
out, _, err := dockerCmdWithError("run", "--blkio-weight-device", "/dev/sda:5", "busybox", "true")
c.Assert(err, check.NotNil, check.Commentf(out))
}
func (s *DockerSuite) TestRunOOMExitCode(c *check.C) {
testRequires(c, oomControl)
errChan := make(chan error)

View File

@ -9,6 +9,7 @@ docker-create - Create a new container
[**-a**|**--attach**[=*[]*]]
[**--add-host**[=*[]*]]
[**--blkio-weight**[=*[BLKIO-WEIGHT]*]]
[**--blkio-weight-device**[=*[]*]]
[**--cpu-shares**[=*0*]]
[**--cap-add**[=*[]*]]
[**--cap-drop**[=*[]*]]
@ -82,6 +83,9 @@ The initial status of the container created with **docker create** is 'created'.
**--blkio-weight**=*0*
Block IO weight (relative weight) accepts a weight value between 10 and 1000.
**--blkio-weight-device**=[]
Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`).
**--cpu-shares**=*0*
CPU shares (relative weight)

View File

@ -9,6 +9,7 @@ docker-run - Run a command in a new container
[**-a**|**--attach**[=*[]*]]
[**--add-host**[=*[]*]]
[**--blkio-weight**[=*[BLKIO-WEIGHT]*]]
[**--blkio-weight-device**[=*[]*]]
[**--cpu-shares**[=*0*]]
[**--cap-add**[=*[]*]]
[**--cap-drop**[=*[]*]]
@ -99,6 +100,9 @@ option can be set multiple times.
**--blkio-weight**=*0*
Block IO weight (relative weight) accepts a weight value between 10 and 1000.
**--blkio-weight-device**=[]
Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`).
**--cpu-shares**=*0*
CPU shares (relative weight)
@ -755,6 +759,13 @@ Note:
You would have to write policy defining a `svirt_apache_t` type.
## Setting device weight
If you want to set `/dev/sda` device weight to `200`, you can specify the device
weight by `--blkio-weight-device` flag. Use the following command:
# docker run -it --blkio-weight-device "/dev/sda:200" ubuntu
# HISTORY
April 2014, Originally compiled by William Henry (whenry at redhat dot com)
based on docker.com source material and internal work.

View File

@ -6,8 +6,10 @@ import (
"os"
"path"
"regexp"
"strconv"
"strings"
"github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/pkg/parsers"
)
@ -168,6 +170,9 @@ func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
// ValidatorFctType defines a validator function that returns a validated string and/or an error.
type ValidatorFctType func(val string) (string, error)
// ValidatorWeightFctType defines a validator function that returns a validated struct and/or an error.
type ValidatorWeightFctType func(val string) (*blkiodev.WeightDevice, error)
// ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
type ValidatorFctListType func(val string) ([]string, error)
@ -182,6 +187,29 @@ func ValidateAttach(val string) (string, error) {
return val, fmt.Errorf("valid streams are STDIN, STDOUT and STDERR")
}
// ValidateWeightDevice validates that the specified string has a valid device-weight format.
func ValidateWeightDevice(val string) (*blkiodev.WeightDevice, error) {
split := strings.SplitN(val, ":", 2)
if len(split) != 2 {
return nil, fmt.Errorf("bad format: %s", val)
}
if !strings.HasPrefix(split[0], "/dev/") {
return nil, fmt.Errorf("bad format for device path: %s", val)
}
weight, err := strconv.ParseUint(split[1], 10, 0)
if err != nil {
return nil, fmt.Errorf("invalid weight for device: %s", val)
}
if weight > 0 && (weight < 10 || weight > 1000) {
return nil, fmt.Errorf("invalid weight for device: %s", val)
}
return &blkiodev.WeightDevice{
Path: split[0],
Weight: uint16(weight),
}, nil
}
// ValidateLink validates that the specified string has a valid link format (containerName:alias).
func ValidateLink(val string) (string, error) {
if _, _, err := parsers.ParseLink(val); err != nil {

56
opts/weightdevice.go Normal file
View File

@ -0,0 +1,56 @@
package opts
import (
"fmt"
"github.com/docker/docker/pkg/blkiodev"
)
// WeightdeviceOpt defines a map of WeightDevices
type WeightdeviceOpt struct {
values []*blkiodev.WeightDevice
validator ValidatorWeightFctType
}
// NewWeightdeviceOpt creates a new WeightdeviceOpt
func NewWeightdeviceOpt(validator ValidatorWeightFctType) WeightdeviceOpt {
values := []*blkiodev.WeightDevice{}
return WeightdeviceOpt{
values: values,
validator: validator,
}
}
// Set validates a WeightDevice and sets its name as a key in WeightdeviceOpt
func (opt *WeightdeviceOpt) Set(val string) error {
var value *blkiodev.WeightDevice
if opt.validator != nil {
v, err := opt.validator(val)
if err != nil {
return err
}
value = v
}
(opt.values) = append((opt.values), value)
return nil
}
// String returns Ulimit values as a string.
func (opt *WeightdeviceOpt) String() string {
var out []string
for _, v := range opt.values {
out = append(out, v.String())
}
return fmt.Sprintf("%v", out)
}
// GetList returns a slice of pointers to WeightDevices.
func (opt *WeightdeviceOpt) GetList() []*blkiodev.WeightDevice {
var weightdevice []*blkiodev.WeightDevice
for _, v := range opt.values {
weightdevice = append(weightdevice, v)
}
return weightdevice
}

15
pkg/blkiodev/blkiodev.go Normal file
View File

@ -0,0 +1,15 @@
package blkiodev
import (
"fmt"
)
// WeightDevice is a structure that hold device:weight pair
type WeightDevice struct {
Path string
Weight uint16
}
func (w *WeightDevice) String() string {
return fmt.Sprintf("%s:%d", w.Path, w.Weight)
}

View File

@ -60,6 +60,9 @@ type cgroupCPUInfo struct {
type cgroupBlkioInfo struct {
// Whether Block IO weight is supported or not
BlkioWeight bool
// Whether Block IO weight_device is supported or not
BlkioWeightDevice bool
}
type cgroupCpusetInfo struct {

View File

@ -117,11 +117,19 @@ func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
return cgroupBlkioInfo{}
}
w := cgroupEnabled(mountPoint, "blkio.weight")
if !quiet && !w {
weight := cgroupEnabled(mountPoint, "blkio.weight")
if !quiet && !weight {
logrus.Warn("Your kernel does not support cgroup blkio weight")
}
return cgroupBlkioInfo{BlkioWeight: w}
weightDevice := cgroupEnabled(mountPoint, "blkio.weight_device")
if !quiet && !weightDevice {
logrus.Warn("Your kernel does not support cgroup blkio weight_device")
}
return cgroupBlkioInfo{
BlkioWeight: weight,
BlkioWeightDevice: weightDevice,
}
}
// checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point.

View File

@ -5,6 +5,7 @@ import (
"io"
"strings"
"github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/pkg/nat"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/pkg/ulimit"
@ -180,7 +181,8 @@ type HostConfig struct {
VolumesFrom []string // List of volumes to take from other container
// Applicable to UNIX platforms
BlkioWeight uint16 // Block IO weight (relative weight vs. other containers)
BlkioWeight uint16 // Block IO weight (relative weight vs. other containers)
BlkioWeightDevice []*blkiodev.WeightDevice
CapAdd *stringutils.StrSlice // List of kernel capabilities to add to the container
CapDrop *stringutils.StrSlice // List of kernel capabilities to remove from the container
CgroupParent string // Parent cgroup.

View File

@ -48,12 +48,13 @@ var (
func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSet, error) {
var (
// FIXME: use utils.ListOpts for attach and volumes?
flAttach = opts.NewListOpts(opts.ValidateAttach)
flVolumes = opts.NewListOpts(nil)
flLinks = opts.NewListOpts(opts.ValidateLink)
flEnv = opts.NewListOpts(opts.ValidateEnv)
flLabels = opts.NewListOpts(opts.ValidateEnv)
flDevices = opts.NewListOpts(opts.ValidateDevice)
flAttach = opts.NewListOpts(opts.ValidateAttach)
flVolumes = opts.NewListOpts(nil)
flBlkioWeightDevice = opts.NewWeightdeviceOpt(opts.ValidateWeightDevice)
flLinks = opts.NewListOpts(opts.ValidateLink)
flEnv = opts.NewListOpts(opts.ValidateEnv)
flLabels = opts.NewListOpts(opts.ValidateEnv)
flDevices = opts.NewListOpts(opts.ValidateDevice)
flUlimits = opts.NewUlimitOpt(nil)
@ -108,6 +109,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
)
cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR")
cmd.Var(&flBlkioWeightDevice, []string{"-blkio-weight-device"}, "Block IO weight (relative device weight)")
cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume")
cmd.Var(&flLinks, []string{"#link", "-link"}, "Add link to another container")
cmd.Var(&flDevices, []string{"-device"}, "Add a host device to the container")
@ -344,6 +346,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
CpusetMems: *flCpusetMems,
CPUQuota: *flCPUQuota,
BlkioWeight: *flBlkioWeight,
BlkioWeightDevice: flBlkioWeightDevice.GetList(),
OomKillDisable: *flOomKillDisable,
MemorySwappiness: flSwappiness,
Privileged: *flPrivileged,