This patch set adds full support the new unified cgroup hierarchy logic
of modern kernels.
A new kernel command line option "systemd.unified_cgroup_hierarchy=1" is
added. If specified the unified hierarchy is mounted to /sys/fs/cgroup
instead of a tmpfs. No further hierarchies are mounted. The kernel
command line option defaults to off. We can turn it on by default as
soon as the kernel's APIs regarding this are stabilized (but even then
downstream distros might want to turn this off, as this will break any
tools that access cgroupfs directly).
It is possibly to choose for each boot individually whether the unified
or the legacy hierarchy is used. nspawn will by default provide the
legacy hierarchy to containers if the host is using it, and the unified
otherwise. However it is possible to run containers with the unified
hierarchy on a legacy host and vice versa, by setting the
$UNIFIED_CGROUP_HIERARCHY environment variable for nspawn to 1 or 0,
respectively.
The unified hierarchy provides reliable cgroup empty notifications for
the first time, via inotify. To make use of this we maintain one
manager-wide inotify fd, and each cgroup to it.
This patch also removes cg_delete() which is unused now.
On kernel 4.2 only the "memory" controller is compatible with the
unified hierarchy, hence that's the only controller systemd exposes when
booted in unified heirarchy mode.
This introduces a new enum for enumerating supported controllers, plus a
related enum for the mask bits mapping to it. The core is changed to
make use of this everywhere.
This moves PID 1 into a new "init.scope" implicit scope unit in the root
slice. This is necessary since on the unified hierarchy cgroups may
either contain subgroups or processes but not both. PID 1 hence has to
move out of the root cgroup (strictly speaking the root cgroup is the
only one where processes and subgroups are still allowed, but in order
to support containers nicey, we move PID 1 into the new scope in all
cases.) This new unit is also used on legacy hierarchy setups. It's
actually pretty useful on all systems, as it can then be used to filter
journal messages coming from PID 1, and so on.
The root slice ("-.slice") is now implicitly created and started (and
does not require a unit file on disk anymore), since
that's where "init.scope" is located and the slice needs to be started
before the scope can.
To check whether we are in unified or legacy hierarchy mode we use
statfs() on /sys/fs/cgroup. If the .f_type field reports tmpfs we are in
legacy mode, if it reports cgroupfs we are in unified mode.
This patch set carefuly makes sure that cgls and cgtop continue to work
as desired.
When invoking nspawn as a service it will implicitly create two
subcgroups in the cgroup it is using, one to move the nspawn process
into, the other to move the actual container processes into. This is
done because of the requirement that cgroups may either contain
processes or other subgroups.
When the user wants to explicitly send our own PID a signal, then do so.
Don't follow up SIGABRT with a SIGHUP if send_sighup is enabled. At that
point the process should have segfaulted, hence there's no point in
following up with a SIGHUP.
Send only termination signals to ourselves, never KILL or ABRT signals.
Always say when we ignore errors. Cast calls whose return value we
knowingly ingore to (void). Use "bool" where we actually mean a boolean,
even if we return it as an int later on.
core: when looking for the unit for a process, look at the PID hashmaps first
It's cheaper that going to cgroupfs, and also usually the better choice
since it's not racy and can map PIDs even if they were moved to a
different unit.
cgroup: drop "ignore_self" argument from cg_is_empty()
In all cases where the function (or cg_is_empty_recursive()) ignoring
the calling process is actually wrong, as a process keeps a cgroup busy
regardless if its the current one or another. Hence, let's simplify
things and drop the "ignore_self" parameter.
units: enable waiting for unit termination in certain cases
The legacy cgroup hierarchy does not support reliable empty
notifications in containers and if there are left-over subgroups in a
cgroup. This makes it hard to correctly wait for them running empty, and
thus we previously disabled this logic entirely.
With this change we explicitly check for the container case, and whether
the unit is a "delegation" unit (i.e. one where programs may create
their own subgroups). If we are neither in a container, nor operating on
a delegation unit cgroup empty notifications become reliable and thus we
start waiting for the empty notifications again.
This doesn't really fix the general problem around cgroup notifications
but reduces the effect around it.
(This also reorders #include lines by their focus, as suggsted in
CODING_STYLE. We have to add "virt.h", so let's do that at the right
place.)
Michal Sekletar [Tue, 1 Sep 2015 14:02:58 +0000 (16:02 +0200)]
selinux: always use *_raw API from libselinux
When mcstransd* is running non-raw functions will return translated SELinux
context. Problem is that libselinux will cache this information and in the
future it will return same context even though mcstransd maybe not running at
that time. If you then check with such context against SELinux policy then
selinux_check_access may fail depending on whether mcstransd is running or not.
To workaround this problem/bug in libselinux, we should always get raw context
instead. Most users will not notice because result of access check is logged
only in debug mode.
* SELinux context translation service, which will translates labels to human
readable form
Martin Pitt [Tue, 1 Sep 2015 08:51:15 +0000 (10:51 +0200)]
logind: Listen to WMI hotkeys to catch SW_DOCK state/events
On Dell and HP laptops the dock state/events (SW_DOCK) come from the "{Dell,HP}
WMI hotkeys" input devices. Tag them as power-switch so that login actually
considers them. Use a general match in case this affects other vendors, too.
core: Use extract_first_word in config_parse_join_controllers
Related to the TODO item to replace FOREACH_WORD_QUOTED with it.
Tested by setting `JoinControllers=cpu,cpuacct,memory net_cls,blkio' in
/etc/systemd/system.conf, rebooting the system with the patched binaries
and checking that the desired setup was created by inspecting the
entries under /sys/fs/cgroup.
Tom Gundersen [Fri, 28 Aug 2015 22:18:20 +0000 (00:18 +0200)]
networkd: dhcp-server - allow configuration of the pool
The constraints we place on the pool is that it is a contiguous
sequence of addresses in the same subnet as the server address, not
including the subnet nor broadcast addresses, but possibly including
the server address itself. If the server address is included in the
pool it is (obviously) reserved and not handed out to clients.
Tom Gundersen [Fri, 28 Aug 2015 18:29:10 +0000 (20:29 +0200)]
sd-dhcp-server: simplify pool creation
Merge sd_dhcp_server_set_address() and sd_dhcp_server_set_lease_pool() into
sd_dhcp_server_configure_pool() as the behavior of the two former depends
on the order they are called in. The flexibility is not needed, so let's
just do this in one call.
David Herrmann [Mon, 31 Aug 2015 16:07:46 +0000 (18:07 +0200)]
login: support user-bus on dbus1
dbus-1.10 was just released, including systemd units to run
`dbus-daemon --session` as systemd user unit. This allows using a
user-bus with dbus1, just like we do per default with kdbus.
All the dbus libraries have already been fixed long ago to use the
user-bus as default. Hence, there's no need to set
DBUS_SESSION_BUS_ADDRESS= if we use the user-bus. However, gdm and
friends continue to spawn a session bus if this variable is not set
(instead of checking for the existence of the user-bus). Hence, we force
the user-bus, if it is available, in pam_systemd. Once gdm and friends
are fixed, we can continue to drop this again. However, that might take
a while.
With this in place, all that is needed to make the user-bus work is:
`systemctl --global enable dbus.socket`
If dbus.socket is not enabled, the legacy session-bus is still used.
Based on a patch by: Jan Alexander Steffens <jan.steffens@gmail.com>
When showing the number of tasks in a cgroup, recursively count tasks in
child cgroups and include them in the number. This ensures that the
number of tasks is cummulative the same way as memory, cpu and IO
resources are.
Old behaviour can be restored by passing the new --recursive=no switch.
This way we can be sure that less has the same idea of the terminal as
we do.
This solves issues in systems that have locale uninitalized, where
systemd would output UTF-8 but less wouldn't allow it and show them as
control characters.
core: don't generate stub unit file for transient units
We store the properties for transient units in drop-ins anyway, and
units don't have to have fragment files, hence don't bother with them,
and don't create them.
Refactor allocation of the result string to the top, since it is
currently done in both branches of the condition.
Remove unreachable code checking for EXTRACT_DONT_COALESCE_SEPARATORS
when state == SEPARATOR (the only place where SEPARATOR is assigned to
state follows a check for EXTRACT_DONT_COALESCE_SEPARATORS that jumps to
the end of the function.)
extract_first_word: Refactor allocation in empty argument case
This covers the case where an argument is an empty string, such as ''.
Instead of allocating the empty string in the individual conditions when
state == VALUE, just always allocate it at the end of state == START, at
which point we know we will have an argument.
Tested that test-util keeps passing after the refactor.
nspawn: add (no)rbind option to --bind and --bind-ro
--bind and --bind-ro perform the bind mount
non-recursively. It is sometimes (often?) desirable
to do a recursive mount. This patch adds an optional
set of bind mount options in the form of:
--bind=src-path:dst-path:options
options are comma separated and currently only
"rbind" and "norbind" are allowed.
Default value is "rbind".
Tom Gundersen [Thu, 27 Aug 2015 06:54:41 +0000 (08:54 +0200)]
sd-dhcp-server: improve predictability of leases
Rather than having all clients attempt to get the same leases (starting at the
beginning of the pool), make each client star at a random offset into the pool
determined by their client id. This greatly increases the chances of a given
client receiving the same IP address even though both the client and server
have lost any lease information (and distinct server instances handing out
the same leases).