From 15ed73c1c075e6590ecf56170acedcba0da8167e Mon Sep 17 00:00:00 2001 From: baude Date: Wed, 5 Sep 2018 13:10:21 -0500 Subject: [PATCH] systemd-239+ no longer allows delegate slice Systemd no longer allows the setting of the Delegate property for cgroups. This patch is modeled after a runc commit 0e16bd9b53eb3c57ea6fe59fc6d9385c2edb9fd9 which corrects a similar situation for them. Signed-off-by: baude --- systemd.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/systemd.go b/systemd.go index 4394ba167c13a..2486ed1941c2d 100644 --- a/systemd.go +++ b/systemd.go @@ -32,6 +32,11 @@ const ( defaultSlice = "system.slice" ) +var ( + canDelegate bool + once sync.Once +) + func Systemd() ([]Subsystem, error) { root, err := v1MountPoint() if err != nil { @@ -80,15 +85,39 @@ func (s *SystemdController) Create(path string, resources *specs.LinuxResources) } defer conn.Close() slice, name := splitName(path) + // We need to see if systemd can handle the delegate property + // Systemd will return an error if it cannot handle delegate regardless + // of its bool setting. + checkDelegate := func() { + canDelegate = true + dlSlice := newProperty("Delegate", true) + if _, err := conn.StartTransientUnit(slice, "testdelegate", []systemdDbus.Property{dlSlice}, nil); err != nil { + if dbusError, ok := err.(dbus.Error); ok { + // Starting with systemd v237, Delegate is not even a property of slices anymore, + // so the D-Bus call fails with "InvalidArgs" error. + if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") || strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.InvalidArgs") { + canDelegate = false + } + } + } + + conn.StopUnit(slice, "testDelegate", nil) + } + once.Do(checkDelegate) properties := []systemdDbus.Property{ systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", name)), systemdDbus.PropWants(slice), newProperty("DefaultDependencies", false), - newProperty("Delegate", true), newProperty("MemoryAccounting", true), newProperty("CPUAccounting", true), newProperty("BlockIOAccounting", true), } + + // If we can delegate, we add the property back in + if canDelegate { + properties = append(properties, newProperty("Delegate", true)) + } + ch := make(chan string) _, err = conn.StartTransientUnit(name, "replace", properties, ch) if err != nil {