There is a TOCTOU in the `systemctl status` where a unit might change
its state during the initial ListUnitsByPatterns call and the subsequent
individual GetAll calls, which then makes the systemctl call fail even
if the unit that was originally pulled in was active/running:
[ 1922.040463] TEST-26-SYSTEMCTL.sh[117]: + systemctl status -a --state active,running,plugged
[ 1922.051423] systemd[1]: Got message type=method_call sender=n/a destination=org.freedesktop.systemd1 path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=ListUnitsByPatterns cookie=1 reply_cookie=0 signature=asas error-name=n/a error-message=n/a
[ 1922.052501] systemd[1]: Sent message type=method_return sender=org.freedesktop.systemd1 destination=n/a path=n/a interface=n/a member=n/a cookie=1 reply_cookie=1 signature=a(ssssssouso) error-name=n/a error-message=n/a
[ 1922.052650] systemd[1]: Got message type=method_call sender=n/a destination=org.freedesktop.systemd1 path=/org/freedesktop/systemd1/unit/_2d_2emount interface=org.freedesktop.DBus.Properties member=GetAll cookie=2 reply_cookie=0 signature=s error-name=n/a error-message=n/a
...
[ 1922.222061] systemd-hostnamed[424]: Idle for 30s, exiting.
...
[ 1922.224961] systemd[1]: systemd-hostnamed.service: Got notification message from PID 424: STOPPING=1, STATUS=Shutting down...
[ 1922.224983] systemd[1]: systemd-hostnamed.service: Changed running ->stop-sigterm
...
[ 1922.228984] systemd[1]: Got message type=method_call sender=n/a destination=org.freedesktop.systemd1 path=/org/freedesktop/systemd1/unit/systemd_2dhostnamed_2eservice interface=org.freedesktop.DBus.Properties member=GetAll cookie=41 reply_cookie=0 signature=s error-name=n/a error-message=n/a
[ 1922.234402] systemd[1]: Sent message type=method_return sender=org.freedesktop.systemd1 destination=n/a path=n/a interface=n/a member=n/a cookie=43 reply_cookie=41 signature=a{sv} error-name=n/a error-message=n/a
Since in this case we care mostly about the code paths the command
triggers, ignore its exit code as we do for the previous one.
Resolves: #39612
As registering the container creates a scope which might not be cleaned
up completely before we run a next command in the same container,
causing intermittent test fails:
[ 63.424739] TEST-13-NSPAWN.sh[4231]: + systemd-nspawn --directory=/var/lib/machines/TEST-13-NSPAWN.sanity.zH2 bash -xec '[[ $USER == root ]]'
[ 63.427504] systemd-nspawn[4381]: ░ Spawning container TEST-13-NSPAWN.sanity.zH2 on /var/lib/machines/TEST-13-NSPAWN.sanity.zH2.
[ 63.437154] systemd[1]: Started TEST-13-NSPAWN.sanity.zH2.scope - Container TEST-13-NSPAWN.sanity.zH2.
[ 63.437765] systemd-machined[1164]: New machine TEST-13-NSPAWN.sanity.zH2.
[ 63.440311] TEST-13-NSPAWN.sh[4381]: + [[ root == root ]]
[ 63.442046] systemd[1]: TEST-13-NSPAWN.sanity.zH2.scope: Killed unit cgroup '/machine.slice/TEST-13-NSPAWN.sanity.zH2.scope' with SIGKILL on client request.
[ 63.442583] systemd-nspawn[4381]: Container TEST-13-NSPAWN.sanity.zH2 exited successfully.
[ 63.443073] systemd-machined[1164]: Machine TEST-13-NSPAWN.sanity.zH2 terminated.
[ 63.448728] TEST-13-NSPAWN.sh[4231]: + systemd-nspawn --directory=/var/lib/machines/TEST-13-NSPAWN.sanity.zH2 --user=testuser bash -xec '[[ $USER == testuser ]]'
[ 63.451209] systemd-nspawn[4385]: ░ Spawning container TEST-13-NSPAWN.sanity.zH2 on /var/lib/machines/TEST-13-NSPAWN.sanity.zH2.
[ 63.455295] systemd-nspawn[4385]: Failed to allocate scope: Unit TEST-13-NSPAWN.sanity.zH2.scope was already loaded or has a fragment file.
[ 63.456139] systemd[1]: TEST-13-NSPAWN.sanity.zH2.scope: Deactivated successfully.
[ 63.461292] TEST-13-NSPAWN.sh[2839]: + at_exit
Since even systemd-nspawn's man page suggests not to register containers
with systemd-machined if they don't run a service manager, let's do just
that to mitigate the race.
Resolves: #39629
Regular generated paths make it hard to identify individual GPIO
devices. This is a challenge when using multiple USB-to-GPIO adapters
like Diolan DLN2.
The unique symlinks from this rule can be used, e.g., with gpiod tools.
The same service name was accidentally used for two invocations:
```
[ 1801.197993] H TEST-04-JOURNAL.sh[20563]: + assert_rc 0 journalctl -q -D /run/log/journal/e30adae55e664d328af442bf5df694c8/ -u test-23833.service --grep service=test-23833.service
[ 1801.198527] H TEST-04-JOURNAL.sh[20685]: + set +ex
[ 1801.222676] H TEST-04-JOURNAL.sh[20686]: Nov 10 03:18:51 H systemd[1]: test-23833.service: About to execute: /usr/bin/bash -c "echo service=test-23833.service invocation=\$INVOCATION_ID; journalctl --sync"
[ 1801.222676] H TEST-04-JOURNAL.sh[20686]: Nov 10 03:18:51 H systemd[1]: Started test-23833.service - [systemd-run] /usr/bin/bash -c "echo service=test-23833.service invocation=\$INVOCATION_ID; journalctl --sync".
[ 1801.222676] H TEST-04-JOURNAL.sh[20686]: Nov 10 03:18:51 H (bash)[20681]: test-23833.service: Executing: /usr/bin/bash -c "echo service=test-23833.service invocation=\$INVOCATION_ID; journalctl --sync"
[ 1801.222676] H TEST-04-JOURNAL.sh[20686]: Nov 10 03:18:51 H bash[20681]: service=test-23833.service invocation=1866f15e95924a688dcecde72bf345f6
[ 1801.227878] H TEST-04-JOURNAL.sh[20563]: + assert_rc 1 journalctl -q -D /var/log/journal/e30adae55e664d328af442bf5df694c8/ -u test-23833.service --grep service=test-23833.service
[ 1801.228265] H TEST-04-JOURNAL.sh[20689]: + set +ex
[ 1801.253412] H TEST-04-JOURNAL.sh[20690]: Nov 10 03:18:49 H systemd[1]: test-23833.service: About to execute: /usr/bin/bash -c "echo service=test-23833.service invocation=\$INVOCATION_ID; journalctl --sync"
[ 1801.253412] H TEST-04-JOURNAL.sh[20690]: Nov 10 03:18:49 H systemd[1]: Started test-23833.service - [systemd-run] /usr/bin/bash -c "echo service=test-23833.service invocation=\$INVOCATION_ID; journalctl --sync".
[ 1801.253412] H TEST-04-JOURNAL.sh[20690]: Nov 10 03:18:49 H (bash)[20581]: test-23833.service: Executing: /usr/bin/bash -c "echo service=test-23833.service invocation=\$INVOCATION_ID; journalctl --sync"
[ 1801.253412] H TEST-04-JOURNAL.sh[20690]: Nov 10 03:18:49 H bash[20581]: service=test-23833.service invocation=a3089a62b5624d21bac0a75a3995d8b5
[ 1801.258158] H TEST-04-JOURNAL.sh[20692]: FAIL: expected: '1' actual: '0'
```
Closes#35788
This gives access to credentials within ExecCondition=. As described in
ticket #35788, I do have a use-case for this and as noted in the
commit that dropped this[1], this is OK to be revisited if there are
use-cases.
[1] a145623bc4
systemd-repart is incorrectly choosing the loop-mount
code path to copy files after formatting, instead of using the --rootdir
path, which is required by mkfs.btrfs to apply compression (since it's
on files, not the fs).
So two fixes (and an integ test):
1. If Btrfs compression is requested without a root directory (e.g.,
Compression= without CopyFiles=), we now log a warning and skip the
--compress flag. This prevents the mkfs.btrfs failure, and it's
meaningless anyway without any files.
2. The logic in repart now uses the --rootdir code path whenever the
partition is btrfs and compression is requested. Otherwise it still
won't work even in the legitimate case because use the loop mounting
code, which is too late to use --compress.
Fixes: https://github.com/systemd/systemd/issues/39584
Add testcase_btrfs_compression() to verify that btrfs partitions with
Compression= and CopyFiles= directives work correctly.
The test verifies the fix for issue #39584, where mkfs.btrfs would fail
with "ERROR: --compression must be used with --rootdir" when repart
tried to create compressed btrfs filesystems.
The test creates a partition definition with Format=btrfs,
Compression=zstd, and CopyFiles=, then validates:
1. systemd-repart output shows "Rootdir from:" and "Compress:",
confirming that the --rootdir code path is used
2. mkfs.btrfs is invoked with both --compress and --rootdir options
3. The file is successfully copied to the filesystem
4. Compression is actually applied (verified via compsize output
containing "zstd")