Merge pull request #15879 from Mashimiao/add-support-blkio_throtte_iops

Add support for blkio read/write iops device
This commit is contained in:
Sebastiaan van Stijn 2015-12-21 23:45:18 +01:00
commit 312c82677b
19 changed files with 244 additions and 70 deletions

View file

@ -1405,7 +1405,9 @@ _docker_run() {
--cpu-shares --cpu-shares
--device --device
--device-read-bps --device-read-bps
--device-read-iops
--device-write-bps --device-write-bps
--device-write-iops
--dns --dns
--dns-opt --dns-opt
--dns-search --dns-search

View file

@ -469,7 +469,9 @@ __docker_subcommand() {
"($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-read-bps=[Limit the read rate (bytes per second) from a device]:device:IO rate: "
"($help)*--device-read-iops=[Limit the read rate (IO 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)*--device-write-bps=[Limit the write rate (bytes per second) to a device]:device:IO rate: "
"($help)*--device-write-iops=[Limit the write rate (IO 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

@ -174,6 +174,16 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
return err return err
} }
readIOpsDevice, err := getBlkioReadIOpsDevices(c.HostConfig)
if err != nil {
return err
}
writeIOpsDevice, err := getBlkioWriteIOpsDevices(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 {
@ -189,18 +199,20 @@ 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,
BlkioThrottleReadBpsDevice: readBpsDevice, BlkioThrottleReadBpsDevice: readBpsDevice,
BlkioThrottleWriteBpsDevice: writeBpsDevice, BlkioThrottleWriteBpsDevice: writeBpsDevice,
OomKillDisable: c.HostConfig.OomKillDisable, BlkioThrottleReadIOpsDevice: readIOpsDevice,
MemorySwappiness: -1, BlkioThrottleWriteIOpsDevice: writeIOpsDevice,
OomKillDisable: c.HostConfig.OomKillDisable,
MemorySwappiness: -1,
} }
if c.HostConfig.MemorySwappiness != nil { if c.HostConfig.MemorySwappiness != nil {

View file

@ -85,6 +85,36 @@ func parseSecurityOpt(container *container.Container, config *runconfig.HostConf
return err return err
} }
func getBlkioReadIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
var blkioReadIOpsDevice []*blkiodev.ThrottleDevice
var stat syscall.Stat_t
for _, iopsDevice := range config.BlkioDeviceReadIOps {
if err := syscall.Stat(iopsDevice.Path, &stat); err != nil {
return nil, err
}
readIOpsDevice := blkiodev.NewThrottleDevice(int64(stat.Rdev/256), int64(stat.Rdev%256), iopsDevice.Rate)
blkioReadIOpsDevice = append(blkioReadIOpsDevice, readIOpsDevice)
}
return blkioReadIOpsDevice, nil
}
func getBlkioWriteIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
var blkioWriteIOpsDevice []*blkiodev.ThrottleDevice
var stat syscall.Stat_t
for _, iopsDevice := range config.BlkioDeviceWriteIOps {
if err := syscall.Stat(iopsDevice.Path, &stat); err != nil {
return nil, err
}
writeIOpsDevice := blkiodev.NewThrottleDevice(int64(stat.Rdev/256), int64(stat.Rdev%256), iopsDevice.Rate)
blkioWriteIOpsDevice = append(blkioWriteIOpsDevice, writeIOpsDevice)
}
return blkioWriteIOpsDevice, nil
}
func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
var blkioReadBpsDevice []*blkiodev.ThrottleDevice var blkioReadBpsDevice []*blkiodev.ThrottleDevice
var stat syscall.Stat_t var stat syscall.Stat_t
@ -299,6 +329,16 @@ func verifyContainerResources(resources *runconfig.Resources) ([]string, error)
logrus.Warnf("Your kernel does not support Block I/O write limit in bytes per second. --device-write-bps discarded.") logrus.Warnf("Your kernel does not support Block I/O write limit in bytes per second. --device-write-bps discarded.")
resources.BlkioDeviceWriteBps = []*pblkiodev.ThrottleDevice{} resources.BlkioDeviceWriteBps = []*pblkiodev.ThrottleDevice{}
} }
if len(resources.BlkioDeviceReadIOps) > 0 && !sysInfo.BlkioReadIOpsDevice {
warnings = append(warnings, "Your kernel does not support Block read limit in IO per second.")
logrus.Warnf("Your kernel does not support Block I/O read limit in IO per second. -device-read-iops discarded.")
resources.BlkioDeviceReadIOps = []*pblkiodev.ThrottleDevice{}
}
if len(resources.BlkioDeviceWriteIOps) > 0 && !sysInfo.BlkioWriteIOpsDevice {
warnings = append(warnings, "Your kernel does not support Block write limit in IO per second.")
logrus.Warnf("Your kernel does not support Block I/O write limit in IO per second. --device-write-iops discarded.")
resources.BlkioDeviceWriteIOps = []*pblkiodev.ThrottleDevice{}
}
return warnings, nil return warnings, nil
} }
@ -328,7 +368,6 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC
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.")
} }
if hostConfig.OomScoreAdj < -1000 || hostConfig.OomScoreAdj > 1000 { if hostConfig.OomScoreAdj < -1000 || hostConfig.OomScoreAdj > 1000 {
return warnings, fmt.Errorf("Invalid value %d, range for oom score adj is [-1000, 1000].", hostConfig.OomScoreAdj) return warnings, fmt.Errorf("Invalid value %d, range for oom score adj is [-1000, 1000].", hostConfig.OomScoreAdj)
} }

