Add support for blkio read/write bps device

Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
This commit is contained in:
Ma Shimiao 2015-07-08 19:06:48 +08:00
parent 4e6bea5964
commit 3f15a055e5
20 changed files with 294 additions and 51 deletions

View File

@ -1372,6 +1372,8 @@ _docker_run() {
--cpuset-mems --cpuset-mems
--cpu-shares --cpu-shares
--device --device
--device-read-bps
--device-write-bps
--dns --dns
--dns-opt --dns-opt
--dns-search --dns-search

View File

@ -468,6 +468,8 @@ __docker_subcommand() {
"($help)*--cap-drop=[Drop Linux capabilities]:capability: " "($help)*--cap-drop=[Drop Linux capabilities]:capability: "
"($help)--cidfile=[Write the container ID to the file]:CID file:_files" "($help)--cidfile=[Write the container ID to the file]:CID file:_files"
"($help)*--device=[Add a host device to the container]:device:_files" "($help)*--device=[Add a host device to the container]:device:_files"
"($help)*--device-read-bps=[Limit the read rate (bytes per second) from a device]:device:IO rate: "
"($help)*--device-write-bps=[Limit the write rate (bytes per second) to a device]:device:IO rate: "
"($help)*--dns=[Set custom DNS servers]:DNS server: " "($help)*--dns=[Set custom DNS servers]:DNS server: "
"($help)*--dns-opt=[Set custom DNS options]:DNS option: " "($help)*--dns-opt=[Set custom DNS options]:DNS option: "
"($help)*--dns-search=[Set custom DNS search domains]:DNS domains: " "($help)*--dns-search=[Set custom DNS search domains]:DNS domains: "

View File

@ -163,6 +163,16 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
return err return err
} }
readBpsDevice, err := getBlkioReadBpsDevices(c.HostConfig)
if err != nil {
return err
}
writeBpsDevice, err := getBlkioWriteBpsDevices(c.HostConfig)
if err != nil {
return err
}
for _, limit := range ulimits { for _, limit := range ulimits {
rl, err := limit.GetRlimit() rl, err := limit.GetRlimit()
if err != nil { if err != nil {
@ -178,16 +188,18 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
CPUShares: c.HostConfig.CPUShares, CPUShares: c.HostConfig.CPUShares,
BlkioWeight: c.HostConfig.BlkioWeight, BlkioWeight: c.HostConfig.BlkioWeight,
}, },
MemorySwap: c.HostConfig.MemorySwap, MemorySwap: c.HostConfig.MemorySwap,
KernelMemory: c.HostConfig.KernelMemory, KernelMemory: c.HostConfig.KernelMemory,
CpusetCpus: c.HostConfig.CpusetCpus, CpusetCpus: c.HostConfig.CpusetCpus,
CpusetMems: c.HostConfig.CpusetMems, CpusetMems: c.HostConfig.CpusetMems,
CPUPeriod: c.HostConfig.CPUPeriod, CPUPeriod: c.HostConfig.CPUPeriod,
CPUQuota: c.HostConfig.CPUQuota, CPUQuota: c.HostConfig.CPUQuota,
Rlimits: rlimits, Rlimits: rlimits,
BlkioWeightDevice: weightDevices, BlkioWeightDevice: weightDevices,
OomKillDisable: c.HostConfig.OomKillDisable, BlkioThrottleReadBpsDevice: readBpsDevice,
MemorySwappiness: *c.HostConfig.MemorySwappiness, BlkioThrottleWriteBpsDevice: writeBpsDevice,
OomKillDisable: c.HostConfig.OomKillDisable,
MemorySwappiness: *c.HostConfig.MemorySwappiness,
} }
processConfig := execdriver.ProcessConfig{ processConfig := execdriver.ProcessConfig{

View File

@ -83,6 +83,36 @@ func parseSecurityOpt(container *container.Container, config *runconfig.HostConf
return err return err
} }
func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
var BlkioReadBpsDevice []*blkiodev.ThrottleDevice
var stat syscall.Stat_t
for _, bpsDevice := range config.BlkioDeviceReadBps {
if err := syscall.Stat(bpsDevice.Path, &stat); err != nil {
return nil, err
}
ReadBpsDevice := blkiodev.NewThrottleDevice(int64(stat.Rdev/256), int64(stat.Rdev%256), bpsDevice.Rate)
BlkioReadBpsDevice = append(BlkioReadBpsDevice, ReadBpsDevice)
}
return BlkioReadBpsDevice, nil
}
func getBlkioWriteBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
var BlkioWriteBpsDevice []*blkiodev.ThrottleDevice
var stat syscall.Stat_t
for _, bpsDevice := range config.BlkioDeviceWriteBps {
if err := syscall.Stat(bpsDevice.Path, &stat); err != nil {
return nil, err
}
WriteBpsDevice := blkiodev.NewThrottleDevice(int64(stat.Rdev/256), int64(stat.Rdev%256), bpsDevice.Rate)
BlkioWriteBpsDevice = append(BlkioWriteBpsDevice, WriteBpsDevice)
}
return BlkioWriteBpsDevice, nil
}
func checkKernelVersion(k, major, minor int) bool { func checkKernelVersion(k, major, minor int) bool {
if v, err := kernel.GetKernelVersion(); err != nil { if v, err := kernel.GetKernelVersion(); err != nil {
logrus.Warnf("%s", err) logrus.Warnf("%s", err)
@ -259,6 +289,16 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
logrus.Warnf("Your kernel does not support Block I/O weight_device. Weight-device discarded.") logrus.Warnf("Your kernel does not support Block I/O weight_device. Weight-device discarded.")
hostConfig.BlkioWeightDevice = []*pblkiodev.WeightDevice{} hostConfig.BlkioWeightDevice = []*pblkiodev.WeightDevice{}
} }
if len(hostConfig.BlkioDeviceReadBps) > 0 && !sysInfo.BlkioReadBpsDevice {
warnings = append(warnings, "Your kernel does not support Block read limit in bytes per second.")
logrus.Warnf("Your kernel does not support Block I/O read limit in bytes per second. --device-read-bps discarded.")
hostConfig.BlkioDeviceReadBps = []*pblkiodev.ThrottleDevice{}
}
if len(hostConfig.BlkioDeviceWriteBps) > 0 && !sysInfo.BlkioWriteBpsDevice {
warnings = append(warnings, "Your kernel does not support Block write limit in bytes per second.")
logrus.Warnf("Your kernel does not support Block I/O write limit in bytes per second. --device-write-bps discarded.")
hostConfig.BlkioDeviceWriteBps = []*pblkiodev.ThrottleDevice{}
}
if hostConfig.OomKillDisable && !sysInfo.OomKillDisable { if hostConfig.OomKillDisable && !sysInfo.OomKillDisable {
hostConfig.OomKillDisable = false hostConfig.OomKillDisable = false
return warnings, fmt.Errorf("Your kernel does not support oom kill disable.") return warnings, fmt.Errorf("Your kernel does not support oom kill disable.")

View File

@ -39,6 +39,14 @@ func parseSecurityOpt(container *container.Container, config *runconfig.HostConf
return nil return nil
} }
func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
return nil, nil
}
func getBlkioWriteBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
return nil, nil
}
func setupInitLayer(initLayer string, rootUID, rootGID int) error { func setupInitLayer(initLayer string, rootUID, rootGID int) error {
return nil return nil
} }

View File

@ -38,16 +38,18 @@ type Resources struct {
// Fields below here are platform specific // Fields below here are platform specific
BlkioWeightDevice []*blkiodev.WeightDevice `json:"blkio_weight_device"` BlkioWeightDevice []*blkiodev.WeightDevice `json:"blkio_weight_device"`
MemorySwap int64 `json:"memory_swap"` BlkioThrottleReadBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_read_bps_device"`
KernelMemory int64 `json:"kernel_memory"` BlkioThrottleWriteBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_write_bps_device"`
CPUQuota int64 `json:"cpu_quota"` MemorySwap int64 `json:"memory_swap"`
CpusetCpus string `json:"cpuset_cpus"` KernelMemory int64 `json:"kernel_memory"`
CpusetMems string `json:"cpuset_mems"` CPUQuota int64 `json:"cpu_quota"`
CPUPeriod int64 `json:"cpu_period"` CpusetCpus string `json:"cpuset_cpus"`
Rlimits []*ulimit.Rlimit `json:"rlimits"` CpusetMems string `json:"cpuset_mems"`
OomKillDisable bool `json:"oom_kill_disable"` CPUPeriod int64 `json:"cpu_period"`
MemorySwappiness int64 `json:"memory_swappiness"` Rlimits []*ulimit.Rlimit `json:"rlimits"`
OomKillDisable bool `json:"oom_kill_disable"`
MemorySwappiness int64 `json:"memory_swappiness"`
} }
// ProcessConfig is the platform specific structure that describes a process // ProcessConfig is the platform specific structure that describes a process
@ -170,6 +172,8 @@ func SetupCgroups(container *configs.Config, c *Command) error {
container.Cgroups.CpuQuota = c.Resources.CPUQuota container.Cgroups.CpuQuota = c.Resources.CPUQuota
container.Cgroups.BlkioWeight = c.Resources.BlkioWeight container.Cgroups.BlkioWeight = c.Resources.BlkioWeight
container.Cgroups.BlkioWeightDevice = c.Resources.BlkioWeightDevice container.Cgroups.BlkioWeightDevice = c.Resources.BlkioWeightDevice
container.Cgroups.BlkioThrottleReadBpsDevice = c.Resources.BlkioThrottleReadBpsDevice
container.Cgroups.BlkioThrottleWriteBpsDevice = c.Resources.BlkioThrottleWriteBpsDevice
container.Cgroups.OomKillDisable = c.Resources.OomKillDisable container.Cgroups.OomKillDisable = c.Resources.OomKillDisable
container.Cgroups.MemorySwappiness = c.Resources.MemorySwappiness container.Cgroups.MemorySwappiness = c.Resources.MemorySwappiness
} }

