1// +build !windows
2
3package main
4
5import (
6	"fmt"
7	"net"
8	"os"
9	"os/signal"
10	"path/filepath"
11	"strconv"
12
13	"github.com/containerd/containerd/runtime/v1/linux"
14	"github.com/docker/docker/cmd/dockerd/hack"
15	"github.com/docker/docker/daemon"
16	"github.com/docker/docker/daemon/config"
17	"github.com/docker/docker/libcontainerd/supervisor"
18	"github.com/docker/libnetwork/portallocator"
19	"golang.org/x/sys/unix"
20)
21
22const defaultDaemonConfigFile = "/etc/docker/daemon.json"
23
24// setDefaultUmask sets the umask to 0022 to avoid problems
25// caused by custom umask
26func setDefaultUmask() error {
27	desiredUmask := 0022
28	unix.Umask(desiredUmask)
29	if umask := unix.Umask(desiredUmask); umask != desiredUmask {
30		return fmt.Errorf("failed to set umask: expected %#o, got %#o", desiredUmask, umask)
31	}
32
33	return nil
34}
35
36func getDaemonConfDir(_ string) string {
37	return "/etc/docker"
38}
39
40func (cli *DaemonCli) getPlatformContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) {
41	opts := []supervisor.DaemonOpt{
42		supervisor.WithOOMScore(cli.Config.OOMScoreAdjust),
43		supervisor.WithPlugin("linux", &linux.Config{
44			Shim:        daemon.DefaultShimBinary,
45			Runtime:     daemon.DefaultRuntimeBinary,
46			RuntimeRoot: filepath.Join(cli.Config.Root, "runc"),
47			ShimDebug:   cli.Config.Debug,
48		}),
49	}
50
51	return opts, nil
52}
53
54// setupConfigReloadTrap configures the USR2 signal to reload the configuration.
55func (cli *DaemonCli) setupConfigReloadTrap() {
56	c := make(chan os.Signal, 1)
57	signal.Notify(c, unix.SIGHUP)
58	go func() {
59		for range c {
60			cli.reloadConfig()
61		}
62	}()
63}
64
65// getSwarmRunRoot gets the root directory for swarm to store runtime state
66// For example, the control socket
67func (cli *DaemonCli) getSwarmRunRoot() string {
68	return filepath.Join(cli.Config.ExecRoot, "swarm")
69}
70
71// allocateDaemonPort ensures that there are no containers
72// that try to use any port allocated for the docker server.
73func allocateDaemonPort(addr string) error {
74	host, port, err := net.SplitHostPort(addr)
75	if err != nil {
76		return err
77	}
78
79	intPort, err := strconv.Atoi(port)
80	if err != nil {
81		return err
82	}
83
84	var hostIPs []net.IP
85	if parsedIP := net.ParseIP(host); parsedIP != nil {
86		hostIPs = append(hostIPs, parsedIP)
87	} else if hostIPs, err = net.LookupIP(host); err != nil {
88		return fmt.Errorf("failed to lookup %s address in host specification", host)
89	}
90
91	pa := portallocator.Get()
92	for _, hostIP := range hostIPs {
93		if _, err := pa.RequestPort(hostIP, "tcp", intPort); err != nil {
94			return fmt.Errorf("failed to allocate daemon listening port %d (err: %v)", intPort, err)
95		}
96	}
97	return nil
98}
99
100func wrapListeners(proto string, ls []net.Listener) []net.Listener {
101	switch proto {
102	case "unix":
103		ls[0] = &hack.MalformedHostHeaderOverride{Listener: ls[0]}
104	case "fd":
105		for i := range ls {
106			ls[i] = &hack.MalformedHostHeaderOverride{Listener: ls[i]}
107		}
108	}
109	return ls
110}
111
112func newCgroupParent(config *config.Config) string {
113	cgroupParent := "docker"
114	useSystemd := daemon.UsingSystemd(config)
115	if useSystemd {
116		cgroupParent = "system.slice"
117	}
118	if config.CgroupParent != "" {
119		cgroupParent = config.CgroupParent
120	}
121	if useSystemd {
122		cgroupParent = cgroupParent + ":" + "docker" + ":"
123	}
124	return cgroupParent
125}
126