[systemd-devel] [WIP PATCH] Do not realize and migrate cgroups multiple times

Lennart Poettering lennart at poettering.net
Mon Dec 8 17:37:47 PST 2014

On Mon, 01.12.14 12:06, Martin Pitt (martin.pitt at ubuntu.com) wrote:

> Hello all,
> In my efforts to make user LXC containers work I noticed that under a
> "real" desktop (not just nspawn with VT login or ssh logins) my
> carefully set up cgroups in the non-systemd controllers get reverted.
> I. e. I put the session leader (and all other pids) of logind sessions
> (/user.slice/user-1000.slice/session-XX.scope) into all cgroup
> controllers, but a second after they are all back in the / cgroups (or
> sometimes in /user.slice). After some days of debugging (during which
> I learned a lot about the innards of systemd :-) I finally found out
> why:
> During unit cgroup initialization (unit_realize_cgroup), sibling
> cgroups are queued instead of initialized immediately.
> unit_create_cgroups() makes an attempt to avoid initializing and
> migrating a cgroup more than once:
>        path = unit_default_cgroup_path(u);
>        [...]
>        r = hashmap_put(u->manager->cgroup_unit, path, u);
>         if (r < 0) {
>                 log_error(r == -EEXIST ? "cgroup %s exists already: %s" : "hashmap_put failed for %s: %s", path, strerror(-r));
>                 return r;
>         }
> But this doesn't work: "path" always gets allocated freshly in that
> function, so the pointer is never in the hashmap and the -EEXISTS
> never actually hits. This causes -.slice to be initialized and
> recursively migrated a gazillion times, which explains the random
> punting of sub-cgroup PIDs back to /.

hashmap_put() will actually compare the string, not the pointer to
it. Our hashmap implementation gets a hash function pointer as well as
an element comparison function as input, to ensure that that works


Lennart Poettering, Red Hat

More information about the systemd-devel mailing list