diff --git a/libcontainer/cgroups/systemd/dbus.go b/libcontainer/cgroups/systemd/dbus.go index deca16b005b..0f7406cd9d6 100644 --- a/libcontainer/cgroups/systemd/dbus.go +++ b/libcontainer/cgroups/systemd/dbus.go @@ -10,37 +10,43 @@ import ( dbus "github.com/godbus/dbus/v5" ) +var ( + dbusC *systemdDbus.Conn + dbusMu sync.RWMutex + dbusInited bool + dbusRootless bool +) + 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, + if dbusInited && rootless != dbusRootless { + panic("can't have both root and rootless dbus") } + dbusRootless = rootless + return &dbusConnManager{} } // getConnection lazily initializes and returns systemd dbus connection. func (d *dbusConnManager) getConnection() (*systemdDbus.Conn, error) { - // In the case where d.conn != nil + // In the case where dbusC != 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() + dbusMu.RLock() + if conn := dbusC; conn != nil { + dbusMu.RUnlock() return conn, nil } - d.RUnlock() + dbusMu.RUnlock() - // In the case where d.conn == nil + // In the case where dbusC == nil // Use write lock to ensure that only one // will be created - d.Lock() - defer d.Unlock() - if conn := d.conn; conn != nil { + dbusMu.Lock() + defer dbusMu.Unlock() + if conn := dbusC; conn != nil { return conn, nil } @@ -48,12 +54,12 @@ func (d *dbusConnManager) getConnection() (*systemdDbus.Conn, error) { if err != nil { return nil, err } - d.conn = conn + dbusC = conn return conn, nil } func (d *dbusConnManager) newConnection() (*systemdDbus.Conn, error) { - if d.rootless { + if dbusRootless { return newUserSystemdDbus() } return systemdDbus.NewWithContext(context.TODO()) @@ -62,11 +68,11 @@ func (d *dbusConnManager) newConnection() (*systemdDbus.Conn, error) { // resetConnection resets the connection to its initial state // (so it can be reconnected if necessary). func (d *dbusConnManager) resetConnection(conn *systemdDbus.Conn) { - d.Lock() - defer d.Unlock() - if d.conn != nil && d.conn == conn { - d.conn.Close() - d.conn = nil + dbusMu.Lock() + defer dbusMu.Unlock() + if dbusC != nil && dbusC == conn { + dbusC.Close() + dbusC = nil } }