View file

@ -38,6 +38,14 @@ func parseSecurityOpt(container *container.Container, config *runconfig.HostConf
return nil return nil
} }
func getBlkioReadIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
return nil, nil
}
func getBlkioWriteIOpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
return nil, nil
}
func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) { func getBlkioReadBpsDevices(config *runconfig.HostConfig) ([]*blkiodev.ThrottleDevice, error) {
return nil, nil return nil, nil
} }

View file

@ -37,18 +37,20 @@ 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"`
BlkioThrottleReadBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_read_bps_device"` BlkioThrottleReadBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_read_bps_device"`
BlkioThrottleWriteBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_write_bps_device"` BlkioThrottleWriteBpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_write_bps_device"`
MemorySwap int64 `json:"memory_swap"` BlkioThrottleReadIOpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_read_iops_device"`
KernelMemory int64 `json:"kernel_memory"` BlkioThrottleWriteIOpsDevice []*blkiodev.ThrottleDevice `json:"blkio_throttle_write_iops_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
@ -181,6 +183,8 @@ func SetupCgroups(container *configs.Config, c *Command) error {
container.Cgroups.BlkioWeightDevice = c.Resources.BlkioWeightDevice container.Cgroups.BlkioWeightDevice = c.Resources.BlkioWeightDevice
container.Cgroups.BlkioThrottleReadBpsDevice = c.Resources.BlkioThrottleReadBpsDevice container.Cgroups.BlkioThrottleReadBpsDevice = c.Resources.BlkioThrottleReadBpsDevice
container.Cgroups.BlkioThrottleWriteBpsDevice = c.Resources.BlkioThrottleWriteBpsDevice container.Cgroups.BlkioThrottleWriteBpsDevice = c.Resources.BlkioThrottleWriteBpsDevice
container.Cgroups.BlkioThrottleReadIOPSDevice = c.Resources.BlkioThrottleReadIOpsDevice
container.Cgroups.BlkioThrottleWriteIOPSDevice = c.Resources.BlkioThrottleWriteIOpsDevice
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

@ -107,6 +107,8 @@ This section lists each version from latest to oldest. Each listing includes a
* Pushes initiated with `POST /images/(name)/push` and pulls initiated with `POST /images/create` * Pushes initiated with `POST /images/(name)/push` and pulls initiated with `POST /images/create`
will be cancelled if the HTTP connection making the API request is closed before will be cancelled if the HTTP connection making the API request is closed before
the push or pull completes. the push or pull completes.
* `POST /containers/create` now allows you to set a read/write rate limit for a
device (in bytes per second or IO per second).
### v1.21 API changes ### v1.21 API changes

View file

@ -248,7 +248,9 @@ Create a container
"BlkioWeight": 300, "BlkioWeight": 300,
"BlkioWeightDevice": [{}], "BlkioWeightDevice": [{}],
"BlkioDeviceReadBps": [{}], "BlkioDeviceReadBps": [{}],
"BlkioDeviceReadIOps": [{}],
"BlkioDeviceWriteBps": [{}], "BlkioDeviceWriteBps": [{}],
"BlkioDeviceWriteIOps": [{}],
"MemorySwappiness": 60, "MemorySwappiness": 60,
"OomKillDisable": false, "OomKillDisable": false,
"OomScoreAdj": 500, "OomScoreAdj": 500,
@ -306,10 +308,14 @@ 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** - Limit read rate (bytes per second) from a device in the form of: `"BlkioDeviceReadBps": [{"Path": "device_path", "Rate": rate}]`, for example:
`"BlkioDeviceReadBps": [{"Path": "/dev/sda", "Rate": "1024"}]"` `"BlkioDeviceReadBps": [{"Path": "/dev/sda", "Rate": "1024"}]"`
- **BlkioDeviceWriteBps** - Limit write rate to a device in the form of: `"BlkioDeviceWriteBps": [{"Path": "device_path", "Rate": rate}]`, for example: - **BlkioDeviceWriteBps** - Limit write rate (bytes per second) to a device in the form of: `"BlkioDeviceWriteBps": [{"Path": "device_path", "Rate": rate}]`, for example:
`"BlkioDeviceWriteBps": [{"Path": "/dev/sda", "Rate": "1024"}]"` `"BlkioDeviceWriteBps": [{"Path": "/dev/sda", "Rate": "1024"}]"`
- **BlkioDeviceReadIOps** - Limit read rate (IO per second) from a device in the form of: `"BlkioDeviceReadIOps": [{"Path": "device_path", "Rate": rate}]`, for example:
`"BlkioDeviceReadIOps": [{"Path": "/dev/sda", "Rate": "1000"}]`
- **BlkioDeviceWiiteIOps** - Limit write rate (IO per second) to a device in the form of: `"BlkioDeviceWriteIOps": [{"Path": "device_path", "Rate": rate}]`, for example:
`"BlkioDeviceWriteIOps": [{"Path": "/dev/sda", "Rate": "1000"}]`
- **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.
@ -465,6 +471,8 @@ Return low-level information on the container `id`
"BlkioWeightDevice": [{}], "BlkioWeightDevice": [{}],
"BlkioDeviceReadBps": [{}], "BlkioDeviceReadBps": [{}],
"BlkioDeviceWriteBps": [{}], "BlkioDeviceWriteBps": [{}],
"BlkioDeviceReadIOps": [{}],
"BlkioDeviceWriteIOps": [{}],
"CapAdd": null, "CapAdd": null,
"CapDrop": null, "CapDrop": null,
"ContainerIDFile": "", "ContainerIDFile": "",

View file

@ -31,7 +31,9 @@ Creates a new container.
--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-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb)
--device-read-iops=[] Limit read rate (IO per second) from a device (e.g., --device-read-iops=/dev/sda:1000)
--device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb) --device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb)
--device-write-iops=[] Limit write rate (IO per second) to a device (e.g., --device-write-iops=/dev/sda:1000)
--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

@ -30,7 +30,9 @@ parent = "smn_cli"
-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-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb)
--device-read-iops=[] Limit read rate (IO per second) from a device (e.g., --device-read-iops=/dev/sda:1000)
--device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb) --device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb)
--device-write-iops=[] Limit write rate (IO per second) to a device (e.g., --device-write-bps=/dev/sda:1000)
--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

@ -633,6 +633,8 @@ container:
| `--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-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`. | | `--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`. |
| `--device-read-iops="" ` | Limit read rate (IO per second) from a device (format: `<device-path>:<number>`). Number is a positive integer. |
| `--device-write-iops="" ` | Limit write rate (IO per second) to a device (format: `<device-path>:<number>`). Number is a positive integer. |
| `--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`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`. | | `--shm-size=""` | Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`. |
@ -984,15 +986,15 @@ on `/dev/sda` setting that weight to `200`:
--blkio-weight-device "/dev/sda:200" \ --blkio-weight-device "/dev/sda:200" \
ubuntu ubuntu
The `--device-read-bps` flag limits the read rate from a device. For example, The `--device-read-bps` flag limits the read rate (bytes per second) from a device.
this command creates a container and limits the read rate to `1mb` per second For example, this command creates a container and limits the read rate to `1mb`
from `/dev/sda`: per second from `/dev/sda`:
$ docker run -it --device-read-bps /dev/sda:1mb ubuntu $ docker run -it --device-read-bps /dev/sda:1mb ubuntu
The `--device-write-bps` flag limits the write rate to a device. For example, The `--device-write-bps` flag limits the write rate (bytes per second)to a device.
this command creates a container and limits the write rate to `1mb` per second For example, this command creates a container and limits the write rate to `1mb`
for `/dev/sda`: per second for `/dev/sda`:
$ docker run -it --device-write-bps /dev/sda:1mb ubuntu $ docker run -it --device-write-bps /dev/sda:1mb ubuntu
@ -1000,6 +1002,21 @@ 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` and write rates must be a positive integer. You can specify the rate in `kb`
(kilobytes), `mb` (megabytes), or `gb` (gigabytes). (kilobytes), `mb` (megabytes), or `gb` (gigabytes).
The `--device-read-iops` flag limits read rate (IO per second) from a device.
For example, this command creates a container and limits the read rate to
`1000` IO per second from `/dev/sda`:
$ docker run -ti --device-read-iops /dev/sda:1000 ubuntu
The `--device-write-iops` flag limits write rate (IO per second) to a device.
For example, this command creates a container and limits the write rate to
`1000` IO per second to `/dev/sda`:
$ docker run -ti --device-write-iops /dev/sda:1000 ubuntu
Both flags take limits in the `<device-path>:<limit>` format. Both read and
write rates must be a positive integer.
## Additional groups ## Additional groups
--group-add: Add Linux capabilities --group-add: Add Linux capabilities

