From cdbed6f02f814773dfbf7c94265d7fa417ed824e Mon Sep 17 00:00:00 2001 From: Shiming Zhang Date: Mon, 26 Apr 2021 11:05:28 +0800 Subject: [PATCH] libct/cg/sd: add dbus manager [@kolyshkin: documentation nits] Signed-off-by: Shiming Zhang Signed-off-by: Kir Kolyshkin --- libcontainer/cgroups/systemd/common.go | 18 -------- libcontainer/cgroups/systemd/dbus.go | 59 ++++++++++++++++++++++++++ libcontainer/cgroups/systemd/v1.go | 8 ++-- libcontainer/cgroups/systemd/v2.go | 10 +++-- 4 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 libcontainer/cgroups/systemd/dbus.go diff --git a/libcontainer/cgroups/systemd/common.go b/libcontainer/cgroups/systemd/common.go index ab95b6ab4..7b04e5ca7 100644 --- a/libcontainer/cgroups/systemd/common.go +++ b/libcontainer/cgroups/systemd/common.go @@ -2,7 +2,6 @@ package systemd import ( "bufio" - "context" "fmt" "math" "os" @@ -29,10 +28,6 @@ const ( ) var ( - connOnce sync.Once - connDbus *systemdDbus.Conn - connErr error - versionOnce sync.Once version int @@ -292,19 +287,6 @@ func generateDeviceProperties(rules []*devices.Rule) ([]systemdDbus.Property, er return properties, nil } -// getDbusConnection lazy initializes systemd dbus connection -// and returns it -func getDbusConnection(rootless bool) (*systemdDbus.Conn, error) { - connOnce.Do(func() { - if rootless { - connDbus, connErr = NewUserSystemdDbus() - } else { - connDbus, connErr = systemdDbus.NewWithContext(context.TODO()) - } - }) - return connDbus, connErr -} - func newProp(name string, units interface{}) systemdDbus.Property { return systemdDbus.Property{ Name: name, diff --git a/libcontainer/cgroups/systemd/dbus.go b/libcontainer/cgroups/systemd/dbus.go new file mode 100644 index 000000000..a90a6638c --- /dev/null +++ b/libcontainer/cgroups/systemd/dbus.go @@ -0,0 +1,59 @@ +// +build linux + +package systemd + +import ( + "context" + "sync" + + systemdDbus "github.com/coreos/go-systemd/v22/dbus" +) + +type dbusConnManager struct { + conn *systemdDbus.Conn + rootless bool + sync.RWMutex +} + +// newDbusConnManager initializes systemd dbus connection manager. +func newDbusConnManager(rootless bool) *dbusConnManager { + return &dbusConnManager{ + rootless: rootless, + } +} + +// getConnection lazily initializes and returns systemd dbus connection. +func (d *dbusConnManager) getConnection() (*systemdDbus.Conn, error) { + // In the case where d.conn != nil + // Use the read lock the first time to ensure + // that Conn can be acquired at the same time. + d.RLock() + if conn := d.conn; conn != nil { + d.RUnlock() + return conn, nil + } + d.RUnlock() + + // In the case where d.conn == nil + // Use write lock to ensure that only one + // will be created + d.Lock() + defer d.Unlock() + if conn := d.conn; conn != nil { + return conn, nil + } + + conn, err := d.newConnection() + if err != nil { + return nil, err + } + d.conn = conn + return conn, nil +} + +func (d *dbusConnManager) newConnection() (*systemdDbus.Conn, error) { + if d.rootless { + return NewUserSystemdDbus() + } + return systemdDbus.NewWithContext(context.TODO()) +} diff --git a/libcontainer/cgroups/systemd/v1.go b/libcontainer/cgroups/systemd/v1.go index 127067cd2..61742b5c8 100644 --- a/libcontainer/cgroups/systemd/v1.go +++ b/libcontainer/cgroups/systemd/v1.go @@ -20,12 +20,14 @@ type legacyManager struct { mu sync.Mutex cgroups *configs.Cgroup paths map[string]string + dbus *dbusConnManager } func NewLegacyManager(cg *configs.Cgroup, paths map[string]string) cgroups.Manager { return &legacyManager{ cgroups: cg, paths: paths, + dbus: newDbusConnManager(false), } } @@ -164,7 +166,7 @@ func (m *legacyManager) Apply(pid int) error { properties = append(properties, newProp("DefaultDependencies", false)) - dbusConnection, err := getDbusConnection(false) + dbusConnection, err := m.dbus.getConnection() if err != nil { return err } @@ -208,7 +210,7 @@ func (m *legacyManager) Destroy() error { m.mu.Lock() defer m.mu.Unlock() - dbusConnection, err := getDbusConnection(false) + dbusConnection, err := m.dbus.getConnection() if err != nil { return err } @@ -341,7 +343,7 @@ func (m *legacyManager) Set(container *configs.Config) error { if container.Cgroups.Resources.Unified != nil { return cgroups.ErrV1NoUnified } - dbusConnection, err := getDbusConnection(false) + dbusConnection, err := m.dbus.getConnection() if err != nil { return err } diff --git a/libcontainer/cgroups/systemd/v2.go b/libcontainer/cgroups/systemd/v2.go index f37b77cf9..e0b9390e1 100644 --- a/libcontainer/cgroups/systemd/v2.go +++ b/libcontainer/cgroups/systemd/v2.go @@ -26,6 +26,7 @@ type unifiedManager struct { // path is like "/sys/fs/cgroup/user.slice/user-1001.slice/session-1.scope" path string rootless bool + dbus *dbusConnManager } func NewUnifiedManager(config *configs.Cgroup, path string, rootless bool) cgroups.Manager { @@ -33,6 +34,7 @@ func NewUnifiedManager(config *configs.Cgroup, path string, rootless bool) cgrou cgroups: config, path: path, rootless: rootless, + dbus: newDbusConnManager(rootless), } } @@ -279,7 +281,7 @@ func (m *unifiedManager) Apply(pid int) error { properties = append(properties, newProp("DefaultDependencies", false)) - dbusConnection, err := getDbusConnection(m.rootless) + dbusConnection, err := m.dbus.getConnection() if err != nil { return err } @@ -305,7 +307,7 @@ func (m *unifiedManager) Destroy() error { m.mu.Lock() defer m.mu.Unlock() - dbusConnection, err := getDbusConnection(m.rootless) + dbusConnection, err := m.dbus.getConnection() if err != nil { return err } @@ -344,7 +346,7 @@ func (m *unifiedManager) getSliceFull() (string, error) { } if m.rootless { - dbusConnection, err := getDbusConnection(m.rootless) + dbusConnection, err := m.dbus.getConnection() if err != nil { return "", err } @@ -427,7 +429,7 @@ func (m *unifiedManager) GetStats() (*cgroups.Stats, error) { } func (m *unifiedManager) Set(container *configs.Config) error { - dbusConnection, err := getDbusConnection(m.rootless) + dbusConnection, err := m.dbus.getConnection() if err != nil { return err }