View File

@ -188,6 +188,8 @@ Create a container
"CpusetMems": "0,1", "CpusetMems": "0,1",
"BlkioWeight": 300, "BlkioWeight": 300,
"BlkioWeightDevice": [{}], "BlkioWeightDevice": [{}],
"BlkioDeviceReadBps": [{}],
"BlkioDeviceWriteBps": [{}],
"MemorySwappiness": 60, "MemorySwappiness": 60,
"OomKillDisable": false, "OomKillDisable": false,
"OomScoreAdj": 500, "OomScoreAdj": 500,
@ -245,6 +247,10 @@ Json Parameters:
- **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. - **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. - **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}]` - **BlkioWeightDevice** - Block IO weight (relative device weight) in the form of: `"BlkioWeightDevice": [{"Path": "device_path", "Weight": weight}]`
- **BlkioDeviceReadBps** - Limit read rate from a device in form of: `"BlkioDeviceReadBps": [{"Path": "device_path", "Rate": rate}]`, for example:
`"BlkioDeviceReadBps": [{"Path": "/dev/sda", "Rate": "1024"}]"`
- **BlkioDeviceWriteBps** - Limit write rate to a device in the form of: `"BlkioDeviceWriteBps": [{"Path": "deivce_path", "Rate": rate}]`, for example:
`"BlkioDeviceWriteBps": [{"Path": "/dev/sda", "Rate": "1024"}]"`
- **MemorySwappiness** - Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. - **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. - **OomKillDisable** - Boolean value, whether to disable OOM Killer for the container or not.
- **OomScoreAdj** - An integer value containing the score given to the container in order to tune OOM killer preferences. - **OomScoreAdj** - An integer value containing the score given to the container in order to tune OOM killer preferences.
@ -398,6 +404,8 @@ Return low-level information on the container `id`
"Binds": null, "Binds": null,
"BlkioWeight": 0, "BlkioWeight": 0,
"BlkioWeightDevice": [{}], "BlkioWeightDevice": [{}],
"BlkioDeviceReadBps": [{}],
"BlkioDeviceWriteBps": [{}],
"CapAdd": null, "CapAdd": null,
"CapDrop": null, "CapDrop": null,
"ContainerIDFile": "", "ContainerIDFile": "",

