浏览代码

Addition of "--shm-size" to which size of /dev/shm is changed.

- Optional "--shm-size=" was added to the sub-command(run, create,and build).
- The size of /dev/shm in the container can be changed
  when container is made.
- Being able to specify is a numerical value that applies number,
  b, k, m, and g.
- The default value is 64MB, when this option is not set.
- It deals with both native and lxc drivers.

Signed-off-by: NIWA Hideyuki <niwa.hiedyuki@jp.fujitsu.com>
NIWA Hideyuki 10 年之前
父节点
当前提交
5aeaf2a0c4

+ 14 - 0
api/client/build.go

@@ -59,6 +59,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 	dockerfileName := cmd.String([]string{"f", "-file"}, "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
 	flMemoryString := cmd.String([]string{"m", "-memory"}, "", "Memory limit")
 	flMemorySwap := cmd.String([]string{"-memory-swap"}, "", "Total memory (memory + swap), '-1' to disable swap")
+	flShmSize := cmd.String([]string{"-shm-size"}, "", "Size of /dev/shm, default value is 64MB")
 	flCPUShares := cmd.Int64([]string{"#c", "-cpu-shares"}, 0, "CPU shares (relative weight)")
 	flCPUPeriod := cmd.Int64([]string{"-cpu-period"}, 0, "Limit the CPU CFS (Completely Fair Scheduler) period")
 	flCPUQuota := cmd.Int64([]string{"-cpu-quota"}, 0, "Limit the CPU CFS (Completely Fair Scheduler) quota")
@@ -210,6 +211,18 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 		}
 	}
 
