From 99233fde8c4f58853a474a5831ef0bcf6bf866c5 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 3 Feb 2015 20:43:21 -0500 Subject: [PATCH] cgroups: systemd: set DefaultDependencies=false if possible The root problem this fixes is the docker daemon uses DefaulDependencies for all of its scopes which means that the containers get killed by systemd before the docker daemon is notified to shutdown. This means that a docker run in a service file won't get ordered properly on shutdown! This has affected many CoreOS users and is documented in systemd as so: "Unless DefaultDependencies=false is used, scope units will implicitly have dependencies of type Conflicts= and Before= on shutdown.target." Unfortunately, systemd didn't allow setting DefaultDependencies=false on transient units until today: systemd-run --scope --property="DefaultDependencies=false" /usr/bin/sleep 50000 Unknown assignment DefaultDependencies=false. Failed to create message: Invalid argument Fixed here: http://cgit.freedesktop.org/systemd/systemd/commit/?id=261420ba2a20305ad271b6f5f380aa74c5c9dd50 Discussion with systemd upstream: http://lists.freedesktop.org/archives/systemd-devel/2014-December/026313.html http://lists.freedesktop.org/archives/systemd-devel/2015-February/027890.html Tested with docker and systemd master as of today and it work for me. Signed-off-by: Brandon Philips --- cgroups/systemd/apply_systemd.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/cgroups/systemd/apply_systemd.go b/cgroups/systemd/apply_systemd.go index 3e7ad846..e250dd70 100644 --- a/cgroups/systemd/apply_systemd.go +++ b/cgroups/systemd/apply_systemd.go @@ -28,9 +28,10 @@ type subsystem interface { } var ( - connLock sync.Mutex - theConn *systemd.Conn - hasStartTransientUnit bool + connLock sync.Mutex + theConn *systemd.Conn + hasStartTransientUnit bool + hasTransientDefaultDependencies bool ) func newProp(name string, units interface{}) systemd.Property { @@ -64,6 +65,18 @@ func UseSystemd() bool { if dbusError, ok := err.(dbus.Error); ok { if dbusError.Name == "org.freedesktop.DBus.Error.UnknownMethod" { hasStartTransientUnit = false + return hasStartTransientUnit + } + } + } + + // Assume StartTransientUnit on a scope allows DefaultDependencies + hasTransientDefaultDependencies = true + ddf := newProp("DefaultDependencies", false) + if _, err := theConn.StartTransientUnit("docker-systemd-test-default-dependencies.scope", "replace", ddf); err != nil { + if dbusError, ok := err.(dbus.Error); ok { + if dbusError.Name == "org.freedesktop.DBus.Error.PropertyReadOnly" { + hasTransientDefaultDependencies = false } } } @@ -108,6 +121,11 @@ func Apply(c *cgroups.Cgroup, pid int) (map[string]string, error) { newProp("CPUAccounting", true), newProp("BlockIOAccounting", true)) + if hasTransientDefaultDependencies { + properties = append(properties, + newProp("DefaultDependencies", false)) + } + if c.Memory != 0 { properties = append(properties, newProp("MemoryLimit", uint64(c.Memory)))