View File

@ -30,6 +30,8 @@ Creates a new container.
--cpuset-cpus="" CPUs in which to allow execution (0-3, 0,1) --cpuset-cpus="" CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems="" Memory nodes (MEMs) in which to allow execution (0-3, 0,1) --cpuset-mems="" Memory nodes (MEMs) in which to allow execution (0-3, 0,1)
--device=[] Add a host device to the container --device=[] Add a host device to the container
--device-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb)
--device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb)
--disable-content-trust=true Skip image verification --disable-content-trust=true Skip image verification
--dns=[] Set custom DNS servers --dns=[] Set custom DNS servers
--dns-opt=[] Set custom DNS options --dns-opt=[] Set custom DNS options

View File

@ -29,6 +29,8 @@ parent = "smn_cli"
--cpuset-mems="" Memory nodes (MEMs) in which to allow execution (0-3, 0,1) --cpuset-mems="" Memory nodes (MEMs) in which to allow execution (0-3, 0,1)
-d, --detach=false Run container in background and print container ID -d, --detach=false Run container in background and print container ID
--device=[] Add a host device to the container --device=[] Add a host device to the container
--device-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb)
--device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb)
--disable-content-trust=true Skip image verification --disable-content-trust=true Skip image verification
--dns=[] Set custom DNS servers --dns=[] Set custom DNS servers
--dns-opt=[] Set custom DNS options --dns-opt=[] Set custom DNS options

