From 1d18743f9e6767580a4276108e0c977d64fd03b6 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 23 Mar 2023 11:15:01 -0700 Subject: [PATCH] libct/cg/sd: reset-failed and retry startUnit on UnitExists In case a systemd unit fails (for example, timed out or OOM-killed), systemd keeps the unit. This prevents starting a new container with the same systemd unit name. The fix is to call reset-failed in case UnitExists error is returned, and retry once. Signed-off-by: Kir Kolyshkin --- libcontainer/cgroups/systemd/common.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libcontainer/cgroups/systemd/common.go b/libcontainer/cgroups/systemd/common.go index 31a3656ee..e6db845cb 100644 --- a/libcontainer/cgroups/systemd/common.go +++ b/libcontainer/cgroups/systemd/common.go @@ -126,6 +126,9 @@ func isUnitExists(err error) bool { func startUnit(cm *dbusConnManager, unitName string, properties []systemdDbus.Property, ignoreExist bool) error { statusChan := make(chan string, 1) + retry := true + +retry: err := cm.retryOnDisconnect(func(c *systemdDbus.Conn) error { _, err := c.StartTransientUnitContext(context.TODO(), unitName, "replace", properties, statusChan) return err @@ -140,6 +143,14 @@ func startUnit(cm *dbusConnManager, unitName string, properties []systemdDbus.Pr // https://github.com/opencontainers/runc/pull/1124). return nil } + if retry { + // In case a unit with the same name exists, this may + // be a leftover failed unit. Reset it, so systemd can + // remove it, and retry once. + resetFailedUnit(cm, unitName) + retry = false + goto retry + } return err }