From 5263bea70f2a8285242da5758f14ebafb176bfc9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 6 Jan 2022 22:20:15 +0100 Subject: [PATCH] daemon: move check for CPU-realtime daemon options Perform the validation when the daemon starts instead of performing these validations for each individual container, so that we can fail early. Signed-off-by: Sebastiaan van Stijn --- cmd/dockerd/config_unix.go | 4 ++-- cmd/dockerd/daemon.go | 5 +++++ cmd/dockerd/daemon_freebsd.go | 6 ++++++ cmd/dockerd/daemon_linux.go | 21 ++++++++++++++++++++- cmd/dockerd/daemon_windows.go | 4 ++++ daemon/oci_linux.go | 10 ---------- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/cmd/dockerd/config_unix.go b/cmd/dockerd/config_unix.go index 354d5da196..1fcc6f5aa7 100644 --- a/cmd/dockerd/config_unix.go +++ b/cmd/dockerd/config_unix.go @@ -57,8 +57,8 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) error { flags.IntVar(&conf.OOMScoreAdjust, "oom-score-adjust", 0, "Set the oom_score_adj for the daemon") flags.BoolVar(&conf.Init, "init", false, "Run an init in the container to forward signals and reap processes") flags.StringVar(&conf.InitPath, "init-path", "", "Path to the docker-init binary") - flags.Int64Var(&conf.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds for the parent cgroup for all containers") - flags.Int64Var(&conf.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds for the parent cgroup for all containers") + flags.Int64Var(&conf.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds for the parent cgroup for all containers (not supported with cgroups v2)") + flags.Int64Var(&conf.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds for the parent cgroup for all containers (not supported with cgroups v2)") flags.StringVar(&conf.SeccompProfile, "seccomp-profile", config.SeccompProfileDefault, `Path to seccomp profile. Use "unconfined" to disable the default seccomp profile`) flags.Var(&conf.ShmSize, "default-shm-size", "Default shm size for containers") flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers") diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index 54a85b651f..dee52700f6 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -463,6 +463,11 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) { conf.TLSVerify = conf.TLS } + err = validateCPURealtimeOptions(conf) + if err != nil { + return nil, err + } + return conf, nil } diff --git a/cmd/dockerd/daemon_freebsd.go b/cmd/dockerd/daemon_freebsd.go index 1bb49047c7..ca230a22fe 100644 --- a/cmd/dockerd/daemon_freebsd.go +++ b/cmd/dockerd/daemon_freebsd.go @@ -1,5 +1,7 @@ package main +import "github.com/docker/docker/daemon/config" + // preNotifyReady sends a message to the host when the API is active, but before the daemon is func preNotifyReady() { } @@ -11,3 +13,7 @@ func notifyReady() { // notifyStopping sends a message to the host when the server is shutting down func notifyStopping() { } + +func validateCPURealtimeOptions(_ *config.Config) error { + return nil +} diff --git a/cmd/dockerd/daemon_linux.go b/cmd/dockerd/daemon_linux.go index aade57a8d3..faa0e7c99a 100644 --- a/cmd/dockerd/daemon_linux.go +++ b/cmd/dockerd/daemon_linux.go @@ -1,6 +1,12 @@ package main -import systemdDaemon "github.com/coreos/go-systemd/v22/daemon" +import ( + cdcgroups "github.com/containerd/cgroups" + systemdDaemon "github.com/coreos/go-systemd/v22/daemon" + "github.com/docker/docker/daemon/config" + "github.com/docker/docker/pkg/sysinfo" + "github.com/pkg/errors" +) // preNotifyReady sends a message to the host when the API is active, but before the daemon is func preNotifyReady() { @@ -16,3 +22,16 @@ func notifyReady() { func notifyStopping() { go systemdDaemon.SdNotify(false, systemdDaemon.SdNotifyStopping) } + +func validateCPURealtimeOptions(config *config.Config) error { + if config.CPURealtimePeriod == 0 && config.CPURealtimeRuntime == 0 { + return nil + } + if cdcgroups.Mode() == cdcgroups.Unified { + return errors.New("daemon-scoped cpu-rt-period and cpu-rt-runtime are not implemented for cgroup v2") + } + if !sysinfo.New().CPURealtime { + return errors.New("daemon-scoped cpu-rt-period and cpu-rt-runtime are not supported by the kernel") + } + return nil +} diff --git a/cmd/dockerd/daemon_windows.go b/cmd/dockerd/daemon_windows.go index ef06b0eb6d..08a77b7cb8 100644 --- a/cmd/dockerd/daemon_windows.go +++ b/cmd/dockerd/daemon_windows.go @@ -97,3 +97,7 @@ func (cli *DaemonCli) initContainerD(_ context.Context) (func(time.Duration) err system.InitContainerdRuntime(cli.Config.ContainerdAddr) return nil, nil } + +func validateCPURealtimeOptions(_ *config.Config) error { + return nil +} diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 02c0cf1f69..139e1deaaf 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -818,16 +818,6 @@ func WithCgroups(daemon *Daemon, c *container.Container) coci.SpecOpts { return nil } - if cdcgroups.Mode() == cdcgroups.Unified { - return errors.New("daemon-scoped cpu-rt-period and cpu-rt-runtime are not implemented for cgroup v2") - } - - // FIXME this is very expensive way to check if cpu rt is supported - sysInfo := daemon.RawSysInfo() - if !sysInfo.CPURealtime { - return errors.New("daemon-scoped cpu-rt-period and cpu-rt-runtime are not supported by the kernel") - } - p := cgroupsPath if useSystemd { initPath, err := cgroups.GetInitCgroup("cpu")