View File

@ -624,6 +624,10 @@ container:
| `--cpu-quota=0` | Limit the CPU CFS (Completely Fair Scheduler) quota | | `--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=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`) | | `--blkio-weight-device=""` | Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`) |
| `--device-read-bps="" ` | Limit read rate from a device (format: `<device-path>:<number>[<unit>]`. |
| | Number is a positive integer. Unit can be one of kb, mb, or gb. |
| `--device-write-bps="" ` | Limit write rate to a device (format: `<device-path>:<number>[<unit>]`. |
| | Number is a positive integer. Unit can be one of kb, mb, or gb. |
| `--oom-kill-disable=false` | Whether to disable OOM Killer for the container or not. | | `--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. | | `--memory-swappiness="" ` | Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. |
| `--shm-size="" ` | Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`. | | `--shm-size="" ` | Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`. |
@ -978,6 +982,18 @@ $ docker run -it \
--blkio-weight-device "/dev/sda:200" \ --blkio-weight-device "/dev/sda:200" \
ubuntu ubuntu
The `--device-read-bps` flag can limit read rate from a device.
For example, the command creates a container and limits theread rate to `1mb` per second from `/dev/sda`:
$ docker run -ti --device-read-bps /dev/sda:1mb ubuntu
The `--device-write-bps` flag can limit write rate to a device.
For example, the command creates a container and limits write rate to `1mb` per second to `/dev/sda`:
$ docker run -ti --device-write-bps /dev/sda:1mb ubuntu
Both flags take limits in the `<device-path>:<limit>[unit]` format. Both read and write rates must be a positive integer. You can specify the rate in `kb` (kilobytes), `mb` (megabytes), or `gb` (gigabytes).
## Additional groups ## Additional groups
--group-add: Add Linux capabilities --group-add: Add Linux capabilities

View File

