diff --git a/libcontainer/cgroups/systemd/dbus.go b/libcontainer/cgroups/systemd/dbus.go index a90a6638c59..21ead22b9d7 100644 --- a/libcontainer/cgroups/systemd/dbus.go +++ b/libcontainer/cgroups/systemd/dbus.go @@ -7,6 +7,8 @@ import ( "sync" systemdDbus "github.com/coreos/go-systemd/v22/dbus" + dbus "github.com/godbus/dbus/v5" + "github.com/sirupsen/logrus" ) type dbusConnManager struct { @@ -57,3 +59,31 @@ func (d *dbusConnManager) newConnection() (*systemdDbus.Conn, error) { } return systemdDbus.NewWithContext(context.TODO()) } + +// 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 + } +} + +var errDbusConnClosed = dbus.ErrClosed.Error() + +// checkAndReconnect checks if the connection is disconnected, +// and tries reconnect if it is. +func (d *dbusConnManager) checkAndReconnect(conn *systemdDbus.Conn, err error) { + if !isDbusError(err, errDbusConnClosed) { + return + } + d.resetConnection(conn) + + // Try to reconnect + _, err = d.getConnection() + if err != nil { + logrus.Warnf("Dbus disconnected and failed to reconnect: %s", err) + } +} diff --git a/libcontainer/cgroups/systemd/v1.go b/libcontainer/cgroups/systemd/v1.go index 61742b5c8e2..b52b13e2faf 100644 --- a/libcontainer/cgroups/systemd/v1.go +++ b/libcontainer/cgroups/systemd/v1.go @@ -173,6 +173,7 @@ func (m *legacyManager) Apply(pid int) error { properties = append(properties, c.SystemdProps...) if err := startUnit(dbusConnection, unitName, properties); err != nil { + m.dbus.checkAndReconnect(dbusConnection, err) return err } @@ -376,6 +377,7 @@ func (m *legacyManager) Set(container *configs.Config) error { } if err := dbusConnection.SetUnitProperties(getUnitName(container.Cgroups), true, properties...); err != nil { + m.dbus.checkAndReconnect(dbusConnection, err) _ = m.Freeze(targetFreezerState) return err } diff --git a/libcontainer/cgroups/systemd/v2.go b/libcontainer/cgroups/systemd/v2.go index e0b9390e119..5c973d577b3 100644 --- a/libcontainer/cgroups/systemd/v2.go +++ b/libcontainer/cgroups/systemd/v2.go @@ -288,6 +288,7 @@ func (m *unifiedManager) Apply(pid int) error { properties = append(properties, c.SystemdProps...) if err := startUnit(dbusConnection, unitName, properties); err != nil { + m.dbus.checkAndReconnect(dbusConnection, err) return errors.Wrapf(err, "error while starting unit %q with properties %+v", unitName, properties) } @@ -462,6 +463,7 @@ func (m *unifiedManager) Set(container *configs.Config) error { } if err := dbusConnection.SetUnitProperties(getUnitName(m.cgroups), true, properties...); err != nil { + m.dbus.checkAndReconnect(dbusConnection, err) _ = m.Freeze(targetFreezerState) return errors.Wrap(err, "error while setting unit properties") }