The payload of a file_handle structure is not 64bit aligned. So far used
_alignas_() to align it to 64bit as a whole, which by accident has the
side-effect that the payload ends up being aligned to 64bit too, but
this is ugly, because it's really just an accident...
Let's do this properly, and just use proper unaligned 64bit reads to
access the field, and do not assume aligning the structure as a whole
also aligns the payload part of it.
Follow-up for: fd51a7d8b5
The change in 4d2e61211d
broke armv7 where uintptr_t is 4 bytes:
/* test_id */
Assertion '((uintptr_t) _p) % alignof(uint64_t) == 0' failed at src/basic/cgroup-util.c:108, function cg_get_cgroupid_at(). Aborting.
(gdb) p (uintptr_t)fh.file_handle.f_handle % _Alignof(uint64_t)
$9 = 4
Enforce that the structure is aligned as expected
Follow-up for 4d2e61211d
The recently added test case TEST-07-PID1.subgroup-kill.sh surfaced a
race: if we enumerate PIDs in a cgroup, and the cgroup is unlinked at
the very same time reading will result in ENODEV. We need to handle that
gracefully. Hence let's do so.
Noticed while looking at:
https://github.com/systemd/systemd/actions/runs/16143084441/job/45554929264?pr=38120
bus_append_unit_property() and associated functions accept a long list of
properties. But the specific names are only available through code. But it is
useful to be able to know the specific list of properties that is supported, in
particular for shell completions. Thus, add a way to list the properties that
are supported by the code.
In the future we could also turn this into a test for the documentation. For
various reasons, the list of properties listed in the docs is a partially
overlapping set. E.g. for service type, the pull request
https://github.com/systemd/systemd/pull/37661 creates a list with 212 entries,
and this code generates 7 entries less and 184 more. I didn't check all the
differences, but in the few cases I did, the list generated here was actually
correctly supported by 'systemd-run -p'.
A smoke test is added.
As explained in https://lore.kernel.org/all/20250419183545.1982187-1-shakeel.butt@linux.dev/,
writing to memory.max or memory.high triggers synchronous memory reclaim
if the limit is lowered. This can end up taking nonnegligible amounts
of time, completely blocking pid1 from doing any other work while the
reclaim is ongoing.
To address this problem, the kernel going to add O_NONBLOCK semantics
to memory.max and memory.high. If the file is opened with O_NONBLOCK,
the synchronous memory reclaim is skipped and only triggered later
without blocking the process writing the file. Let's make sure we make
use of this by opening cgroupv2 attribute files with O_NONBLOCK.
We opt to do this for all cgroupv2 attribute files, to make sure that
if the same problem happens elsewhere in the future and is fixed in the
same way, we immediately take advantage of that fix without having to
make changes in systemd as well. We probably never want to block when
writing cgroupv2 attributes and any cases where we do want to block should
indicate so explicitly instead of blocking by default.
Let's rename the return parameters as "ret_xyz" systematically in
sd-login.
Also, let's make the return parameters systematically optional, like we
typically do these days. So far some where optional, other's weren't.
Let's clean this up.
This is not a trivial wrapper around user-created-buffer-based
syscall, so do not use _malloc suffix. Most of our functions
return an internally allocated buffer and this one's not special.
cg_get_keyed_attribute() is a more generic version of this,
and cg_is_empty_recursive() was the only user of this function,
which got converted in the previous commit.
This effectively renames cg_is_empty_recursive() to cg_is_empty().
Note that all existing code calls the former and not the latter,
hence with cgv1 support being dropped it's trivial to consult
cgroup.events directly for populated state everywhere.
Additionally, use more generic cg_get_keyed_attribute() helper
rather than cg_read_event().
- assert on supplied keys being unique
- Reject duplicate attributes with -EBADMSG
- Rename 'ret_values' to just 'values', given we don't
allocate the array
- Remove now unused cg_get_keyed_attribute_graceful()
Our baseline is v5.4 and cgroup v2 is enforced now,
which means CPU accounting is cheap everywhere without
requiring any controller, hence just remove the directive.
Let's return the size in a return parameter instead of the return value.
And if NULL is specified this tells us the caller doesn't care about the
size and expects a NUL terminated string. In that case look for an
embedded NUL byte, and refuse in that case.
This should lock things down a bit, as we'll systematically refuse
embedded NUL strings now when we expect strings.
The capsule instances are related to user instances, so treat them
equally to user@.service when handling cgroup paths. This also saves us
from polluting public libsystemd API with variant for capsules too.
Fix: #36098
Supersedes #35308 (cherry-picked one commit and replaced the rest)
(I left a few comments that's folded by GitHub. Please make sure to
check them too.)
"nsenter -a" doesn't migrate the specified process into the target
cgroup (it really should). Thus the cgroup will remain in a cgroup
that is (due to cgroup ns) outside our visibility. The kernel will
report the cgroup path of such cgroups as starting with "/../". Detect
that and print a reasonably error message instead of trying to resolve
that.