View file

@ -267,6 +267,18 @@ func (s *DockerSuite) TestRunWithBlkioInvalidDeviceWriteBps(c *check.C) {
c.Assert(err, check.NotNil, check.Commentf(out)) c.Assert(err, check.NotNil, check.Commentf(out))
} }
func (s *DockerSuite) TestRunWithBlkioInvalidReadiopsDevice(c *check.C) {
testRequires(c, blkioWeight)
out, _, err := dockerCmdWithError("run", "--device-read-iops", "/dev/sdX:500", "busybox", "true")
c.Assert(err, check.NotNil, check.Commentf(out))
}
func (s *DockerSuite) TestRunWithBlkioInvalidWriteiopsDevice(c *check.C) {
testRequires(c, blkioWeight)
out, _, err := dockerCmdWithError("run", "--device-write-iops", "/dev/sdX: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

@ -21,7 +21,9 @@ docker-create - Create a new container
[**--cpuset-mems**[=*CPUSET-MEMS*]] [**--cpuset-mems**[=*CPUSET-MEMS*]]
[**--device**[=*[]*]] [**--device**[=*[]*]]
[**--device-read-bps**[=*[]*]] [**--device-read-bps**[=*[]*]]
[**--device-read-iops**[=*[]*]]
[**--device-write-bps**[=*[]*]] [**--device-write-bps**[=*[]*]]
[**--device-write-iops**[=*[]*]]
[**--dns**[=*[]*]] [**--dns**[=*[]*]]
[**--dns-search**[=*[]*]] [**--dns-search**[=*[]*]]
[**--dns-opt**[=*[]*]] [**--dns-opt**[=*[]*]]
@ -130,9 +132,15 @@ two memory nodes.
**--device-read-bps**=[] **--device-read-bps**=[]
Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb) Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)
**--device-read-iops**=[]
Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000)
**--device-write-bps**=[] **--device-write-bps**=[]
Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb) Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb)
**--device-write-iops**=[]
Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)
**--dns**=[] **--dns**=[]
Set custom DNS servers Set custom DNS servers

