Procházet zdrojové kódy

Add support for blkio.weight_device

Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
Ma Shimiao před 10 roky
rodič
revize
0fbfa1449d

+ 1 - 0
contrib/completion/bash/docker

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

+ 1 - 0
contrib/completion/zsh/_docker

@@ -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"

+ 15 - 9
daemon/container_unix.go

@@ -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 {

+ 1 - 0
daemon/daemon.go

@@ -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

+ 22 - 0
daemon/daemon_unix.go

@@ -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.")

+ 5 - 0
daemon/daemon_windows.go

@@ -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
 }

+ 12 - 9
daemon/execdriver/driver_unix.go

@@ -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
 	}

+ 3 - 0
docs/reference/api/docker_remote_api_v1.22.md

@@ -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": "",

+ 1 - 0
docs/reference/commandline/create.md

@@ -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

+ 1 - 0
docs/reference/commandline/run.md

@@ -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

+ 22 - 2
docs/reference/run.md

@@ -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

+ 6 - 0
integration-cli/docker_cli_run_unix_test.go

@@ -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)

+ 4 - 0
man/docker-create.1.md

@@ -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)
 

+ 11 - 0
man/docker-run.1.md

@@ -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.

+ 28 - 0
opts/opts.go

@@ -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 - 0
opts/weightdevice.go

@@ -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 - 0
pkg/blkiodev/blkiodev.go

@@ -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)
+}

+ 3 - 0
pkg/sysinfo/sysinfo.go

@@ -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 {

+ 11 - 3
pkg/sysinfo/sysinfo_linux.go

@@ -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.

+ 3 - 1
runconfig/hostconfig.go

@@ -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.

+ 9 - 6
runconfig/parse.go

@@ -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,