mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Merge pull request #29692 from yongtang/29492-daemon-shm-size
Add daemon option `--default-shm-size`
This commit is contained in:
		
						commit
						354bd4aadd
					
				
					 20 changed files with 199 additions and 64 deletions
				
			
		| 
						 | 
					@ -106,7 +106,7 @@ type containerOptions struct {
 | 
				
			||||||
	stopSignal         string
 | 
						stopSignal         string
 | 
				
			||||||
	stopTimeout        int
 | 
						stopTimeout        int
 | 
				
			||||||
	isolation          string
 | 
						isolation          string
 | 
				
			||||||
	shmSize            string
 | 
						shmSize            opts.MemBytes
 | 
				
			||||||
	noHealthcheck      bool
 | 
						noHealthcheck      bool
 | 
				
			||||||
	healthCmd          string
 | 
						healthCmd          string
 | 
				
			||||||
	healthInterval     time.Duration
 | 
						healthInterval     time.Duration
 | 
				
			||||||
| 
						 | 
					@ -270,7 +270,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
 | 
				
			||||||
	flags.StringVar(&copts.ipcMode, "ipc", "", "IPC namespace to use")
 | 
						flags.StringVar(&copts.ipcMode, "ipc", "", "IPC namespace to use")
 | 
				
			||||||
	flags.StringVar(&copts.isolation, "isolation", "", "Container isolation technology")
 | 
						flags.StringVar(&copts.isolation, "isolation", "", "Container isolation technology")
 | 
				
			||||||
	flags.StringVar(&copts.pidMode, "pid", "", "PID namespace to use")
 | 
						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.utsMode, "uts", "", "UTS namespace to use")
 | 
				
			||||||
	flags.StringVar(&copts.runtime, "runtime", "", "Runtime to use for this container")
 | 
						flags.StringVar(&copts.runtime, "runtime", "", "Runtime to use for this container")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
							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
 | 
						// TODO FIXME units.RAMInBytes should have a uint64 version
 | 
				
			||||||
	var maxIOBandwidth int64
 | 
						var maxIOBandwidth int64
 | 
				
			||||||
	if copts.ioMaxBandwidth != "" {
 | 
						if copts.ioMaxBandwidth != "" {
 | 
				
			||||||
| 
						 | 
					@ -629,7 +621,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*container.Config, *c
 | 
				
			||||||
		LogConfig:      container.LogConfig{Type: copts.loggingDriver, Config: loggingOpts},
 | 
							LogConfig:      container.LogConfig{Type: copts.loggingDriver, Config: loggingOpts},
 | 
				
			||||||
		VolumeDriver:   copts.volumeDriver,
 | 
							VolumeDriver:   copts.volumeDriver,
 | 
				
			||||||
		Isolation:      container.Isolation(copts.isolation),
 | 
							Isolation:      container.Isolation(copts.isolation),
 | 
				
			||||||
		ShmSize:        shmSize,
 | 
							ShmSize:        copts.shmSize.Value(),
 | 
				
			||||||
		Resources:      resources,
 | 
							Resources:      resources,
 | 
				
			||||||
		Tmpfs:          tmpfs,
 | 
							Tmpfs:          tmpfs,
 | 
				
			||||||
		Sysctls:        copts.sysctls.GetAll(),
 | 
							Sysctls:        copts.sysctls.GetAll(),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -411,8 +411,9 @@ func TestParseModes(t *testing.T) {
 | 
				
			||||||
		t.Fatalf("Expected a valid UTSMode, got %v", hostconfig.UTSMode)
 | 
							t.Fatalf("Expected a valid UTSMode, got %v", hostconfig.UTSMode)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// shm-size ko
 | 
						// shm-size ko
 | 
				
			||||||
	if _, _, _, err = parseRun([]string{"--shm-size=a128m", "img", "cmd"}); err == nil || err.Error() != "invalid size: 'a128m'" {
 | 
						expectedErr := `invalid argument "a128m" for --shm-size=a128m: invalid size: 'a128m'`
 | 
				
			||||||
		t.Fatalf("Expected an error with message 'invalid size: a128m', got %v", err)
 | 
						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
 | 
						// shm-size ok
 | 
				
			||||||
	_, hostconfig, _, err = parseRun([]string{"--shm-size=128m", "img", "cmd"})
 | 
						_, hostconfig, _, err = parseRun([]string{"--shm-size=128m", "img", "cmd"})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ type buildOptions struct {
 | 
				
			||||||
	ulimits        *opts.UlimitOpt
 | 
						ulimits        *opts.UlimitOpt
 | 
				
			||||||
	memory         string
 | 
						memory         string
 | 
				
			||||||
	memorySwap     string
 | 
						memorySwap     string
 | 
				
			||||||
	shmSize        string
 | 
						shmSize        opts.MemBytes
 | 
				
			||||||
	cpuShares      int64
 | 
						cpuShares      int64
 | 
				
			||||||
	cpuPeriod      int64
 | 
						cpuPeriod      int64
 | 
				
			||||||
	cpuQuota       int64
 | 
						cpuQuota       int64
 | 
				
			||||||
| 
						 | 
					@ -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.dockerfileName, "file", "f", "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
 | 
				
			||||||
	flags.StringVarP(&options.memory, "memory", "m", "", "Memory limit")
 | 
						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.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.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.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")
 | 
						flags.Int64Var(&options.cpuQuota, "cpu-quota", 0, "Limit the CPU CFS (Completely Fair Scheduler) quota")
 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
						authConfigs, _ := dockerCli.GetAllCredentials()
 | 
				
			||||||
	buildOptions := types.ImageBuildOptions{
 | 
						buildOptions := types.ImageBuildOptions{
 | 
				
			||||||
		Memory:         memory,
 | 
							Memory:         memory,
 | 
				
			||||||
| 
						 | 
					@ -300,7 +292,7 @@ func runBuild(dockerCli *command.DockerCli, options buildOptions) error {
 | 
				
			||||||
		CPUPeriod:      options.cpuPeriod,
 | 
							CPUPeriod:      options.cpuPeriod,
 | 
				
			||||||
		CgroupParent:   options.cgroupParent,
 | 
							CgroupParent:   options.cgroupParent,
 | 
				
			||||||
		Dockerfile:     relDockerfile,
 | 
							Dockerfile:     relDockerfile,
 | 
				
			||||||
		ShmSize:        shmSize,
 | 
							ShmSize:        options.shmSize.Value(),
 | 
				
			||||||
		Ulimits:        options.ulimits.GetList(),
 | 
							Ulimits:        options.ulimits.GetList(),
 | 
				
			||||||
		BuildArgs:      runconfigopts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()),
 | 
							BuildArgs:      runconfigopts.ConvertKVStringsToMapWithNil(options.buildArgs.GetAll()),
 | 
				
			||||||
		AuthConfigs:    authConfigs,
 | 
							AuthConfigs:    authConfigs,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,6 @@ import (
 | 
				
			||||||
	"github.com/docker/docker/opts"
 | 
						"github.com/docker/docker/opts"
 | 
				
			||||||
	runconfigopts "github.com/docker/docker/runconfig/opts"
 | 
						runconfigopts "github.com/docker/docker/runconfig/opts"
 | 
				
			||||||
	"github.com/docker/go-connections/nat"
 | 
						"github.com/docker/go-connections/nat"
 | 
				
			||||||
	units "github.com/docker/go-units"
 | 
					 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,26 +18,6 @@ type int64Value interface {
 | 
				
			||||||
	Value() int64
 | 
						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.
 | 
					// PositiveDurationOpt is an option type for time.Duration that uses a pointer.
 | 
				
			||||||
// It bahave similarly to DurationOpt but only allows positive duration values.
 | 
					// It bahave similarly to DurationOpt but only allows positive duration values.
 | 
				
			||||||
type PositiveDurationOpt struct {
 | 
					type PositiveDurationOpt struct {
 | 
				
			||||||
| 
						 | 
					@ -149,9 +128,9 @@ type updateOptions struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type resourceOptions struct {
 | 
					type resourceOptions struct {
 | 
				
			||||||
	limitCPU      opts.NanoCPUs
 | 
						limitCPU      opts.NanoCPUs
 | 
				
			||||||
	limitMemBytes memBytes
 | 
						limitMemBytes opts.MemBytes
 | 
				
			||||||
	resCPU        opts.NanoCPUs
 | 
						resCPU        opts.NanoCPUs
 | 
				
			||||||
	resMemBytes   memBytes
 | 
						resMemBytes   opts.MemBytes
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *resourceOptions) ToResourceRequirements() *swarm.ResourceRequirements {
 | 
					func (r *resourceOptions) ToResourceRequirements() *swarm.ResourceRequirements {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,12 +11,12 @@ import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMemBytesString(t *testing.T) {
 | 
					func TestMemBytesString(t *testing.T) {
 | 
				
			||||||
	var mem memBytes = 1048576
 | 
						var mem opts.MemBytes = 1048576
 | 
				
			||||||
	assert.Equal(t, mem.String(), "1 MiB")
 | 
						assert.Equal(t, mem.String(), "1 MiB")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMemBytesSetAndValue(t *testing.T) {
 | 
					func TestMemBytesSetAndValue(t *testing.T) {
 | 
				
			||||||
	var mem memBytes
 | 
						var mem opts.MemBytes
 | 
				
			||||||
	assert.NilError(t, mem.Set("5kb"))
 | 
						assert.NilError(t, mem.Set("5kb"))
 | 
				
			||||||
	assert.Equal(t, mem.Value(), int64(5120))
 | 
						assert.Equal(t, mem.Value(), int64(5120))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,9 +22,7 @@ import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	// DefaultSHMSize is the default size (64MB) of the SHM which will be mounted in the container
 | 
						containerSecretMountPath = "/run/secrets"
 | 
				
			||||||
	DefaultSHMSize           int64 = 67108864
 | 
					 | 
				
			||||||
	containerSecretMountPath       = "/run/secrets"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Container holds the fields specific to unixen implementations.
 | 
					// Container holds the fields specific to unixen implementations.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ var (
 | 
				
			||||||
	defaultPidFile  = "/var/run/docker.pid"
 | 
						defaultPidFile  = "/var/run/docker.pid"
 | 
				
			||||||
	defaultGraph    = "/var/lib/docker"
 | 
						defaultGraph    = "/var/lib/docker"
 | 
				
			||||||
	defaultExecRoot = "/var/run/docker"
 | 
						defaultExecRoot = "/var/run/docker"
 | 
				
			||||||
 | 
						defaultShmSize  = int64(67108864)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Config defines the configuration of a docker daemon.
 | 
					// Config defines the configuration of a docker daemon.
 | 
				
			||||||
| 
						 | 
					@ -36,6 +37,7 @@ type Config struct {
 | 
				
			||||||
	Init                 bool                     `json:"init,omitempty"`
 | 
						Init                 bool                     `json:"init,omitempty"`
 | 
				
			||||||
	InitPath             string                   `json:"init-path,omitempty"`
 | 
						InitPath             string                   `json:"init-path,omitempty"`
 | 
				
			||||||
	SeccompProfile       string                   `json:"seccomp-profile,omitempty"`
 | 
						SeccompProfile       string                   `json:"seccomp-profile,omitempty"`
 | 
				
			||||||
 | 
						ShmSize              opts.MemBytes            `json:"default-shm-size,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// bridgeConfig stores all the bridge driver specific
 | 
					// bridgeConfig stores all the bridge driver specific
 | 
				
			||||||
| 
						 | 
					@ -66,6 +68,9 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	config.Ulimits = make(map[string]*units.Ulimit)
 | 
						config.Ulimits = make(map[string]*units.Ulimit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set default value for `--default-shm-size`
 | 
				
			||||||
 | 
						config.ShmSize = opts.MemBytes(defaultShmSize)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Then platform-specific install flags
 | 
						// Then platform-specific install flags
 | 
				
			||||||
	flags.BoolVar(&config.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support")
 | 
						flags.BoolVar(&config.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support")
 | 
				
			||||||
	flags.Var(opts.NewUlimitOpt(&config.Ulimits), "default-ulimit", "Default ulimits for containers")
 | 
						flags.Var(opts.NewUlimitOpt(&config.Ulimits), "default-ulimit", "Default ulimits for containers")
 | 
				
			||||||
| 
						 | 
					@ -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.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.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.StringVar(&config.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile")
 | 
				
			||||||
 | 
						flags.Var(&config.ShmSize, "default-shm-size", "Default shm size for containers")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	config.attachExperimentalFlags(flags)
 | 
						config.attachExperimentalFlags(flags)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,12 @@ package daemon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/docker/docker/pkg/testutil/assert"
 | 
				
			||||||
 | 
						"github.com/spf13/pflag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestDaemonConfigurationMerge(t *testing.T) {
 | 
					func TestDaemonConfigurationMerge(t *testing.T) {
 | 
				
			||||||
| 
						 | 
					@ -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())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			shmSize := container.DefaultSHMSize
 | 
								shmSize := int64(daemon.configStore.ShmSize)
 | 
				
			||||||
			if c.HostConfig.ShmSize != 0 {
 | 
								if c.HostConfig.ShmSize != 0 {
 | 
				
			||||||
				shmSize = c.HostConfig.ShmSize
 | 
									shmSize = c.HostConfig.ShmSize
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -256,7 +256,10 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
 | 
				
			||||||
		hostConfig.MemorySwap = hostConfig.Memory * 2
 | 
							hostConfig.MemorySwap = hostConfig.Memory * 2
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if hostConfig.ShmSize == 0 {
 | 
						if hostConfig.ShmSize == 0 {
 | 
				
			||||||
		hostConfig.ShmSize = container.DefaultSHMSize
 | 
							hostConfig.ShmSize = defaultShmSize
 | 
				
			||||||
 | 
							if daemon.configStore != nil {
 | 
				
			||||||
 | 
								hostConfig.ShmSize = int64(daemon.configStore.ShmSize)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	opts, err := daemon.generateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode, hostConfig.Privileged)
 | 
						opts, err := daemon.generateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode, hostConfig.Privileged)
 | 
				
			||||||
| 
						 | 
					@ -576,6 +579,10 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
 | 
				
			||||||
		daemon.configStore.DefaultRuntime = config.DefaultRuntime
 | 
							daemon.configStore.DefaultRuntime = config.DefaultRuntime
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if config.IsValueSet("default-shm-size") {
 | 
				
			||||||
 | 
							daemon.configStore.ShmSize = config.ShmSize
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update attributes
 | 
						// Update attributes
 | 
				
			||||||
	var runtimeList bytes.Buffer
 | 
						var runtimeList bytes.Buffer
 | 
				
			||||||
	for name, rt := range daemon.configStore.Runtimes {
 | 
						for name, rt := range daemon.configStore.Runtimes {
 | 
				
			||||||
| 
						 | 
					@ -586,8 +593,9 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return map[string]string{
 | 
						return map[string]string{
 | 
				
			||||||
		"runtimes":        runtimeList.String(),
 | 
							"runtimes":         runtimeList.String(),
 | 
				
			||||||
		"default-runtime": daemon.configStore.DefaultRuntime,
 | 
							"default-runtime":  daemon.configStore.DefaultRuntime,
 | 
				
			||||||
 | 
							"default-shm-size": fmt.Sprintf("%d", daemon.configStore.ShmSize),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@ Options:
 | 
				
			||||||
  -q, --quiet                   Suppress the build output and print image ID on success
 | 
					  -q, --quiet                   Suppress the build output and print image ID on success
 | 
				
			||||||
      --rm                      Remove intermediate containers after a successful build (default true)
 | 
					      --rm                      Remove intermediate containers after a successful build (default true)
 | 
				
			||||||
      --security-opt value      Security Options (default [])
 | 
					      --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`.
 | 
					                                The format is `<number><unit>`. `number` must be greater than `0`.
 | 
				
			||||||
                                Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
 | 
					                                Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
 | 
				
			||||||
                                or `g` (gigabytes). If you omit the unit, the system uses bytes.
 | 
					                                or `g` (gigabytes). If you omit the unit, the system uses bytes.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,7 +107,7 @@ Options:
 | 
				
			||||||
      --rm                          Automatically remove the container when it exits
 | 
					      --rm                          Automatically remove the container when it exits
 | 
				
			||||||
      --runtime string              Runtime to use for this container
 | 
					      --runtime string              Runtime to use for this container
 | 
				
			||||||
      --security-opt value          Security Options (default [])
 | 
					      --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`.
 | 
					                                    The format is `<number><unit>`. `number` must be greater than `0`.
 | 
				
			||||||
                                    Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
 | 
					                                    Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
 | 
				
			||||||
                                    or `g` (gigabytes). If you omit the unit, the system uses bytes.
 | 
					                                    or `g` (gigabytes). If you omit the unit, the system uses bytes.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@ Options:
 | 
				
			||||||
      --default-gateway value                 Container default gateway IPv4 address
 | 
					      --default-gateway value                 Container default gateway IPv4 address
 | 
				
			||||||
      --default-gateway-v6 value              Container default gateway IPv6 address
 | 
					      --default-gateway-v6 value              Container default gateway IPv6 address
 | 
				
			||||||
      --default-runtime string                Default OCI runtime for containers (default "runc")
 | 
					      --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 [])
 | 
					      --default-ulimit value                  Default ulimits for containers (default [])
 | 
				
			||||||
      --disable-legacy-registry               Disable contacting legacy registries
 | 
					      --disable-legacy-registry               Disable contacting legacy registries
 | 
				
			||||||
      --dns value                             DNS server to use (default [])
 | 
					      --dns value                             DNS server to use (default [])
 | 
				
			||||||
| 
						 | 
					@ -1161,6 +1162,7 @@ This is a full example of the allowed configuration options on Linux:
 | 
				
			||||||
	"cluster-advertise": "",
 | 
						"cluster-advertise": "",
 | 
				
			||||||
	"max-concurrent-downloads": 3,
 | 
						"max-concurrent-downloads": 3,
 | 
				
			||||||
	"max-concurrent-uploads": 5,
 | 
						"max-concurrent-uploads": 5,
 | 
				
			||||||
 | 
						"default-shm-size": "64M",
 | 
				
			||||||
	"shutdown-timeout": 15,
 | 
						"shutdown-timeout": 15,
 | 
				
			||||||
	"debug": true,
 | 
						"debug": true,
 | 
				
			||||||
	"hosts": [],
 | 
						"hosts": [],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ Options:
 | 
				
			||||||
      --rm                          Automatically remove the container when it exits
 | 
					      --rm                          Automatically remove the container when it exits
 | 
				
			||||||
      --runtime string              Runtime to use for this container
 | 
					      --runtime string              Runtime to use for this container
 | 
				
			||||||
      --security-opt value          Security Options (default [])
 | 
					      --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`.
 | 
					                                    The format is `<number><unit>`. `number` must be greater than `0`.
 | 
				
			||||||
                                    Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
 | 
					                                    Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes),
 | 
				
			||||||
                                    or `g` (gigabytes). If you omit the unit, the system uses bytes.
 | 
					                                    or `g` (gigabytes). If you omit the unit, the system uses bytes.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ Options:
 | 
				
			||||||
      --hostname string                  Container hostname
 | 
					      --hostname string                  Container hostname
 | 
				
			||||||
  -l, --label list                       Service labels (default [])
 | 
					  -l, --label list                       Service labels (default [])
 | 
				
			||||||
      --limit-cpu decimal                Limit CPUs (default 0.000)
 | 
					      --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-driver string                Logging driver for service
 | 
				
			||||||
      --log-opt list                     Logging driver options (default [])
 | 
					      --log-opt list                     Logging driver options (default [])
 | 
				
			||||||
      --mode string                      Service mode (replicated or global) (default "replicated")
 | 
					      --mode string                      Service mode (replicated or global) (default "replicated")
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,7 @@ Options:
 | 
				
			||||||
      --read-only                        Mount the container's root filesystem as read only
 | 
					      --read-only                        Mount the container's root filesystem as read only
 | 
				
			||||||
      --replicas uint                    Number of tasks
 | 
					      --replicas uint                    Number of tasks
 | 
				
			||||||
      --reserve-cpu decimal              Reserve CPUs (default 0.000)
 | 
					      --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-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-delay duration           Delay between restart attempts (ns|us|ms|s|m|h)
 | 
				
			||||||
      --restart-max-attempts uint        Maximum number of restarts before giving up
 | 
					      --restart-max-attempts uint        Maximum number of restarts before giving up
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,7 +50,7 @@ Options:
 | 
				
			||||||
      --label-add list                   Add or update a service label (default [])
 | 
					      --label-add list                   Add or update a service label (default [])
 | 
				
			||||||
      --label-rm list                    Remove a label by its key (default [])
 | 
					      --label-rm list                    Remove a label by its key (default [])
 | 
				
			||||||
      --limit-cpu decimal                Limit CPUs (default 0.000)
 | 
					      --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-driver string                Logging driver for service
 | 
				
			||||||
      --log-opt list                     Logging driver options (default [])
 | 
					      --log-opt list                     Logging driver options (default [])
 | 
				
			||||||
      --mount-add mount                  Add or update a mount on a service
 | 
					      --mount-add mount                  Add or update a mount on a service
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ Options:
 | 
				
			||||||
      --read-only                        Mount the container's root filesystem as read only
 | 
					      --read-only                        Mount the container's root filesystem as read only
 | 
				
			||||||
      --replicas uint                    Number of tasks
 | 
					      --replicas uint                    Number of tasks
 | 
				
			||||||
      --reserve-cpu decimal              Reserve CPUs (default 0.000)
 | 
					      --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-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-delay duration           Delay between restart attempts (ns|us|ms|s|m|h)
 | 
				
			||||||
      --restart-max-attempts uint        Maximum number of restarts before giving up
 | 
					      --restart-max-attempts uint        Maximum number of restarts before giving up
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2879,3 +2879,60 @@ func (s *DockerDaemonSuite) TestRestartPolicyWithLiveRestore(c *check.C) {
 | 
				
			||||||
	out, err = s.d.Cmd("stop", id)
 | 
						out, err = s.d.Cmd("stop", id)
 | 
				
			||||||
	c.Assert(err, check.IsNil, check.Commentf("output: %s", out))
 | 
						c.Assert(err, check.IsNil, check.Commentf("output: %s", out))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *DockerDaemonSuite) TestShmSize(c *check.C) {
 | 
				
			||||||
 | 
						testRequires(c, DaemonIsLinux)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size := 67108864 * 2
 | 
				
			||||||
 | 
						pattern := regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s.d.StartWithBusybox(c, "--default-shm-size", fmt.Sprintf("%v", size))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name := "shm1"
 | 
				
			||||||
 | 
						out, err := s.d.Cmd("run", "--name", name, "busybox", "mount")
 | 
				
			||||||
 | 
						c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 | 
				
			||||||
 | 
						c.Assert(pattern.MatchString(out), checker.True)
 | 
				
			||||||
 | 
						out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.ShmSize}}", name)
 | 
				
			||||||
 | 
						c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 | 
				
			||||||
 | 
						c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *DockerDaemonSuite) TestShmSizeReload(c *check.C) {
 | 
				
			||||||
 | 
						testRequires(c, DaemonIsLinux)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						configPath, err := ioutil.TempDir("", "test-daemon-shm-size-reload-config")
 | 
				
			||||||
 | 
						c.Assert(err, checker.IsNil, check.Commentf("could not create temp file for config reload"))
 | 
				
			||||||
 | 
						defer os.RemoveAll(configPath) // clean up
 | 
				
			||||||
 | 
						configFile := filepath.Join(configPath, "config.json")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size := 67108864 * 2
 | 
				
			||||||
 | 
						configData := []byte(fmt.Sprintf(`{"default-shm-size": "%dM"}`, size/1024/1024))
 | 
				
			||||||
 | 
						c.Assert(ioutil.WriteFile(configFile, configData, 0666), checker.IsNil, check.Commentf("could not write temp file for config reload"))
 | 
				
			||||||
 | 
						pattern := regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s.d.StartWithBusybox(c, "--config-file", configFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name := "shm1"
 | 
				
			||||||
 | 
						out, err := s.d.Cmd("run", "--name", name, "busybox", "mount")
 | 
				
			||||||
 | 
						c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 | 
				
			||||||
 | 
						c.Assert(pattern.MatchString(out), checker.True)
 | 
				
			||||||
 | 
						out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.ShmSize}}", name)
 | 
				
			||||||
 | 
						c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 | 
				
			||||||
 | 
						c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size = 67108864 * 3
 | 
				
			||||||
 | 
						configData = []byte(fmt.Sprintf(`{"default-shm-size": "%dM"}`, size/1024/1024))
 | 
				
			||||||
 | 
						c.Assert(ioutil.WriteFile(configFile, configData, 0666), checker.IsNil, check.Commentf("could not write temp file for config reload"))
 | 
				
			||||||
 | 
						pattern = regexp.MustCompile(fmt.Sprintf("shm on /dev/shm type tmpfs(.*)size=%dk", size/1024))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = s.d.ReloadConfig()
 | 
				
			||||||
 | 
						c.Assert(err, checker.IsNil, check.Commentf("error reloading daemon config"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name = "shm2"
 | 
				
			||||||
 | 
						out, err = s.d.Cmd("run", "--name", name, "busybox", "mount")
 | 
				
			||||||
 | 
						c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 | 
				
			||||||
 | 
						c.Assert(pattern.MatchString(out), checker.True)
 | 
				
			||||||
 | 
						out, err = s.d.Cmd("inspect", "--format", "{{.HostConfig.ShmSize}}", name)
 | 
				
			||||||
 | 
						c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 | 
				
			||||||
 | 
						c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -427,7 +427,7 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) {
 | 
				
			||||||
	out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c))
 | 
						out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c))
 | 
				
			||||||
	c.Assert(err, checker.IsNil)
 | 
						c.Assert(err, checker.IsNil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, default-runtime=runc, insecure-registries=[], labels=[\"bar=foo\"], live-restore=false, max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s, registry-mirrors=[], runtimes=runc:{docker-runc []}, shutdown-timeout=10)", daemonID, daemonName))
 | 
						c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, default-runtime=runc, default-shm-size=67108864, insecure-registries=[], labels=[\"bar=foo\"], live-restore=false, max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s, registry-mirrors=[], runtimes=runc:{docker-runc []}, shutdown-timeout=10)", daemonID, daemonName))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) {
 | 
					func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@ dockerd - Enable daemon mode
 | 
				
			||||||
[**--default-gateway**[=*DEFAULT-GATEWAY*]]
 | 
					[**--default-gateway**[=*DEFAULT-GATEWAY*]]
 | 
				
			||||||
[**--default-gateway-v6**[=*DEFAULT-GATEWAY-V6*]]
 | 
					[**--default-gateway-v6**[=*DEFAULT-GATEWAY-V6*]]
 | 
				
			||||||
[**--default-runtime**[=*runc*]]
 | 
					[**--default-runtime**[=*runc*]]
 | 
				
			||||||
 | 
					[**--default-shm-size**[=*64MiB*]]
 | 
				
			||||||
[**--default-ulimit**[=*[]*]]
 | 
					[**--default-ulimit**[=*[]*]]
 | 
				
			||||||
[**--disable-legacy-registry**]
 | 
					[**--disable-legacy-registry**]
 | 
				
			||||||
[**--dns**[=*[]*]]
 | 
					[**--dns**[=*[]*]]
 | 
				
			||||||
| 
						 | 
					@ -164,6 +165,9 @@ $ sudo dockerd --add-runtime runc=runc --add-runtime custom=/usr/local/bin/my-ru
 | 
				
			||||||
**--default-runtime**="runc"
 | 
					**--default-runtime**="runc"
 | 
				
			||||||
  Set default runtime if there're more than one specified by `--add-runtime`.
 | 
					  Set default runtime if there're more than one specified by `--add-runtime`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**--default-shm-size**=*64MiB*
 | 
				
			||||||
 | 
					  Set the daemon-wide default shm size for containers. Default is `64MiB`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**--default-ulimit**=[]
 | 
					**--default-ulimit**=[]
 | 
				
			||||||
  Default ulimits for containers.
 | 
					  Default ulimits for containers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										42
									
								
								opts/opts.go
									
										
									
									
									
								
							
							
						
						
									
										42
									
								
								opts/opts.go
									
										
									
									
									
								
							| 
						 | 
					@ -9,6 +9,7 @@ import (
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/docker/api/types/filters"
 | 
						"github.com/docker/docker/api/types/filters"
 | 
				
			||||||
 | 
						units "github.com/docker/go-units"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
| 
						 | 
					@ -402,3 +403,44 @@ func ValidateLink(val string) (string, error) {
 | 
				
			||||||
	_, _, err := ParseLink(val)
 | 
						_, _, err := ParseLink(val)
 | 
				
			||||||
	return val, err
 | 
						return val, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MemBytes is a type for human readable memory bytes (like 128M, 2g, etc)
 | 
				
			||||||
 | 
					type MemBytes int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns the string format of the human readable memory bytes
 | 
				
			||||||
 | 
					func (m *MemBytes) String() string {
 | 
				
			||||||
 | 
						// NOTE: In spf13/pflag/flag.go, "0" is considered as "zero value" while "0 B" is not.
 | 
				
			||||||
 | 
						// We return "0" in case value is 0 here so that the default value is hidden.
 | 
				
			||||||
 | 
						// (Sometimes "default 0 B" is actually misleading)
 | 
				
			||||||
 | 
						if m.Value() != 0 {
 | 
				
			||||||
 | 
							return units.BytesSize(float64(m.Value()))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "0"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set sets the value of the MemBytes by passing a string
 | 
				
			||||||
 | 
					func (m *MemBytes) Set(value string) error {
 | 
				
			||||||
 | 
						val, err := units.RAMInBytes(value)
 | 
				
			||||||
 | 
						*m = MemBytes(val)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Type returns the type
 | 
				
			||||||
 | 
					func (m *MemBytes) Type() string {
 | 
				
			||||||
 | 
						return "bytes"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Value returns the value in int64
 | 
				
			||||||
 | 
					func (m *MemBytes) Value() int64 {
 | 
				
			||||||
 | 
						return int64(*m)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnmarshalJSON is the customized unmarshaler for MemBytes
 | 
				
			||||||
 | 
					func (m *MemBytes) UnmarshalJSON(s []byte) error {
 | 
				
			||||||
 | 
						if len(s) <= 2 || s[0] != '"' || s[len(s)-1] != '"' {
 | 
				
			||||||
 | 
							return fmt.Errorf("invalid size: %q", s)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						val, err := units.RAMInBytes(string(s[1 : len(s)-1]))
 | 
				
			||||||
 | 
						*m = MemBytes(val)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue