Skip to content

Commit

Permalink
Merge pull request moby#29692 from yongtang/29492-daemon-shm-size
Browse files Browse the repository at this point in the history
Add daemon option `--default-shm-size`
  • Loading branch information
vdemeester authored Feb 1, 2017
2 parents 4c1b40b + d198286 commit 354bd4a
Show file tree
Hide file tree
Showing 20 changed files with 199 additions and 64 deletions.
14 changes: 3 additions & 11 deletions cli/command/container/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ type containerOptions struct {
stopSignal string
stopTimeout int
isolation string
shmSize string
shmSize opts.MemBytes
noHealthcheck bool
healthCmd string
healthInterval time.Duration
Expand Down Expand Up @@ -270,7 +270,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
flags.StringVar(&copts.ipcMode, "ipc", "", "IPC namespace to use")
flags.StringVar(&copts.isolation, "isolation", "", "Container isolation technology")
flags.StringVar(&copts.pidMode, "pid", "", "PID namespace to use")
flags.StringVar(&copts.shmSize, "shm-size", "", "Size of /dev/shm, default value is 64MB")
flags.Var(&copts.shmSize, "shm-size", "Size of /dev/shm")
flags.StringVar(&copts.utsMode, "uts", "", "UTS namespace to use")
flags.StringVar(&copts.runtime, "runtime", "", "Runtime to use for this container")

Expand Down Expand Up @@ -349,14 +349,6 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*container.Config, *c
return nil, nil, nil, fmt.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
}

var shmSize int64
if copts.shmSize != "" {
shmSize, err = units.RAMInBytes(copts.shmSize)
if err != nil {
return nil, nil, nil, err
}
}

