mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	daemon: load and cache sysInfo on initialization
The `daemon.RawSysInfo()` function can be a heavy operation, as it collects information about all cgroups on the host, networking, AppArmor, Seccomp, etc. While looking at our code, I noticed that various parts in the code call this function, potentially even _multiple times_ per container, for example, it is called from: - `verifyPlatformContainerSettings()` - `oci.WithCgroups()` if the daemon has `cpu-rt-period` or `cpu-rt-runtime` configured - in `ContainerDecoder.DecodeConfig()`, which is called on boith `container create` and `container commit` Given that this information is not expected to change during the daemon's lifecycle, and various information coming from this (such as seccomp and apparmor status) was already cached, we may as well load it once, and cache the results in the daemon instance. This patch updates `daemon.RawSysInfo()` to use a `sync.Once()` so that it's only executed once for the daemon's lifecycle. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
		
							parent
							
								
									f045d0de94
								
							
						
					
					
						commit
						483aa6294b
					
				
					 7 changed files with 42 additions and 34 deletions
				
			
		| 
						 | 
				
			
			@ -11,7 +11,7 @@ import (
 | 
			
		|||
func (daemon *Daemon) saveAppArmorConfig(container *container.Container) error {
 | 
			
		||||
	container.AppArmorProfile = "" // we don't care about the previous value.
 | 
			
		||||
 | 
			
		||||
	if !daemon.apparmorEnabled {
 | 
			
		||||
	if !daemon.RawSysInfo().AppArmor {
 | 
			
		||||
		return nil // if apparmor is disabled there is nothing to do here.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,13 +19,10 @@ func (daemon *Daemon) saveAppArmorConfig(container *container.Container) error {
 | 
			
		|||
		return errdefs.InvalidParameter(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !container.HostConfig.Privileged {
 | 
			
		||||
		if container.AppArmorProfile == "" {
 | 
			
		||||
			container.AppArmorProfile = defaultAppArmorProfile
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
	if container.HostConfig.Privileged {
 | 
			
		||||
		container.AppArmorProfile = unconfinedAppArmorProfile
 | 
			
		||||
	} else if container.AppArmorProfile == "" {
 | 
			
		||||
		container.AppArmorProfile = defaultAppArmorProfile
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,6 +47,7 @@ import (
 | 
			
		|||
	"github.com/docker/docker/pkg/fileutils"
 | 
			
		||||
	"github.com/docker/docker/pkg/idtools"
 | 
			
		||||
	"github.com/docker/docker/pkg/plugingetter"
 | 
			
		||||
	"github.com/docker/docker/pkg/sysinfo"
 | 
			
		||||
	"github.com/docker/docker/pkg/system"
 | 
			
		||||
	"github.com/docker/docker/pkg/truncindex"
 | 
			
		||||
	"github.com/docker/docker/plugin"
 | 
			
		||||
| 
						 | 
				
			
			@ -92,8 +93,8 @@ type Daemon struct {
 | 
			
		|||
	netController         libnetwork.NetworkController
 | 
			
		||||
	volumes               *volumesservice.VolumesService
 | 
			
		||||
	root                  string
 | 
			
		||||
	seccompEnabled        bool
 | 
			
		||||
	apparmorEnabled       bool
 | 
			
		||||
	sysInfoOnce           sync.Once
 | 
			
		||||
	sysInfo               *sysinfo.SysInfo
 | 
			
		||||
	shutdown              bool
 | 
			
		||||
	idMapping             *idtools.IdentityMapping
 | 
			
		||||
	graphDriver           string        // TODO: move graphDriver field to an InfoService
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,8 +1035,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
 | 
			
		|||
	d.EventsService = events.New()
 | 
			
		||||
	d.root = config.Root
 | 
			
		||||
	d.idMapping = idMapping
 | 
			
		||||
	d.seccompEnabled = sysInfo.Seccomp
 | 
			
		||||
	d.apparmorEnabled = sysInfo.AppArmor
 | 
			
		||||
 | 
			
		||||
	d.linkIndex = newLinkIndex()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1472,3 +1471,16 @@ func (daemon *Daemon) BuilderBackend() builder.Backend {
 | 
			
		|||
		*images.ImageService
 | 
			
		||||
	}{daemon, daemon.imageService}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RawSysInfo returns *sysinfo.SysInfo .
 | 
			
		||||
func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
 | 
			
		||||
	daemon.sysInfoOnce.Do(func() {
 | 
			
		||||
		// We check if sysInfo is not set here, to allow some test to
 | 
			
		||||
		// override the actual sysInfo.
 | 
			
		||||
		if daemon.sysInfo == nil {
 | 
			
		||||
			daemon.loadSysInfo()
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return daemon.sysInfo
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1731,19 +1731,14 @@ func (daemon *Daemon) setupSeccompProfile() error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RawSysInfo returns *sysinfo.SysInfo .
 | 
			
		||||
func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
 | 
			
		||||
func (daemon *Daemon) loadSysInfo() {
 | 
			
		||||
	var siOpts []sysinfo.Opt
 | 
			
		||||
	if daemon.getCgroupDriver() == cgroupSystemdDriver {
 | 
			
		||||
		if euid := os.Getenv("ROOTLESSKIT_PARENT_EUID"); euid != "" {
 | 
			
		||||
			siOpts = append(siOpts, sysinfo.WithCgroup2GroupPath("/user.slice/user-"+euid+".slice"))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return sysinfo.New(siOpts...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func recursiveUnmount(target string) error {
 | 
			
		||||
	return mount.RecursiveUnmount(target)
 | 
			
		||||
	daemon.sysInfo = sysinfo.New(siOpts...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (daemon *Daemon) initLibcontainerd(ctx context.Context) error {
 | 
			
		||||
| 
						 | 
				
			
			@ -1757,3 +1752,7 @@ func (daemon *Daemon) initLibcontainerd(ctx context.Context) error {
 | 
			
		|||
	)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func recursiveUnmount(target string) error {
 | 
			
		||||
	return mount.RecursiveUnmount(target)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,6 @@ const platformSupported = false
 | 
			
		|||
func setupResolvConf(config *config.Config) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RawSysInfo returns *sysinfo.SysInfo .
 | 
			
		||||
func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
 | 
			
		||||
	return sysinfo.New()
 | 
			
		||||
func (daemon *Daemon) loadSysInfo() {
 | 
			
		||||
	daemon.sysInfo = sysinfo.New()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -650,9 +650,8 @@ func (daemon *Daemon) initRuntimes(_ map[string]types.Runtime) error {
 | 
			
		|||
func setupResolvConf(config *config.Config) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RawSysInfo returns *sysinfo.SysInfo .
 | 
			
		||||
func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
 | 
			
		||||
	return sysinfo.New()
 | 
			
		||||
func (daemon *Daemon) loadSysInfo() {
 | 
			
		||||
	daemon.sysInfo = sysinfo.New()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (daemon *Daemon) initLibcontainerd(ctx context.Context) error {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ func WithSeccomp(daemon *Daemon, c *container.Container) coci.SpecOpts {
 | 
			
		|||
		if c.HostConfig.Privileged {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		if !daemon.seccompEnabled {
 | 
			
		||||
		if !daemon.RawSysInfo().Seccomp {
 | 
			
		||||
			if c.SeccompProfile != "" && c.SeccompProfile != dconfig.SeccompProfileDefault {
 | 
			
		||||
				return fmt.Errorf("seccomp is not enabled in your kernel, cannot run a custom seccomp profile")
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ import (
 | 
			
		|||
	"github.com/docker/docker/container"
 | 
			
		||||
	dconfig "github.com/docker/docker/daemon/config"
 | 
			
		||||
	doci "github.com/docker/docker/oci"
 | 
			
		||||
	"github.com/docker/docker/pkg/sysinfo"
 | 
			
		||||
	"github.com/docker/docker/profiles/seccomp"
 | 
			
		||||
	specs "github.com/opencontainers/runtime-spec/specs-go"
 | 
			
		||||
	"gotest.tools/v3/assert"
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +32,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "unconfined seccompProfile runs unconfined",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo: &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
				SeccompProfile: dconfig.SeccompProfileUnconfined,
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +46,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "privileged container w/ custom profile runs unconfined",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo: &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
				SeccompProfile: "{ \"defaultAction\": \"SCMP_ACT_LOG\" }",
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +60,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "privileged container w/ default runs unconfined",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo: &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
				SeccompProfile: "",
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +74,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "privileged container w/ daemon profile runs unconfined",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo:        &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
				seccompProfile: []byte("{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }"),
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +89,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "custom profile when seccomp is disabled returns error",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: false,
 | 
			
		||||
				sysInfo: &sysinfo.SysInfo{Seccomp: false},
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
				SeccompProfile: "{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }",
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +104,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "empty profile name loads default profile",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo: &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
				SeccompProfile: "",
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +123,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "load container's profile",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo: &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
				SeccompProfile: "{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }",
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +144,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "load daemon's profile",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo:        &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
				seccompProfile: []byte("{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }"),
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
| 
						 | 
				
			
			@ -165,7 +166,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
		{
 | 
			
		||||
			comment: "load prioritise container profile over daemon's",
 | 
			
		||||
			daemon: &Daemon{
 | 
			
		||||
				seccompEnabled: true,
 | 
			
		||||
				sysInfo:        &sysinfo.SysInfo{Seccomp: true},
 | 
			
		||||
				seccompProfile: []byte("{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }"),
 | 
			
		||||
			},
 | 
			
		||||
			c: &container.Container{
 | 
			
		||||
| 
						 | 
				
			
			@ -185,6 +186,7 @@ func TestWithSeccomp(t *testing.T) {
 | 
			
		|||
			}(),
 | 
			
		||||
		},
 | 
			
		||||
	} {
 | 
			
		||||
		x := x
 | 
			
		||||
		t.Run(x.comment, func(t *testing.T) {
 | 
			
		||||
			opts := WithSeccomp(x.daemon, x.c)
 | 
			
		||||
			err := opts(nil, nil, nil, &x.inSpec)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue