--component-all is documented to include the default component-less
installation. Do not drop it merely because the context operates on a
root/image, or because all its transfers are currently disabled by
features.
This lets --component-all --feature-all enable-feature write the
default component feature drop-ins instead of succeeding with no
components selected.
TEST-72-SYSUPDATE covers both all transfers disabled by features and
the same default component feature operation under --root=.
Repro: create a default feata.feature plus a transfer gated by feata,
then run:
build/systemd-sysupdate --root="$root" --component-all --feature-all enable-feature
Before: no drop-in was written.
Follow-up for: 4481661a75
When recording installdb entries under --root=, keep the leading slash
after stripping the root. Compare current transfer target paths in the
same root-relative form during cleanup.
This prevents cleanup from treating still-owned resources below --root=
as orphaned.
TEST-72-SYSUPDATE covers --root= cleanup keeping a still-owned file and
its matching installdb entry.
Repro: create a rooted transfer for /target/foo-@v.bin, add a
matching installdb entry for /target/./foo-@v.bin, then run:
build/systemd-sysupdate --root="$root" --verify=no cleanup
Before: foo-1.bin and the installdb entry were removed.
Follow-up for: d82e256bb9
Repeats the enable/disable specifier-expansion check with 'systemctl
preset' instead. preset-all is intentionally not exercised here, since
$root accumulates unit files from earlier sections that are
deliberately invalid, and preset-all would trip on those unrelated
units.
Definitions enumerated under --root= are already rooted. Passing those
paths to the config parsers with the same root prefixes the root again,
so feature and transfer files are parsed from the wrong path.
Repro: create root/etc/sysupdate.d/rootfeat.feature and
01-root.transfer, then run:
build/systemd-sysupdate --root="$root" --verify=no --offline features rootfeat
Before: parsing failed at line 1 with a bogus Source Type= error.
Fixes#42783.
Follow-up for: e1384cfb09
systemd-escape currently only processes strings passed as
command line arguments. This is awkward for callers that already
have a generated list of strings, because they need to loop around
the tool or use xargs and carefully preserve whitespace and other
special characters.
Add --stdin to read one string per line from standard input and
write one escaped result per output line. Keep command line strings
mutually exclusive with --stdin so the input source remains
unambiguous.
Use an explicit option instead of treating '-' specially, since '-'
is itself a valid string to escape. The existing escape, unescape,
mangle, path, suffix, and template rules are reused unchanged.
The io.systemd.Unit context exposes CollectMode, but StartTransient
rejects it as unsupported. This prevents Varlink clients from selecting
whether failed transient units should be garbage-collected.
Accept CollectMode when creating transient units and persist the setting
in the runtime unit configuration. Extend the integration test to verify
the value in both the Varlink response and the resulting unit.
X entries inherit the cleanup age from the closest parent directory rule.
Inherit the age-by fields too, so parent rules such as m:1d keep their
full cleanup policy.
Reproducer:
mkdir -p /tmp/tmpfiles-ageby/parent/{child,other}
printf old >/tmp/tmpfiles-ageby/parent/child/file
printf old >/tmp/tmpfiles-ageby/parent/other/file
touch -d '3 days ago' /tmp/tmpfiles-ageby/parent/{child,other}/file
systemd-tmpfiles --clean - <<'EOT'
d /tmp/tmpfiles-ageby/parent - - - m:1d
X /tmp/tmpfiles-ageby/parent/child - - - -
EOT
Before:
child/file remained because X used the default age-by set.
other/file was removed by the parent m: rule.
Follow-up for 7f7a50dd15.
Resolve /etc/machine-id before checking the mount state and before
writing back, so symlinked targets are committed correctly.
Fixes: #43104
Follow-up for: efabf4e044
PrivateIPC= sets up a private mqueue mount for the service. When
CONFIG_POSIX_MQUEUE is disabled, mounting mqueue fails with ENODEV and
prevents the service from starting.
Treat ENODEV as an unavailable optional kernel feature while preserving
the private IPC namespace. Keep all other mount errors fatal.
Add coverage verifying that PrivateIPC= still creates a separate IPC
namespace when POSIX message queues are unavailable.
Fixes#42582
The option is generalized from a simple boolean switch that enables
a fixed list to a list-of-patterns.
The old value works, but is deprecated: -Dstandalone-binaries=true is translated
to -Dstandalone-binaries=repart,report,tmpfiles,sysusers,shutdown.
We could already build all normal executables as .standalone, but the
installation only supported a small fixes subset. This wasn't flexible
enough:
- packagers might want to provide additional standalone binaries then the
small subset that was already enabled
- but at the same time, whenever new binaries were added to this subset,
downstream packaging had to be adjusted in sync, at least in the case of
Fedora, because otherwise we'd get a complaint about unexpected .standalone
binaries in the temporary install root.
With the new option, downstreams can just specify the binaries that they
want to be installed in the .standalone variant.
As usual with this type of change, the build dir must be reprovisioned.
A calendar timer that is already waiting keeps the base timestamp it was
last armed from. When the wall clock is set backwards, that base can end
up in the future relative to the new realtime, and passing it to
calendar_spec_next_usec() schedules the next elapse relative to the old
future time instead of recalculating from now. systemctl list-timers
then keeps showing the stale pre-adjustment elapse (e.g. "3 years left"
after the clock moved back two years) and the timer never catches up.
Clamp the selected calendar base to the current realtime before asking
calendar_spec_next_usec() for the next occurrence. The clamp only kicks
in when the base is genuinely in the future, so Persistent=yes timers
whose last trigger is still in the past keep their catch-up behaviour and
we don't reintroduce the missed-run regression seen after suspend.
Fixes#6036.
1f76654f94 added support to build .standalone
variants of most binaries. test-dlopen-note.py is hooked in the test suite for
everything that can do .standalone, but this means that the .standalone
variants become a prerequisite for tests. This means that meson will build the
.standalone variants for all binaries before running tests, which takes quite a
bit of time in some situations. (Arguably, the dlopen test suite was excluded
by default, so maybe meson could be smart and figure out that those tests are
not enabled by default. But it doesn't seem to make this distinction.)
C lines copy symlinks as symlinks. The post-copy type check should
inspect the source symlink itself, not follow its target.
Reproducer:
src=/tmp/tmpfiles-src-link.$$
dst=/tmp/tmpfiles-dst-link.$$
conf=/tmp/tmpfiles-conf.$$
ln -s missing-target "$src"
printf 'C %s - - - - %s\n' "$dst" "$src" >"$conf"
systemd-tmpfiles --create "$conf"
Before:
Failed to stat($src): No such file or directory
status=73
$dst -> missing-target already existed
Follow-up for 8f6fb95cd0.
Opening the destination only proves that it exists. If copy_tree_at()
failed for any reason other than an existing destination, report that
copy error.
Reproducer:
name=tmpfiles-copy-bug.$$
src=/tmp/$name.src; dst=/tmp/$name.dst; conf=/tmp/$name.conf
mkdir "$src" "$dst"
printf payload >"$src/file"
chmod 500 "$dst"
printf 'C %s - - - - %s\n' "$dst" "$src" >"$conf"
systemd-tmpfiles --create "$conf"
Before:
exit=0
copied=no
Follow-up for 8f6fb95cd0.
Relative symlink targets are resolved from the directory containing the
link. Make the L? existence check use the same rule.
Reproducer:
tmp=$(mktemp -d /tmp/tmpfiles-link.XXXXXX)
conf=$(mktemp /tmp/tmpfiles-conf.XXXXXX)
printf data >"$tmp/target"
printf 'L? %s/link - - - - target\n' "$tmp" >"$conf"
systemd-tmpfiles --create --dry-run "$conf"
Before:
The target was checked root-relative, not beside the link.
Follow-up for b5dc805583.
%t and the other directory specifiers are parsed as normal paths.
They are prefixed by --root= later, so the specifier itself must stay
rootless.
Reproducer:
tmp=$(mktemp -d /tmp/tmpfiles-root.XXXXXX)
conf=$(mktemp /tmp/tmpfiles-conf.XXXXXX)
printf 'd %%t/tmpfiles-repro 0755 - - -\n' >"$conf"
systemd-tmpfiles --root="$tmp" --create --dry-run "$conf"
Before:
Would create directory $tmp/$tmp/run/tmpfiles-repro
Follow-up for de61a04b18.
Track which machine the cached address list belongs to and refresh it
when ResolveRecord() advances to another machine. This keeps A/AAAA
reuse for the same machine while avoiding mixed name/address records.
Reproducer: register two machines with private addresses 10.88.1.1
and 10.88.2.1, then call io.systemd.Resolve.Hook.ResolveRecord
with both A questions in one request.
Before: the answer for the second machine used its own name but
reused the first machine's address, e.g. resolve-bug-m2 returned
10.88.1.1 instead of 10.88.2.1.
Follow-up: 3cd929f837
Workers may return a newer embedded identity while processing
an owner update. Accept self-modifiable changes, but require
privileged changes to carry a trusted signature.
Follow-up for 70a5db5822
The modern hwdb.bin format contains the filenames of the input data that
makes up the database. This is useful but in offline builds where
--root is used, the filenames are the full build paths including the
specified root. This introduces build paths and thus information
leakage and non-reproducible data.
Solve this by stripping the root prefix off the original path when
passing to import_file.
Add TEST-17-UDEV.hwdb.sh to verify that hwdb.bin files contain the
path inside the root, but not the path of the root.
Add a new --no-reconfigure flag to 'networkctl reload' that reloads
.network and .netdev files from disk without reconfiguring any network
interfaces. This may be useful to avoid reconfiguring multiple interfaces
simultaneously when multiple .network files are updated, or when an updated
.network file is applied to multiple interfaces.
On the networkd side, manager_reload() gains a reconfigure_links parameter
that gates the per-link reconfiguration loop. A new io.systemd.Network.Reload
varlink method is added that exposes this as an optional reconfigureLinks
boolean (defaults to true). Both plain 'networkctl reload' and
'--no-reconfigure' now unconditionally call this method first. If an older
networkd returns MethodNotFound, plain reload falls back to
io.systemd.service.Reload for backward compatibility; '--no-reconfigure'
fails with a clear error in that case.
Reject credentials whose not-after timestamp is equal to the timestamp
at each encryption entry point.
Reproducer: systemd-creds --timestamp=TS --not-after=TS encrypt in out
Before: encryption succeeded, but decrypt refused the credential as not
in order.
Follow-up: 21bc0b6fa1
Use the image metadata size when building JSON output, matching the
value already shown by the text output.
Reproducer: systemd-dissect --json=short image.raw
Before: text output showed Size, but JSON omitted the top-level size
field.
Follow-up: be5bee2a13
Return failure for --json check-new when no candidate is available.
Let sysupdated accept that exact JSON no-update result from workers.
Reproducer: systemd-sysupdate --verify=no --json=short check-new
Before: the command printed {"available":null} and exited successfully.
Follow-up: 42c0b689a8
Skip generated fstab and crypttab output when --dry-run=yes is used,
after confirming there is eligible content to generate.
Reproducer: systemd-repart --dry-run=yes --generate-fstab=/tmp/root/etc/fstab -
Before: the command exited successfully and still wrote the requested
fstab file.
Follow-up: 1a0541d44c
Validate passwd.shell.root after reading the credential so it uses
the same target-root shell checks as --root-shell= and prompted input.
Reproducer: CREDENTIALS_DIRECTORY=... systemd-firstboot --root=...
with passwd.shell.root=/bin/nonexistentshell
Before: /etc/passwd was written with the nonexistent root shell and
the command exited successfully.
Follow-up: 416f7b3a11
Validate passwd.shell.<user> credentials with the same login-shell
rules used for sysusers.d shell fields before writing passwd entries.
Reproducer: CREDENTIALS_DIRECTORY=... systemd-sysusers --root=...
with --inline 'u creduser 999 "Cred User" / -'
Before: relative-shell was written as the login shell and the command
exited successfully.
Follow-up: 99e9f896fb
Reject --app-specific= for the new verb. The option only makes sense
for verbs that derive IDs from an existing base ID.
Reproducer: systemd-id128 new --app-specific=4f68bce3e8cd4db196e7fbcaf984b709
Before: the command printed a random ID and exited successfully.
Follow-up: 0d1d512f7f
Since 5c6bb28999 image_discover() uses
chaseat() to chase the path to the image. This however breaks the raw
image check in image_make() as "path" is now not the symlink itself, but
the symlink target.
So with:
$ ls -l /var/lib/machines
total 872104
lrwxrwxrwx. 1 root root 12 Jul 14 06:10 foo.raw -> foo.squashfs
-rw-r--r--. 1 root root 5368709120 Jul 13 02:07 foo.squashfs
The endswith(path, ".raw") check is now performed on "/.../foo.squashfs"
instead of "/.../foo.raw", making it false and thus ignoring the image
symlink completely.
Address this by also checking if the pretty name is set - if so, and the
path is a regular file, the caller must've been image_find() or
image_discover() which already checked if the original path ends in .raw
and is a regular file.
Follow-up for 5c6bb28999.
Resolves: #41656
Pass relax_extension_release_check through the directory extraction
path instead of hardcoding false. Directory extensions now honor the
same --force relaxation as dissected images.
Reproducer:
cp -a /tmp/app0 /tmp/app10
sudo portablectl attach --force --runtime \
--extension /tmp/app10 /tmp/rootdir app0
Before:
directory image extraction always used strict extension-release name
checks. --force relaxed other extension paths but still rejected a
renamed directory extension with matching metadata.
Follow-up: 06768b90a3
unmerge_hierarchy() joined the persisted work_dir value directly with
--root=. An empty value therefore resolved to the root itself and was passed
to rm_rf().
Require the decoded metadata to name a non-empty, safe, normalized relative
path before constructing the removal target. Add coverage using a disposable
root with deliberately emptied metadata.
Follow-up for 9cfad502f4
Reproducer:
journalctl -F _SYSTEMD_UNIT -u test.service --no-pager
journalctl -u test.service --no-pager -n 1
Before, the field listing ignored the unit filter and listed unrelated
units, while the normal journal query applied the filter.
sd_journal_query_unique() cannot represent journalctl filters such as
unit, boot, time, cursor, or grep filters. Walking the journal line by
line would make field listing linear in the number of entries and
duplicate unique-value handling.
Keep the scope-option predicate next to add_filters(), and reject field
listings combined with options that actually limit the journal.
Display-only options such as --pager-end are left alone.
This adds an IPv4 counterpart to `IPv6ProxyNDPAddress=` for adding
manual entries to the kernel's IPv4 neighbour proxy table (check via
`ip -4 neighbour show proxy dev <dev>`). systemd-networkd only exposed
`IPv4ProxyARP=` for per-interface `proxy_arp` sysctl (automatic proxy
ARP) with no way to manage manual entries from a .network file.
To avoid duplicating the IPv6 proxy NDP code path, both families are
now combined into a single new `networkd-neighbor-proxy` module. The
IPv6 behaviour is preserved: `IPv6ProxyNDPAddress=` still implies
`IPv6ProxyNDP=yes` unless `IPv6ProxyNDP=` is explicitly disabled and
entries are still dropped if the kernel has no IPv6 support.
The same rule is applied to `IPv4ProxyARPAddress=`. It implies
`IPv4ProxyARP=yes` when the sysctl is not explicitly set and has no
effect if `IPv4ProxyARP=` has been set to false.
This keeps the user model symmetric and predictable across both
families: a single per-address setting that turns on the matching
per-interface sysctl automatically, while still letting system
administrators opt out by setting the boolean explicitly to false.
Note that the IPv4 manual NTF_PROXY entries installed here would
actually function without `proxy_arp` (unlike IPv6, where `proxy_ndp`
gates the manual entries); the implication is kept for symmetry with
`IPv6ProxyNDPAddress=` and is now called out explicitly in the man
page, together with the fact that enabling `proxy_arp` also activates
interface-wide automatic proxy ARP for routed-toward addresses on
connected subnets.
Parser-time validation rejects addresses the kernel would refuse:
the ANY/null address for both families, IPv4 and IPv6 multicast
and the IPv4 limited broadcast 255.255.255.255.
Signed-off-by: Aritra Basu <aritrbas+gh@cisco.com>
Normalize each remove argument with determine_image() before building
the RemoveImage request. Relative paths are converted before reaching
portabled.
Reproducer:
cd /tmp
portablectl remove ./portable-repro
Before:
./portable-repro was sent unchanged to portabled and rejected as an
invalid image name/path. Removing an image by a relative path failed
even though the path referred to a valid local image.
Follow-up: 61d0578b07
Open unit files with chase_and_openat() rooted at the image instead of
plain openat(). Symlinks are now resolved under the image root and must
end at a regular file.
Reproducer:
ln -s /tmp/portable-host-unit \
IMAGE/usr/lib/systemd/system/PREFIX.service
portablectl inspect --cat IMAGE PREFIX.service
Before:
inspect followed the absolute symlink on the host and printed host
file contents as image unit metadata. Image inspection could leak or
trust files outside the portable image.
Follow-up: 61d0578b07
Parse the WithExtensions metadata block whenever --force selects that
bus method. This keeps the following unit-file array aligned with the
reply layout.
Reproducer:
portablectl inspect --force /usr/share/minimal_0.raw \
minimal-app0.service
Before:
inspect printed the image metadata but dropped the matching unit
list. Scripts could not see which unit files were selected when
--force was used with the WithExtensions bus reply.
Follow-up: bdfa3f3a5c