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 <brandon.philips@coreos.com>
This commit is contained in:
Brandon Philips 2015-02-03 20:43:21 -05:00
parent 2da44f8c7b
commit 99233fde8c
1 changed files with 21 additions and 3 deletions

View File

@ -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)))