Skip to content

Commit

Permalink
Add support for blkio.weight_device
Browse files Browse the repository at this point in the history
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
  • Loading branch information
Ma Shimiao committed Nov 11, 2015
1 parent 69f7325 commit 4a1a8e5
Show file tree
Hide file tree
Showing 21 changed files with 228 additions and 28 deletions.
1 change: 1 addition & 0 deletions contrib/completion/bash/docker
Expand Up @@ -1355,6 +1355,7 @@ _docker_run() {
--add-host
--attach -a
--blkio-weight
--blkio-weight-device
--cap-add
--cap-drop
--cgroup-parent
Expand Down
1 change: 1 addition & 0 deletions contrib/completion/zsh/_docker
Expand Up @@ -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"
Expand Down
24 changes: 15 additions & 9 deletions daemon/container_unix.go
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions daemon/daemon.go
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions daemon/daemon_unix.go
Expand Up @@ -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"
Expand All @@ -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"
)
Expand All @@ -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
Expand Down Expand Up @@ -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.")
Expand Down
5 changes: 5 additions & 0 deletions daemon/daemon_windows.go
Expand Up @@ -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 (
Expand All @@ -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
}
Expand Down
21 changes: 12 additions & 9 deletions daemon/execdriver/driver_unix.go
Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
3 changes: 3 additions & 0 deletions docs/reference/api/docker_remote_api_v1.22.md
Expand Up @@ -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" }] },
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -391,6 +393,7 @@ Return low-level information on the container `id`
"HostConfig": {
"Binds": null,
"BlkioWeight": 0,
"BlkioWeightDevice": [{}],
"CapAdd": null,
"CapDrop": null,
"ContainerIDFile": "",
Expand Down
1 change: 1 addition & 0 deletions docs/reference/commandline/create.md
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/reference/commandline/run.md
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions docs/reference/run.md
Expand Up @@ -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. |

Expand Down Expand Up @@ -951,6 +952,25 @@ 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.

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

> **Note:** The blkio weight setting is only available for direct IO. Buffered IO
> is not currently supported.
Expand Down
6 changes: 6 additions & 0 deletions integration-cli/docker_cli_run_unix_test.go
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions man/docker-create.1.md
Expand Up @@ -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**[=*[]*]]
Expand Down Expand Up @@ -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)

Expand Down
11 changes: 11 additions & 0 deletions man/docker-run.1.md
Expand Up @@ -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**[=*[]*]]
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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.
Expand Down
28 changes: 28 additions & 0 deletions opts/opts.go
Expand Up @@ -6,8 +6,10 @@ import (
"os"
"path"
"regexp"
"strconv"
"strings"

"github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/pkg/parsers"
)

Expand Down Expand Up @@ -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)

Expand All @@ -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 {
Expand Down

0 comments on commit 4a1a8e5

Please sign in to comment.