@ -246,6 +246,18 @@ func (s *DockerSuite) TestRunWithBlkioInvalidWeightDevice(c *check.C) {
c.Assert(err, check.NotNil, check.Commentf(out)) c.Assert(err, check.NotNil, check.Commentf(out))
} }
func (s *DockerSuite) TestRunWithBlkioInvalidDeivceReadBps(c *check.C) {
testRequires(c, blkioWeight)
out, _, err := dockerCmdWithError("run", "--device-read-bps", "/dev/sda:500", "busybox", "true")
c.Assert(err, check.NotNil, check.Commentf(out))
}
func (s *DockerSuite) TestRunWithBlkioInvalidDeviceWriteBps(c *check.C) {
testRequires(c, blkioWeight)
out, _, err := dockerCmdWithError("run", "--device-write-bps", "/dev/sda:500", "busybox", "true")
c.Assert(err, check.NotNil, check.Commentf(out))
}
func (s *DockerSuite) TestRunOOMExitCode(c *check.C) { func (s *DockerSuite) TestRunOOMExitCode(c *check.C) {
testRequires(c, oomControl) testRequires(c, oomControl)
errChan := make(chan error) errChan := make(chan error)

View File

@ -20,6 +20,8 @@ docker-create - Create a new container
[**--cpuset-cpus**[=*CPUSET-CPUS*]] [**--cpuset-cpus**[=*CPUSET-CPUS*]]
[**--cpuset-mems**[=*CPUSET-MEMS*]] [**--cpuset-mems**[=*CPUSET-MEMS*]]
[**--device**[=*[]*]] [**--device**[=*[]*]]
[**--device-read-bps**[=*[]*]]
[**--device-write-bps**[=*[]*]]
[**--dns**[=*[]*]] [**--dns**[=*[]*]]
[**--dns-search**[=*[]*]] [**--dns-search**[=*[]*]]
[**--dns-opt**[=*[]*]] [**--dns-opt**[=*[]*]]
@ -125,6 +127,12 @@ two memory nodes.
**--device**=[] **--device**=[]
Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm) Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)
**--device-read-bps**=[]
Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)
**--device-write-bps**=[]
Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb)
**--dns**=[] **--dns**=[]
Set custom DNS servers Set custom DNS servers

View File