// TODO FIXME units.RAMInBytes should have a uint64 version
var maxIOBandwidth int64
if copts.ioMaxBandwidth != "" {
Expand Down Expand Up @@ -629,7 +621,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*container.Config, *c
LogConfig: container.LogConfig{Type: copts.loggingDriver, Config: loggingOpts},
VolumeDriver: copts.volumeDriver,
Isolation: container.Isolation(copts.isolation),
ShmSize: shmSize,
ShmSize: copts.shmSize.Value(),
Resources: resources,
Tmpfs: tmpfs,
Sysctls: copts.sysctls.GetAll(),
Expand Down
5 changes: 3 additions & 2 deletions cli/command/container/opts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,9 @@ func TestParseModes(t *testing.T) {
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() != "invalid size: 'a128m'" {
t.Fatalf("Expected an error with message 'invalid size: a128m', got %v", err)
expectedErr := `invalid argument "a128m" for --shm-size=a128m: invalid size: 'a128m'`
if _, _, _, err = parseRun([]string{"--shm-size=a128m", "img", "cmd"}); err == nil || err.Error() != expectedErr {
t.Fatalf("Expected an error with message '%v', got %v", expectedErr, err)
}
// shm-size ok
_, hostconfig, _, err = parseRun([]string{"--shm-size=128m", "img", "cmd"})
Expand Down
14 changes: 3 additions & 11 deletions cli/command/image/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type buildOptions struct {
ulimits *opts.UlimitOpt
memory string
memorySwap string
shmSize string
shmSize opts.MemBytes
cpuShares int64
cpuPeriod int64
cpuQuota int64
Expand Down Expand Up @@ -89,7 +89,7 @@ func NewBuildCommand(dockerCli *command.DockerCli) *cobra.Command {
flags.StringVarP(&options.dockerfileName, "file", "f", "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
flags.StringVarP(&options.memory, "memory", "m", "", "Memory limit")
flags.StringVar(&options.memorySwap, "memory-swap", "", "Swap limit equal to memory plus swap: '-1' to enable unlimited swap")
flags.StringVar(&options.shmSize, "shm-size", "", "Size of /dev/shm, default value is 64MB")
flags.Var(&options.shmSize, "shm-size", "Size of /dev/shm")
flags.Int64VarP(&options.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
flags.Int64Var(&options.cpuPeriod, "cpu-period", 0, "Limit the CPU CFS (Completely Fair Scheduler) period")
flags.Int64Var(&options.cpuQuota, "cpu-quota", 0, "Limit the CPU CFS (Completely Fair Scheduler) quota")
Expand Down Expand Up @@ -274,14 +274,6 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
}
}

var shmSize int64
if options.shmSize != "" {
shmSize, err = units.RAMInBytes(options.shmSize)
if err != nil {
return err
}
}

authConfigs, _ := dockerCli.GetAllCredentials()
buildOptions := types.ImageBuildOptions{
Memory: memory,
Expand All @@ -300,7 +292,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
CPUPeriod: options.cpuPeriod,
CgroupParent: options.cgroupParent,
Dockerfile: relDockerfile,
ShmSize: shmSize,
ShmSize: options.shmSize.Value(),
Ulimits: options.ulimits.GetList(),
BuildArgs: runconfigopts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()),
AuthConfigs: authConfigs,
Expand Down
25 changes: 2 additions & 23 deletions cli/command/service/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,13 @@ import (
"github.com/docker/docker/opts"
runconfigopts "github.com/docker/docker/runconfig/opts"
"github.com/docker/go-connections/nat"
units "github.com/docker/go-units"
"github.com/spf13/cobra"
)

type int64Value interface {
Value() int64
}

type memBytes int64

func (m *memBytes) String() string {
return units.BytesSize(float64(m.Value()))
}

func (m *memBytes) Set(value string) error {
val, err := units.RAMInBytes(value)
*m = memBytes(val)
return err
}

func (m *memBytes) Type() string {
return "bytes"
}

func (m *memBytes) Value() int64 {
return int64(*m)
}

// PositiveDurationOpt is an option type for time.Duration that uses a pointer.
// It bahave similarly to DurationOpt but only allows positive duration values.
type PositiveDurationOpt struct {
Expand Down Expand Up @@ -149,9 +128,9 @@ type updateOptions struct {

type resourceOptions struct {
limitCPU opts.NanoCPUs
limitMemBytes memBytes
limitMemBytes opts.MemBytes
resCPU opts.NanoCPUs
resMemBytes memBytes
resMemBytes opts.MemBytes
}

func (r *resourceOptions) ToResourceRequirements() *swarm.ResourceRequirements {
Expand Down
4 changes: 2 additions & 2 deletions cli/command/service/opts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import (
)

func TestMemBytesString(t *testing.T) {
var mem memBytes = 1048576
var mem opts.MemBytes = 1048576
assert.Equal(t, mem.String(), "1 MiB")
}

func TestMemBytesSetAndValue(t *testing.T) {
var mem memBytes
var mem opts.MemBytes
assert.NilError(t, mem.Set("5kb"))
assert.Equal(t, mem.Value(), int64(5120))
}
Expand Down
4 changes: 1 addition & 3 deletions container/container_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import (
)

const (
// DefaultSHMSize is the default size (64MB) of the SHM which will be mounted in the container
DefaultSHMSize int64 = 67108864
containerSecretMountPath = "/run/secrets"
containerSecretMountPath = "/run/secrets"
)

// Container holds the fields specific to unixen implementations.
Expand Down
6 changes: 6 additions & 0 deletions daemon/config_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var (
defaultPidFile = "/var/run/docker.pid"
defaultGraph = "/var/lib/docker"
defaultExecRoot = "/var/run/docker"
defaultShmSize = int64(67108864)
)

// Config defines the configuration of a docker daemon.
Expand All @@ -36,6 +37,7 @@ type Config struct {
Init bool `json:"init,omitempty"`
InitPath string `json:"init-path,omitempty"`
SeccompProfile string `json:"seccomp-profile,omitempty"`
ShmSize opts.MemBytes `json:"default-shm-size,omitempty"`
}

// bridgeConfig stores all the bridge driver specific
Expand Down Expand Up @@ -66,6 +68,9 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {

config.Ulimits = make(map[string]*units.Ulimit)

// Set default value for `--default-shm-size`
config.ShmSize = opts.MemBytes(defaultShmSize)

// Then platform-specific install flags
flags.BoolVar(&config.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support")
flags.Var(opts.NewUlimitOpt(&config.Ulimits), "default-ulimit", "Default ulimits for containers")
Expand All @@ -89,6 +94,7 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {
flags.Int64Var(&config.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds")
flags.Int64Var(&config.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds")
flags.StringVar(&config.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile")
flags.Var(&config.ShmSize, "default-shm-size", "Default shm size for containers")

config.attachExperimentalFlags(flags)
}
Expand Down
54 changes: 54 additions & 0 deletions daemon/config_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ package daemon

import (
"io/ioutil"
"runtime"

"testing"

"github.com/docker/docker/pkg/testutil/assert"
"github.com/spf13/pflag"
)

func TestDaemonConfigurationMerge(t *testing.T) {
Expand Down Expand Up @@ -78,3 +83,52 @@ func TestDaemonConfigurationMerge(t *testing.T) {
}
}
}

func TestDaemonParseShmSize(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("ShmSize not supported on Solaris\n")
}
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)

config := &Config{}
config.InstallFlags(flags)
// By default `--default-shm-size=64M`
expectedValue := 64 * 1024 * 1024
if config.ShmSize.Value() != int64(expectedValue) {
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
}
assert.NilError(t, flags.Set("default-shm-size", "128M"))
expectedValue = 128 * 1024 * 1024
if config.ShmSize.Value() != int64(expectedValue) {
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
}
}

func TestDaemonConfigurationMergeShmSize(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("ShmSize not supported on Solaris\n")
}
f, err := ioutil.TempFile("", "docker-config-")
if err != nil {
t.Fatal(err)
}

configFile := f.Name()

f.Write([]byte(`
{
"default-shm-size": "1g"
}`))

f.Close()

c := &Config{}
cc, err := MergeDaemonConfigurations(c, nil, configFile)
if err != nil {
t.Fatal(err)
}
expectedValue := 1 * 1024 * 1024 * 1024
if cc.ShmSize.Value() != int64(expectedValue) {
t.Fatalf("expected default shm size %d, got %d", expectedValue, cc.ShmSize.Value())
}
}
2 changes: 1 addition & 1 deletion daemon/container_operations_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
return err
}

shmSize := container.DefaultSHMSize
shmSize := int64(daemon.configStore.ShmSize)
if c.HostConfig.ShmSize != 0 {
shmSize = c.HostConfig.ShmSize
}
Expand Down
14 changes: 11 additions & 3 deletions daemon/daemon_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,10 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
hostConfig.MemorySwap = hostConfig.Memory * 2
}
if hostConfig.ShmSize == 0 {
hostConfig.ShmSize = container.DefaultSHMSize
hostConfig.ShmSize = defaultShmSize
if daemon.configStore != nil {
hostConfig.ShmSize = int64(daemon.configStore.ShmSize)
}
}
var err error
opts, err := daemon.generateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode, hostConfig.Privileged)
Expand Down Expand Up @@ -576,6 +579,10 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
daemon.configStore.DefaultRuntime = config.DefaultRuntime
}

if config.IsValueSet("default-shm-size") {
daemon.configStore.ShmSize = config.ShmSize
}

// Update attributes
var runtimeList bytes.Buffer
for name, rt := range daemon.configStore.Runtimes {
Expand All @@ -586,8 +593,9 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
}

return map[string]string{
"runtimes": runtimeList.String(),
"default-runtime": daemon.configStore.DefaultRuntime,
"runtimes": runtimeList.String(),
"default-runtime": daemon.configStore.DefaultRuntime,
"default-shm-size": fmt.Sprintf("%d", daemon.configStore.ShmSize),
}
}

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/commandline/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Options:
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt value Security Options (default [])
--shm-size string Size of /dev/shm, default value is 64MB.
--shm-size bytes 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.
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/commandline/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Options:
--rm Automatically remove the container when it exits
--runtime string Runtime to use for this container
--security-opt value Security Options (default [])
--shm-size string Size of /dev/shm, default value is 64MB.
--shm-size bytes 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.
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/commandline/dockerd.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Options:
--default-gateway value Container default gateway IPv4 address
--default-gateway-v6 value Container default gateway IPv6 address
--default-runtime string Default OCI runtime for containers (default "runc")
--default-shm-size bytes Set the default shm size for containers (default 64 MiB)
--default-ulimit value Default ulimits for containers (default [])
--disable-legacy-registry Disable contacting legacy registries
--dns value DNS server to use (default [])
Expand Down Expand Up @@ -1161,6 +1162,7 @@ This is a full example of the allowed configuration options on Linux:
"cluster-advertise": "",
"max-concurrent-downloads": 3,
"max-concurrent-uploads": 5,
"default-shm-size": "64M",
"shutdown-timeout": 15,
"debug": true,
"hosts": [],
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/commandline/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Options:
--rm Automatically remove the container when it exits
--runtime string Runtime to use for this container
--security-opt value Security Options (default [])
--shm-size string Size of /dev/shm, default value is 64MB.
--shm-size bytes 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.
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/commandline/service_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Options:
--hostname string Container hostname
-l, --label list Service labels (default [])
--limit-cpu decimal Limit CPUs (default 0.000)
--limit-memory bytes Limit Memory (default 0 B)
--limit-memory bytes Limit Memory
--log-driver string Logging driver for service
--log-opt list Logging driver options (default [])
--mode string Service mode (replicated or global) (default "replicated")
Expand All @@ -51,7 +51,7 @@ Options:
--read-only Mount the container's root filesystem as read only
--replicas uint Number of tasks
--reserve-cpu decimal Reserve CPUs (default 0.000)
--reserve-memory bytes Reserve Memory (default 0 B)
--reserve-memory bytes Reserve Memory
--restart-condition string Restart when condition is met (none, on-failure, or any)
--restart-delay duration Delay between restart attempts (ns|us|ms|s|m|h)
--restart-max-attempts uint Maximum number of restarts before giving up
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/commandline/service_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Options:
--label-add list Add or update a service label (default [])
--label-rm list Remove a label by its key (default [])
--limit-cpu decimal Limit CPUs (default 0.000)
--limit-memory bytes Limit Memory (default 0 B)
--limit-memory bytes Limit Memory
--log-driver string Logging driver for service
--log-opt list Logging driver options (default [])
--mount-add mount Add or update a mount on a service
Expand All @@ -61,7 +61,7 @@ Options:
--read-only Mount the container's root filesystem as read only
--replicas uint Number of tasks
--reserve-cpu decimal Reserve CPUs (default 0.000)
--reserve-memory bytes Reserve Memory (default 0 B)
--reserve-memory bytes Reserve Memory
--restart-condition string Restart when condition is met (none, on-failure, or any)
--restart-delay duration Delay between restart attempts (ns|us|ms|s|m|h)
--restart-max-attempts uint Maximum number of restarts before giving up
Expand Down
Loading

0 comments on commit 354bd4a

Please sign in to comment.