From 0015ad0b3e6ef8bef3c2da434442554ec7e1a1d3 Mon Sep 17 00:00:00 2001 From: David Trudgian Date: Thu, 20 Feb 2025 09:40:04 +0000 Subject: [PATCH] fix: cgroups: check for systemd init when needed When `CanUseCgroups` is called, with systemd as the intended cgroups manager, make sure that a systemd init is actually running. This fixes flows where Singularity run nested inside another container, that doesn't provide a systemd init or mount the host `/run` directory into the container. Fixes #3536 --- CHANGELOG.md | 2 ++ internal/pkg/cgroups/manager_linux_test.go | 4 ++++ internal/pkg/cgroups/util.go | 14 ++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f55b84deff..9e1c0f8637 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ native SIF, so environment sourcing does not fail. - Fix the Makefile generated by `mconfig -b` to work when the selected build directory is not a subdirectory of the source code. +- Check for existence of `/run/systemd/system` when verifying cgroups can be + used via systemd manager. ### New Features & Functionality diff --git a/internal/pkg/cgroups/manager_linux_test.go b/internal/pkg/cgroups/manager_linux_test.go index 9a711b533a..f729df2011 100644 --- a/internal/pkg/cgroups/manager_linux_test.go +++ b/internal/pkg/cgroups/manager_linux_test.go @@ -19,6 +19,7 @@ import ( "github.com/sylabs/singularity/v4/internal/pkg/test" "github.com/sylabs/singularity/v4/internal/pkg/test/tool/require" + "github.com/sylabs/singularity/v4/internal/pkg/util/fs" ) // This file contains tests that will run under cgroups v1 & v2, and test utility functions. @@ -55,6 +56,9 @@ func runCgroupfsTests(t *testing.T, tests CgroupTests) { func runSystemdTests(t *testing.T, tests CgroupTests) { t.Run("systemd", func(t *testing.T) { + if !fs.IsDir("/run/systemd/system") { + t.Skip("systemd not running as init on this host") + } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.testFunc(t, true) diff --git a/internal/pkg/cgroups/util.go b/internal/pkg/cgroups/util.go index efb7985feb..b74c24ffc7 100644 --- a/internal/pkg/cgroups/util.go +++ b/internal/pkg/cgroups/util.go @@ -14,6 +14,7 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" lccgroups "github.com/opencontainers/runc/libcontainer/cgroups" + "github.com/sylabs/singularity/v4/internal/pkg/util/fs" "github.com/sylabs/singularity/v4/internal/pkg/util/rootless" "github.com/sylabs/singularity/v4/pkg/sylog" "golang.org/x/sys/unix" @@ -117,12 +118,25 @@ func HasXDGRuntimeDir() (bool, error) { } // CanUseCgroups checks whether it's possible to use the cgroups manager. +// - Systemd cgroups management requires systemd running as init. // - Host root can always use cgroups. // - Rootless needs cgroups v2. // - Rootless needs systemd manager. // - Rootless needs DBUS_SESSION_BUS_ADDRESS and XDG_RUNTIME_DIR set properly. // warn controls whether configuration problems preventing use of cgroups will be logged as warnings, or debug messages. func CanUseCgroups(systemd bool, warn bool) bool { + if systemd { + systemdRunning := fs.IsDir("/run/systemd/system") + if !systemdRunning { + if warn { + sylog.Warningf("Cannot use systemd cgroups manager, systemd not running as init on this host.") + } else { + sylog.Debugf("Cannot use systemd cgroups manager, systemd not running as init on this host.") + } + return false + } + } + uid, err := rootless.Getuid() if err != nil { sylog.Errorf("cannot determine uid: %v", err)