View file

@ -22,7 +22,9 @@ docker-run - Run a command in a new container
[**-d**|**--detach**[=*false*]] [**-d**|**--detach**[=*false*]]
[**--device**[=*[]*]] [**--device**[=*[]*]]
[**--device-read-bps**[=*[]*]] [**--device-read-bps**[=*[]*]]
[**--device-read-iops**[=*[]*]]
[**--device-write-bps**[=*[]*]] [**--device-write-bps**[=*[]*]]
[**--device-write-iops**[=*[]*]]
[**--dns**[=*[]*]] [**--dns**[=*[]*]]
[**--dns-opt**[=*[]*]] [**--dns-opt**[=*[]*]]
[**--dns-search**[=*[]*]] [**--dns-search**[=*[]*]]
@ -197,9 +199,15 @@ stopping the process by pressing the keys CTRL-P CTRL-Q.
**--device-read-bps**=[] **--device-read-bps**=[]
Limit read rate from a device (e.g. --device-read-bps=/dev/sda:1mb) Limit read rate from a device (e.g. --device-read-bps=/dev/sda:1mb)
**--device-read-iops**=[]
Limit read rate from a device (e.g. --device-read-iops=/dev/sda:1000)
**--device-write-bps**=[] **--device-write-bps**=[]
Limit write rate to a device (e.g. --device-write-bps=/dev/sda:1mb) Limit write rate to a device (e.g. --device-write-bps=/dev/sda:1mb)
**--device-write-iops**=[]
Limit write rate a a device (e.g. --device-write-iops=/dev/sda:1000)
**--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