+	var shmSize int64 = 67108864 // initial SHM size is 64MB
+	if *flShmSize != "" {
+		parsedShmSize, err := units.RAMInBytes(*flShmSize)
+		if err != nil {
+			return err
+		}
+		if parsedShmSize <= 0 {
+			return fmt.Errorf("--shm-size: SHM size must be greater than 0 . You specified: %v ", parsedShmSize)
+		}
+		shmSize = parsedShmSize
+	}
+
 	// Send the build context
 	v := url.Values{
 		"t": flTags.GetAll(),
@@ -248,6 +261,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
 	v.Set("cpuperiod", strconv.FormatInt(*flCPUPeriod, 10))
 	v.Set("memory", strconv.FormatInt(memory, 10))
 	v.Set("memswap", strconv.FormatInt(memorySwap, 10))
+	v.Set("shmsize", strconv.FormatInt(shmSize, 10))
 	v.Set("cgroupparent", *flCgroupParent)
 
 	v.Set("dockerfile", relDockerfile)

+ 1 - 0
api/server/router/local/image.go

@@ -323,6 +323,7 @@ func (s *router) postBuild(ctx context.Context, w http.ResponseWriter, r *http.R
 	buildConfig.ForceRemove = httputils.BoolValue(r, "forcerm")
 	buildConfig.MemorySwap = httputils.Int64ValueOrZero(r, "memswap")
 	buildConfig.Memory = httputils.Int64ValueOrZero(r, "memory")
+	buildConfig.ShmSize = httputils.Int64ValueOrZero(r, "shmsize")
 	buildConfig.CPUShares = httputils.Int64ValueOrZero(r, "cpushares")
 	buildConfig.CPUPeriod = httputils.Int64ValueOrZero(r, "cpuperiod")
 	buildConfig.CPUQuota = httputils.Int64ValueOrZero(r, "cpuquota")

+ 1 - 0
builder/dockerfile/builder.go

@@ -60,6 +60,7 @@ type Config struct {
 
 	Memory       int64
 	MemorySwap   int64
+	ShmSize      int64
 	CPUShares    int64
 	CPUPeriod    int64
 	CPUQuota     int64

+ 1 - 0
builder/dockerfile/internals.go

@@ -508,6 +508,7 @@ func (b *Builder) create() (*daemon.Container, error) {
 		CgroupParent: b.CgroupParent,
 		Memory:       b.Memory,
 		MemorySwap:   b.MemorySwap,
+		ShmSize:      b.ShmSize,
 		Ulimits:      b.Ulimits,
 		Isolation:    b.Isolation,
 	}

+ 6 - 1
daemon/container_unix.go

@@ -1357,7 +1357,12 @@ func (daemon *Daemon) setupIpcDirs(container *Container) error {
 			return err
 		}
 
-		if err := syscall.Mount("shm", shmPath, "tmpfs", uintptr(syscall.MS_NOEXEC|syscall.MS_NOSUID|syscall.MS_NODEV), label.FormatMountLabel("mode=1777,size=65536k", container.getMountLabel())); err != nil {
+		// When ShmSize is 0 or less, the SHM size is set to 64MB.
+		if container.hostConfig.ShmSize <= 0 {
+			container.hostConfig.ShmSize = 67108864
+		}
+		shmproperty := "mode=1777,size=" + strconv.FormatInt(container.hostConfig.ShmSize, 10)
+		if err := syscall.Mount("shm", shmPath, "tmpfs", uintptr(syscall.MS_NOEXEC|syscall.MS_NOSUID|syscall.MS_NODEV), label.FormatMountLabel(shmproperty, container.getMountLabel())); err != nil {
 			return fmt.Errorf("mounting shm tmpfs: %s", err)
 		}
 		if err := os.Chown(shmPath, rootUID, rootGID); err != nil {

+ 6 - 2
docs/reference/api/docker_remote_api_v1.22.md

@@ -208,7 +208,8 @@ Create a container
              "LogConfig": { "Type": "json-file", "Config": {} },
              "SecurityOpt": [""],
              "CgroupParent": "",
-             "VolumeDriver": ""
+             "VolumeDriver": "",
+             "ShmSize": 67108864
           }
       }
 
@@ -318,6 +319,7 @@ Json Parameters:
           `json-file` logging driver.
     -   **CgroupParent** - Path to `cgroups` under which the container's `cgroup` is created. If the path is not absolute, the path is considered to be relative to the `cgroups` path of the init process. Cgroups are created if they do not already exist.
     -   **VolumeDriver** - Driver that this container users to mount volumes.
+    -   **ShmSize** - Size of `/dev/shm` in bytes. The size must be greater than 0.  If omitted the system uses 64MB.
 
 Query Parameters:
 
@@ -430,7 +432,8 @@ Return low-level information on the container `id`
 			"SecurityOpt": null,
 			"VolumesFrom": null,
 			"Ulimits": [{}],
-			"VolumeDriver": ""
+			"VolumeDriver": "",
+			"ShmSize": 67108864
 		},
 		"HostnamePath": "/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/hostname",
 		"HostsPath": "/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/hosts",
@@ -1435,6 +1438,7 @@ Query Parameters:
         context for command(s) run via the Dockerfile's `RUN` instruction or for
         variable expansion in other Dockerfile instructions. This is not meant for
         passing secret values. [Read more about the buildargs instruction](../../reference/builder.md#arg)
+-   **shmsize** - Size of `/dev/shm` in bytes. The size must be greater than 0.  If omitted the system uses 64MB.
 
     Request Headers:
 

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

@@ -31,6 +31,7 @@ parent = "smn_cli"
       --pull=false                    Always attempt to pull a newer version of the image
       -q, --quiet=false               Suppress the verbose output generated by the containers
       --rm=true                       Remove intermediate containers after a successful build
+      --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`.
       -t, --tag=[]                    Name and optionally a tag in the 'name:tag' format
       --ulimit=[]                     Ulimit options
 

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

@@ -65,6 +65,7 @@ Creates a new container.
       --restart="no"                Restart policy (no, on-failure[:max-retry], always, unless-stopped)
       --security-opt=[]             Security options
       --stop-signal="SIGTERM"       Signal to stop a container
+      --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`.
       -t, --tty=false               Allocate a pseudo-TTY
       -u, --user=""                 Username or UID
       --ulimit=[]                   Ulimit options

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

@@ -68,6 +68,7 @@ parent = "smn_cli"
       --read-only=false             Mount the container's root filesystem as read only
       --restart="no"                Restart policy (no, on-failure[:max-retry], always, unless-stopped)
       --rm=false                    Automatically remove the container when it exits
+      --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`.
       --security-opt=[]             Security Options
       --sig-proxy=true              Proxy received signals to the process
       --stop-signal="SIGTERM"       Signal to stop a container

+ 4 - 0
docs/reference/run.md

@@ -626,6 +626,10 @@ container:
 | `--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.        |
+| `--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`.                                                            |
 
 ### User memory constraints
 

+ 6 - 0
man/docker-build.1.md

@@ -19,6 +19,7 @@ docker-build - Build a new image from the source code at PATH
 [**-t**|**--tag**[=*[]*]]
 [**-m**|**--memory**[=*MEMORY*]]
 [**--memory-swap**[=*MEMORY-SWAP*]]
+[**--shm-size**[=*SHM-SIZE*]]
 [**--cpu-period**[=*0*]]
 [**--cpu-quota**[=*0*]]
 [**--cpuset-cpus**[=*CPUSET-CPUS*]]
@@ -90,6 +91,11 @@ set as the **URL**, the repository is cloned locally and then sent as the contex
 **--memory-swap**=*MEMORY-SWAP*
   Total memory (memory + swap), '-1' to disable swap.
 
+**--shm-size**=*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`.
+
 **--cpu-shares**=*0*
   CPU shares (relative weight).
 

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

@@ -54,6 +54,7 @@ docker-create - Create a new container
 [**--restart**[=*RESTART*]]
 [**--security-opt**[=*[]*]]
 [**--stop-signal**[=*SIGNAL*]]
+[**--shm-size**[=*[]*]]
 [**-t**|**--tty**[=*false*]]
 [**-u**|**--user**[=*USER*]]
 [**--ulimit**[=*[]*]]
@@ -252,6 +253,11 @@ This value should always larger than **-m**, so you should always use this with
 **--restart**="*no*"
    Restart policy to apply when a container exits (no, on-failure[:max-retry], always, unless-stopped).
 
+**--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`.
+
 **--security-opt**=[]
    Security Options
 

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

@@ -56,6 +56,7 @@ docker-run - Run a command in a new container
 [**--rm**[=*false*]]
 [**--security-opt**[=*[]*]]
 [**--stop-signal**[=*SIGNAL*]]
+[**--shm-size**[=*[]*]]
 [**--sig-proxy**[=*true*]]
 [**-t**|**--tty**[=*false*]]
 [**-u**|**--user**[=*USER*]]
@@ -410,6 +411,11 @@ its root filesystem mounted as read only prohibiting any writes.
 **--stop-signal**=*SIGTERM*
   Signal to stop a container. Default is SIGTERM.
 
+**--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`.
+
 **--sig-proxy**=*true*|*false*
    Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is *true*.
 

+ 1 - 0
runconfig/hostconfig.go

@@ -211,6 +211,7 @@ type HostConfig struct {
 	SecurityOpt       []string              // List of string values to customize labels for MLS systems, such as SELinux.
 	Ulimits           []*ulimit.Ulimit      // List of ulimits to be set in the container
 	UTSMode           UTSMode               // UTS namespace to use for the container
+	ShmSize           int64                 // Total shm memory usage
 
 	// Applicable to Windows
 	ConsoleSize [2]int         // Initial console size

+ 14 - 0
runconfig/parse.go

@@ -105,6 +105,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		flVolumeDriver      = cmd.String([]string{"-volume-driver"}, "", "Optional volume driver for the container")
 		flStopSignal        = cmd.String([]string{"-stop-signal"}, signal.DefaultStopSignal, fmt.Sprintf("Signal to stop a container, %v by default", signal.DefaultStopSignal))
 		flIsolation         = cmd.String([]string{"-isolation"}, "", "Container isolation level")
+		flShmSize           = cmd.String([]string{"-shm-size"}, "", "Size of /dev/shm, default value is 64MB")
 	)
 
 	cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR")
@@ -200,6 +201,18 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		return nil, nil, cmd, fmt.Errorf("Invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
 	}
 
+	var parsedShm int64 = 67108864 // initial SHM size is 64MB
+	if *flShmSize != "" {
+		var err error
+		parsedShm, err = units.RAMInBytes(*flShmSize)
+		if err != nil {
+			return nil, nil, cmd, fmt.Errorf("--shm-size: invalid SHM size")
+		}
+		if parsedShm <= 0 {
+			return nil, nil, cmd, fmt.Errorf("--shm-size: SHM size must be greater than 0 . You specified: %v ", parsedShm)
+		}
+	}
+
 	var binds []string
 	// add any bind targets to the list of container volumes
 	for bind := range flVolumes.GetMap() {
@@ -381,6 +394,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		CgroupParent:   *flCgroupParent,
 		VolumeDriver:   *flVolumeDriver,
 		Isolation:      IsolationLevel(*flIsolation),
+		ShmSize:        parsedShm,
 	}
 
 	// When allocating stdin in attached mode, close stdin at client disconnect

+ 12 - 0
runconfig/parse_test.go

@@ -524,6 +524,18 @@ func TestParseModes(t *testing.T) {
 	if !hostconfig.UTSMode.Valid() {
 		t.Fatalf("Expected a valid UTSMode, got %v", hostconfig.UTSMode)
 	}
+	// shm-size ko
+	if _, _, _, err = parseRun([]string{"--shm-size=a128m", "img", "cmd"}); err == nil || err.Error() != "--shm-size: invalid SHM size" {
+		t.Fatalf("Expected an error with message '--shm-size: invalid SHM size', got %v", err)
+	}
+	// shm-size ok
+	_, hostconfig, _, err = parseRun([]string{"--shm-size=128m", "img", "cmd"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if hostconfig.ShmSize != 134217728 {
+		t.Fatalf("Expected a valid ShmSize, got %v", hostconfig.ShmSize)
+	}
 }
 
 func TestParseRestartPolicy(t *testing.T) {