@ -21,6 +21,8 @@ docker-run - Run a command in a new container
[**--cpuset-mems**[=*CPUSET-MEMS*]] [**--cpuset-mems**[=*CPUSET-MEMS*]]
[**-d**|**--detach**[=*false*]] [**-d**|**--detach**[=*false*]]
[**--device**[=*[]*]] [**--device**[=*[]*]]
[**--device-read-bps**[=*[]*]]
[**--device-write-bps**[=*[]*]]
[**--dns**[=*[]*]] [**--dns**[=*[]*]]
[**--dns-opt**[=*[]*]] [**--dns-opt**[=*[]*]]
[**--dns-search**[=*[]*]] [**--dns-search**[=*[]*]]
@ -192,6 +194,12 @@ stopping the process by pressing the keys CTRL-P CTRL-Q.
**--device**=[] **--device**=[]
Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm) Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)
**--device-read-bps**=[]
Limit read rate from a device (e.g. --device-read-bps=/dev/sda:1mb)
**--device-write-bps**=[]
Limit write rate to a device (e.g. --device-write-bps=/dev/sda:1mb)
**--dns-search**=[] **--dns-search**=[]
Set custom DNS search domains (Use --dns-search=. if you don't wish to set the search domain) Set custom DNS search domains (Use --dns-search=. if you don't wish to set the search domain)

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/docker/pkg/blkiodev" "github.com/docker/docker/pkg/blkiodev"
"github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/units"
) )
var ( var (
@ -173,6 +174,9 @@ type ValidatorFctType func(val string) (string, error)
// ValidatorWeightFctType defines a validator function that returns a validated struct and/or an error. // ValidatorWeightFctType defines a validator function that returns a validated struct and/or an error.
type ValidatorWeightFctType func(val string) (*blkiodev.WeightDevice, error) type ValidatorWeightFctType func(val string) (*blkiodev.WeightDevice, error)
// ValidatorThrottleFctType defines a validator function that returns a validated struct and/or an error.
type ValidatorThrottleFctType func(val string) (*blkiodev.ThrottleDevice, error)
// ValidatorFctListType defines a validator function that returns a validated list of string and/or an error // ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
type ValidatorFctListType func(val string) ([]string, error) type ValidatorFctListType func(val string) ([]string, error)
@ -210,6 +214,29 @@ func ValidateWeightDevice(val string) (*blkiodev.WeightDevice, error) {
}, nil }, nil
} }
// ValidateThrottleBpsDevice validates that the specified string has a valid device-rate format.
func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, 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)
}
rate, err := units.RAMInBytes(split[1])
if err != nil {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
}
if rate < 0 {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
}
return &blkiodev.ThrottleDevice{
Path: split[0],
Rate: uint64(rate),
}, nil
}
// ValidateLink validates that the specified string has a valid link format (containerName:alias). // ValidateLink validates that the specified string has a valid link format (containerName:alias).
func ValidateLink(val string) (string, error) { func ValidateLink(val string) (string, error) {
if _, _, err := parsers.ParseLink(val); err != nil { if _, _, err := parsers.ParseLink(val); err != nil {

56
opts/throttledevice.go Normal file
View File

@ -0,0 +1,56 @@
package opts
import (
"fmt"
"github.com/docker/docker/pkg/blkiodev"
)
// ThrottledeviceOpt defines a map of ThrottleDevices
type ThrottledeviceOpt struct {
values []*blkiodev.ThrottleDevice
validator ValidatorThrottleFctType
}
// NewThrottledeviceOpt creates a new ThrottledeviceOpt
func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt {
values := []*blkiodev.ThrottleDevice{}
return ThrottledeviceOpt{
values: values,
validator: validator,
}
}
// Set validates a ThrottleDevice and sets its name as a key in ThrottledeviceOpt
func (opt *ThrottledeviceOpt) Set(val string) error {
var value *blkiodev.ThrottleDevice
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 ThrottledeviceOpt values as a string.
func (opt *ThrottledeviceOpt) 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 ThrottleDevices.
func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice {
var throttledevice []*blkiodev.ThrottleDevice
for _, v := range opt.values {
throttledevice = append(throttledevice, v)
}
return throttledevice
}

View File

@ -13,3 +13,13 @@ type WeightDevice struct {
func (w *WeightDevice) String() string { func (w *WeightDevice) String() string {
return fmt.Sprintf("%s:%d", w.Path, w.Weight) return fmt.Sprintf("%s:%d", w.Path, w.Weight)
} }
// ThrottleDevice is a structure that hold device:rate_per_second pair
type ThrottleDevice struct {
Path string
Rate uint64
}
func (t *ThrottleDevice) String() string {
return fmt.Sprintf("%s:%d", t.Path, t.Rate)
}

View File

@ -63,6 +63,12 @@ type cgroupBlkioInfo struct {
// Whether Block IO weight_device is supported or not // Whether Block IO weight_device is supported or not
BlkioWeightDevice bool BlkioWeightDevice bool
// Whether Block IO read limit in bytes per second is supported or not
BlkioReadBpsDevice bool
// Whether Block IO write limit in bytes per second is supported or not
BlkioWriteBpsDevice bool
} }
type cgroupCpusetInfo struct { type cgroupCpusetInfo struct {

View File

@ -126,9 +126,21 @@ func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
if !quiet && !weightDevice { if !quiet && !weightDevice {
logrus.Warn("Your kernel does not support cgroup blkio weight_device") logrus.Warn("Your kernel does not support cgroup blkio weight_device")
} }
readBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device")
if !quiet && !readBpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.read_bps_device")
}
writeBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device")
if !quiet && !writeBpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device")
}
return cgroupBlkioInfo{ return cgroupBlkioInfo{
BlkioWeight: weight, BlkioWeight: weight,
BlkioWeightDevice: weightDevice, BlkioWeightDevice: weightDevice,
BlkioReadBpsDevice: readBpsDevice,
BlkioWriteBpsDevice: writeBpsDevice,
} }
} }

View File

@ -171,20 +171,22 @@ type Resources struct {
CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers) CPUShares int64 `json:"CpuShares"` // CPU shares (relative weight vs. other containers)
// Applicable to UNIX platforms // Applicable to UNIX platforms
CgroupParent string // Parent cgroup. CgroupParent string // Parent cgroup.
BlkioWeight uint16 // Block IO weight (relative weight vs. other containers) BlkioWeight uint16 // Block IO weight (relative weight vs. other containers)
BlkioWeightDevice []*blkiodev.WeightDevice BlkioWeightDevice []*blkiodev.WeightDevice
CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period BlkioDeviceReadBps []*blkiodev.ThrottleDevice
CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota BlkioDeviceWriteBps []*blkiodev.ThrottleDevice
CpusetCpus string // CpusetCpus 0-2, 0,1 CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period
CpusetMems string // CpusetMems 0-2, 0,1 CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota
Devices []DeviceMapping // List of devices to map inside the container CpusetCpus string // CpusetCpus 0-2, 0,1
KernelMemory int64 // Kernel memory limit (in bytes) CpusetMems string // CpusetMems 0-2, 0,1
Memory int64 // Memory limit (in bytes) Devices []DeviceMapping // List of devices to map inside the container
MemoryReservation int64 // Memory soft limit (in bytes) KernelMemory int64 // Kernel memory limit (in bytes)
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap Memory int64 // Memory limit (in bytes)
MemorySwappiness *int64 // Tuning container memory swappiness behaviour MemoryReservation int64 // Memory soft limit (in bytes)
Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap
MemorySwappiness *int64 // Tuning container memory swappiness behaviour
Ulimits []*ulimit.Ulimit // List of ulimits to be set in the container
} }
// HostConfig the non-portable Config structure of a container. // HostConfig the non-portable Config structure of a container.

View File

@ -53,6 +53,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
flVolumes = opts.NewListOpts(nil) flVolumes = opts.NewListOpts(nil)
flTmpfs = opts.NewListOpts(nil) flTmpfs = opts.NewListOpts(nil)
flBlkioWeightDevice = opts.NewWeightdeviceOpt(opts.ValidateWeightDevice) flBlkioWeightDevice = opts.NewWeightdeviceOpt(opts.ValidateWeightDevice)
flDeviceReadBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice)
flDeviceWriteBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice)
flLinks = opts.NewListOpts(opts.ValidateLink) flLinks = opts.NewListOpts(opts.ValidateLink)
flEnv = opts.NewListOpts(opts.ValidateEnv) flEnv = opts.NewListOpts(opts.ValidateEnv)
flLabels = opts.NewListOpts(opts.ValidateEnv) flLabels = opts.NewListOpts(opts.ValidateEnv)
@ -113,6 +115,8 @@ 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(&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(&flBlkioWeightDevice, []string{"-blkio-weight-device"}, "Block IO weight (relative device weight)")
cmd.Var(&flDeviceReadBps, []string{"-device-read-bps"}, "Limit read rate (bytes per second) from a device")
cmd.Var(&flDeviceWriteBps, []string{"-device-write-bps"}, "Limit write rate (bytes per second) to a device")
cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume") cmd.Var(&flVolumes, []string{"v", "-volume"}, "Bind mount a volume")
cmd.Var(&flTmpfs, []string{"-tmpfs"}, "Mount a tmpfs directory") cmd.Var(&flTmpfs, []string{"-tmpfs"}, "Mount a tmpfs directory")
cmd.Var(&flLinks, []string{"-link"}, "Add link to another container") cmd.Var(&flLinks, []string{"-link"}, "Add link to another container")
@ -338,21 +342,23 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
} }
resources := Resources{ resources := Resources{
CgroupParent: *flCgroupParent, CgroupParent: *flCgroupParent,
Memory: flMemory, Memory: flMemory,
MemoryReservation: MemoryReservation, MemoryReservation: MemoryReservation,
MemorySwap: memorySwap, MemorySwap: memorySwap,
MemorySwappiness: flSwappiness, MemorySwappiness: flSwappiness,
KernelMemory: KernelMemory, KernelMemory: KernelMemory,
CPUShares: *flCPUShares, CPUShares: *flCPUShares,
CPUPeriod: *flCPUPeriod, CPUPeriod: *flCPUPeriod,
CpusetCpus: *flCpusetCpus, CpusetCpus: *flCpusetCpus,
CpusetMems: *flCpusetMems, CpusetMems: *flCpusetMems,
CPUQuota: *flCPUQuota, CPUQuota: *flCPUQuota,
BlkioWeight: *flBlkioWeight, BlkioWeight: *flBlkioWeight,
BlkioWeightDevice: flBlkioWeightDevice.GetList(), BlkioWeightDevice: flBlkioWeightDevice.GetList(),
Ulimits: flUlimits.GetList(), BlkioDeviceReadBps: flDeviceReadBps.GetList(),
Devices: deviceMappings, BlkioDeviceWriteBps: flDeviceWriteBps.GetList(),
Ulimits: flUlimits.GetList(),
Devices: deviceMappings,
} }
config := &Config{ config := &Config{