@ -219,6 +219,29 @@ func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
}, nil }, nil
} }
// ValidateThrottleIOpsDevice validates that the specified string has a valid device-rate format.
func ValidateThrottleIOpsDevice(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 := strconv.ParseUint(split[1], 10, 64)
if err != nil {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
}
if rate < 0 {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
}
return &blkiodev.ThrottleDevice{
Path: split[0],
Rate: uint64(rate),
}, nil
}
// ValidateEnv validates an environment variable and returns it. // ValidateEnv validates an environment variable and returns it.
// If no value is specified, it returns the current value using os.Getenv. // If no value is specified, it returns the current value using os.Getenv.
// //

View file

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

View file

@ -136,11 +136,22 @@ func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
if !quiet && !writeBpsDevice { if !quiet && !writeBpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device") logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device")
} }
readIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_iops_device")
if !quiet && !readIOpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.read_iops_device")
}
writeIOpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_iops_device")
if !quiet && !writeIOpsDevice {
logrus.Warn("Your kernel does not support cgroup blkio throttle.write_iops_device")
}
return cgroupBlkioInfo{ return cgroupBlkioInfo{
BlkioWeight: weight, BlkioWeight: weight,
BlkioWeightDevice: weightDevice, BlkioWeightDevice: weightDevice,
BlkioReadBpsDevice: readBpsDevice, BlkioReadBpsDevice: readBpsDevice,
BlkioWriteBpsDevice: writeBpsDevice, BlkioWriteBpsDevice: writeBpsDevice,
BlkioReadIOpsDevice: readIOpsDevice,
BlkioWriteIOpsDevice: writeIOpsDevice,
} }
} }

View file

@ -171,22 +171,24 @@ 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
BlkioDeviceReadBps []*blkiodev.ThrottleDevice BlkioDeviceReadBps []*blkiodev.ThrottleDevice
BlkioDeviceWriteBps []*blkiodev.ThrottleDevice BlkioDeviceWriteBps []*blkiodev.ThrottleDevice
CPUPeriod int64 `json:"CpuPeriod"` // CPU CFS (Completely Fair Scheduler) period BlkioDeviceReadIOps []*blkiodev.ThrottleDevice
CPUQuota int64 `json:"CpuQuota"` // CPU CFS (Completely Fair Scheduler) quota BlkioDeviceWriteIOps []*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

@ -57,6 +57,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
flDeviceReadBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice) flDeviceReadBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice)
flDeviceWriteBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice) flDeviceWriteBps = opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice)
flLinks = opts.NewListOpts(ValidateLink) flLinks = opts.NewListOpts(ValidateLink)
flDeviceReadIOps = opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice)
flDeviceWriteIOps = opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice)
flEnv = opts.NewListOpts(opts.ValidateEnv) flEnv = opts.NewListOpts(opts.ValidateEnv)
flLabels = opts.NewListOpts(opts.ValidateEnv) flLabels = opts.NewListOpts(opts.ValidateEnv)
flDevices = opts.NewListOpts(ValidateDevice) flDevices = opts.NewListOpts(ValidateDevice)
@ -118,6 +120,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
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(&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(&flDeviceWriteBps, []string{"-device-write-bps"}, "Limit write rate (bytes per second) to a device")
cmd.Var(&flDeviceReadIOps, []string{"-device-read-iops"}, "Limit read rate (IO per second) from a device")
cmd.Var(&flDeviceWriteIOps, []string{"-device-write-iops"}, "Limit write rate (IO 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")
@ -343,23 +347,25 @@ 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(),
BlkioDeviceReadBps: flDeviceReadBps.GetList(), BlkioDeviceReadBps: flDeviceReadBps.GetList(),
BlkioDeviceWriteBps: flDeviceWriteBps.GetList(), BlkioDeviceWriteBps: flDeviceWriteBps.GetList(),
Ulimits: flUlimits.GetList(), BlkioDeviceReadIOps: flDeviceReadIOps.GetList(),
Devices: deviceMappings, BlkioDeviceWriteIOps: flDeviceWriteIOps.GetList(),
Ulimits: flUlimits.GetList(),
Devices: deviceMappings,
} }
config := &Config{ config := &Config{