diff --git a/libcontainer/cgroups/systemd/apply_systemd.go b/libcontainer/cgroups/systemd/apply_systemd.go index 6e4748d68a5..0a908c15e7d 100644 --- a/libcontainer/cgroups/systemd/apply_systemd.go +++ b/libcontainer/cgroups/systemd/apply_systemd.go @@ -71,8 +71,9 @@ const ( ) var ( - connLock sync.Mutex - theConn *systemdDbus.Conn + connOnce sync.Once + connDbus *systemdDbus.Conn + connErr error ) func newProp(name string, units interface{}) systemdDbus.Property { @@ -97,22 +98,13 @@ func IsRunningSystemd() bool { return fi.IsDir() } -func UseSystemd() bool { - if !IsRunningSystemd() { - return false - } - - connLock.Lock() - defer connLock.Unlock() - - if theConn == nil { - var err error - theConn, err = systemdDbus.New() - if err != nil { - return false - } - } - return true +// getDbusConnection lazy initializes systemd dbus connection +// and returns it +func getDbusConnection() (*systemdDbus.Conn, error) { + connOnce.Do(func() { + connDbus, connErr = systemdDbus.New() + }) + return connDbus, connErr } func NewSystemdCgroupsManager() (func(config *configs.Cgroup, paths map[string]string) cgroups.Manager, error) { @@ -245,8 +237,13 @@ func (m *LegacyManager) Apply(pid int) error { } } + dbusConnection, err := getDbusConnection() + if err != nil { + return err + } + statusChan := make(chan string, 1) - if _, err := theConn.StartTransientUnit(unitName, "replace", properties, statusChan); err == nil { + if _, err := dbusConnection.StartTransientUnit(unitName, "replace", properties, statusChan); err == nil { select { case <-statusChan: case <-time.After(time.Second): @@ -280,9 +277,13 @@ func (m *LegacyManager) Destroy() error { if m.Cgroups.Paths != nil { return nil } + dbusConnection, err := getDbusConnection() + if err != nil { + return err + } m.mu.Lock() defer m.mu.Unlock() - theConn.StopUnit(getUnitName(m.Cgroups), "replace", nil) + dbusConnection.StopUnit(getUnitName(m.Cgroups), "replace", nil) if err := cgroups.RemovePaths(m.Paths); err != nil { return err } diff --git a/libcontainer/cgroups/systemd/unified_hierarchy.go b/libcontainer/cgroups/systemd/unified_hierarchy.go index 6605099190c..ebb6026cce5 100644 --- a/libcontainer/cgroups/systemd/unified_hierarchy.go +++ b/libcontainer/cgroups/systemd/unified_hierarchy.go @@ -136,8 +136,13 @@ func (m *UnifiedManager) Apply(pid int) error { } } + dbusConnection, err := getDbusConnection() + if err != nil { + return err + } + statusChan := make(chan string, 1) - if _, err := theConn.StartTransientUnit(unitName, "replace", properties, statusChan); err == nil { + if _, err := dbusConnection.StartTransientUnit(unitName, "replace", properties, statusChan); err == nil { select { case <-statusChan: case <-time.After(time.Second): @@ -171,9 +176,13 @@ func (m *UnifiedManager) Destroy() error { if m.Cgroups.Paths != nil { return nil } + dbusConnection, err := getDbusConnection() + if err != nil { + return err + } m.mu.Lock() defer m.mu.Unlock() - theConn.StopUnit(getUnitName(m.Cgroups), "replace", nil) + dbusConnection.StopUnit(getUnitName(m.Cgroups), "replace", nil) if err := cgroups.RemovePaths(m.Paths); err != nil { return err } diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 7822fa85bfe..14aed266f59 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -506,7 +506,7 @@ func TestFreeze(t *testing.T) { } func TestSystemdFreeze(t *testing.T) { - if !systemd.UseSystemd() { + if !systemd.IsRunningSystemd() { t.Skip("Systemd is unsupported") } testFreeze(t, true) @@ -563,7 +563,7 @@ func TestCpuShares(t *testing.T) { } func TestCpuSharesSystemd(t *testing.T) { - if !systemd.UseSystemd() { + if !systemd.IsRunningSystemd() { t.Skip("Systemd is unsupported") } testCpuShares(t, true) @@ -598,7 +598,7 @@ func TestPids(t *testing.T) { } func TestPidsSystemd(t *testing.T) { - if !systemd.UseSystemd() { + if !systemd.IsRunningSystemd() { t.Skip("Systemd is unsupported") } testPids(t, true) @@ -684,7 +684,7 @@ func TestRunWithKernelMemory(t *testing.T) { } func TestRunWithKernelMemorySystemd(t *testing.T) { - if !systemd.UseSystemd() { + if !systemd.IsRunningSystemd() { t.Skip("Systemd is unsupported") } testRunWithKernelMemory(t, true) diff --git a/utils_linux.go b/utils_linux.go index 984e6b0f1b6..77255067664 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -47,7 +47,7 @@ func loadFactory(context *cli.Context) (libcontainer.Factory, error) { cgroupManager = libcontainer.RootlessCgroupfs } if context.GlobalBool("systemd-cgroup") { - if systemd.UseSystemd() { + if systemd.IsRunningSystemd() { cgroupManager = libcontainer.SystemdCgroups } else { return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available")