The idea is that we have strvs like list of server names or addresses, where
the majority of strings is rather short, but some are long and there can
potentially be many strings. So formattting them either all on one line or all
in separate lines leads to output that is either hard to read or uses way too
many rows. We want to wrap them, but relying on the pager to do the wrapping is
not nice. Normal text has a lot of redundancy, so when the pager wraps a line
in the middle of a word the read can understand what is going on without any
trouble. But for a high-density zero-redundancy text like an IP address it is
much nicer to wrap between words. This also makes c&p easier.
This adds a variant of TABLE_STRV which is wrapped on output (with line breaks
inserted between different strv entries).
The change table_print() is quite ugly. A second pass is added to re-calculate
column widths. Since column size is now "soft", i.e. it can adjust based on
available columns, we need to two passes:
- first we figure out how much space we want
- in the second pass we figure out what the actual wrapped columns
widths will be.
To avoid unnessary work, the second pass is only done when we actually have
wrappable fields.
A test is added in test-format-table.
We check that the binary exists before writing the service file, but
let's also not consider the service started until the fork has happened.
This is still relatively new stuff, so we're can change the implementation
details like this.
The test was failing because it couldn't start the service:
path-modified.service: state = failed; result = exit-code
path-modified.path: state = waiting; result = success
path-modified.service: state = failed; result = exit-code
path-modified.path: state = waiting; result = success
path-modified.service: state = failed; result = exit-code
path-modified.path: state = waiting; result = success
path-modified.service: state = failed; result = exit-code
path-modified.path: state = waiting; result = success
path-modified.service: state = failed; result = exit-code
path-modified.path: state = waiting; result = success
path-modified.service: state = failed; result = exit-code
Failed to connect to system bus: No such file or directory
-.slice: Failed to enable/disable controllers on cgroup /system.slice/kojid.service, ignoring: Permission denied
path-modified.service: Failed to create cgroup /system.slice/kojid.service/path-modified.service: Permission denied
path-modified.service: Failed to attach to cgroup /system.slice/kojid.service/path-modified.service: No such file or directory
path-modified.service: Failed at step CGROUP spawning /bin/true: No such file or directory
path-modified.service: Main process exited, code=exited, status=219/CGROUP
path-modified.service: Failed with result 'exit-code'.
Test timeout when testing path-modified.path
In fact any of the services that we try to start may fail, especially
considering that we're doing some rogue cgroup operations. See
https://github.com/systemd/systemd/pull/16603#issuecomment-679133641.
Just to make it easier to grok what happens when test-path fails.
Change printf→log_info so that output is interleaved and not split in two
independent parts in log files.
A comment indicates the start of the new contents of the override file,
and another indicates that lines following it will be discarded once
editing is finished.
The contents of the unit file and drop-ins are listed out after this
last marker.
Adds WRITE_STRING_FILE_TRUNCATE to set O_TRUNC when opening a file.
Thanks to cgzones for providing the required SELinux function calls.
Co-authored-by: Christian Göttsche <cgzones@googlemail.com>
For encrypted block devices that we need to unlock from the initramfs,
we currently rely on dracut shipping `cryptsetup.target`. This works,
but doesn't cover the case where the encrypted block device requires
networking (i.e. the `remote-cryptsetup.target` version). That target
however is traditionally dynamically enabled.
Instead, let's rework things here by adding a `initrd-cryptsetup.target`
specifically for initramfs encrypted block device setup. This plays the
role of both `cryptsetup.target` and `remote-cryptsetup.target` in the
initramfs.
Then, adapt `systemd-cryptsetup-generator` to hook all generated
services to this new unit when running from the initrd. This is
analogous to `systemd-fstab-generator` hooking all mounts to
`initrd-fs.target`, regardless of whether they're network-backed or not.
Why this change
---------------
Assumption - PAM's auth stack is properly configured.
Currently account pam_systemd_home.so returns PAM_SUCCESS for non
systemd-homed users, and a variety of return values (including
PAM_SUCCESS) for homed users.
account pam_unix returns PAM_AUTHINFO_UNAVAIL for systemd-homed
users, and a variety of return values (including PAM_AUTHINFO_UNAVAIL)
for normal users.
No possible combination in the pam stack can let us preserve the
various return values of the modules. For example, the configuration
mentioned in the manpage causes account pam_unix to never be reached
since pam_systemd_home just returns a success for ordinary users. Users
with expired passwords are allowed to log in because a check cannot be
made.
More configuration examples and why they don't work are mentioned
in #16906 and the downstream discussion linked there.
After this change
-----------------
account pam_unix will continue to return wrong value for homed users.
But we can skip the module conditionally using the return value from
account pam_systemd_home. We can already do this with the auth and
password modules.
This creates a private mount namespace for test-mountpint-util, with all
propagation from the host turned off. This gives us the guarantee that
/proc/self/mountinfo remains fixed and constant while we operate,
removing potential races against other unrelated stuff running on the
system that changes the mount table.
Prompted-by: #17050
(I doubt this actually fixes 17050, this is mostly to make sure that we
aren't possibly affected by such races in our test)
The status string is modeled after our --version output: +enabled -disabled equals=more-info
For example:
Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=allow-downgrade/supported
We would print the whole string as a single super-long line. Let's nicely
break the text into lines that fit on the screen.
$ COLUMNS=70 build/resolvectl --no-pager nta
Global: home local intranet 23.172.in-addr.arpa lan
18.172.in-addr.arpa 16.172.in-addr.arpa 19.172.in-addr.arpa
25.172.in-addr.arpa 21.172.in-addr.arpa d.f.ip6.arpa
20.172.in-addr.arpa 30.172.in-addr.arpa 17.172.in-addr.arpa
internal 168.192.in-addr.arpa 28.172.in-addr.arpa
22.172.in-addr.arpa 24.172.in-addr.arpa 26.172.in-addr.arpa
corp 10.in-addr.arpa private 29.172.in-addr.arpa test
27.172.in-addr.arpa 31.172.in-addr.arpa
Link 2 (hub0):
Link 4 (enp0s31f6):
Link 5 (wlp4s0):
Link 7 (virbr0): adsfasdfasdfasd.com 21.172.in-addr.arpa lan j b
a.com home d.f.ip6.arpa b.com local 16.172.in-addr.arpa
19.172.in-addr.arpa 18.172.in-addr.arpa 25.172.in-addr.arpa
20.172.in-addr.arpa k i h 23.172.in-addr.arpa
168.192.in-addr.arpa d g intranet 17.172.in-addr.arpa c e.com
30.172.in-addr.arpa a f d.com e internal
Link 8 (virbr0-nic):
Link 9 (vnet0):
Link 10 (vb-rawhide):
Link 15 (wwp0s20f0u2i12):
Failed to enter shared memory directory multipath: Permission denied
→
Failed to enter shared memory directory /dev/shm/multipath: Permission denied
When looking at nested directories, we will print only the final two elements
of the path. That is still more useful than just the last component of the
path. To print the full path, we'd have to allocate the string, and since the
error occurs so very rarely, I think the current best-effort approach is
enough.
So far we didn't allow empty properties, but it makes sense to do so, for
example to distinguish empty data from lack of data. It also makes it easy to
override properties (back to the empty) value for specific cases.
Using `bootctl set-default @current` will set the default loader entry
to the currently booted entry as read from the `LoaderEntrySelected` EFI
variable.
Also `bootctl set-oneshot @current` will set the oneshot loader entry to
the current booted entry.
Correspondingly `@default` and `@oneshot` can be used to read from the
LoaderEntryDefault and LoaderEntryOneshot EFI variables.
Previously, .device units generated by SYSTEMD_ALIAS= udev properties
are not supported to specify devices for e.g. 'udevadm info'.
Before:
```
$ udevadm info sys-subsystem-net-devices-enp0s31f6.device
Unknown device "sys-subsystem-net-devices-enp0s31f6.device": No such device
```
After:
```
$ ./udevadm info sys-subsystem-net-devices-enp0s31f6.device
P: /devices/pci0000:00/0000:00:1f.6/net/enp0s31f6
L: 0
E: DEVPATH=/devices/pci0000:00/0000:00:1f.6/net/enp0s31f6
E: INTERFACE=enp0s31f6
E: IFINDEX=2
E: SUBSYSTEM=net
E: USEC_INITIALIZED=25317523
E: ID_NET_NAMING_SCHEME=v245
(snip)
```
By making them unsigned comparing them with other sizes is less likely
to trigger compiler warnings regarding signed/unsigned comparisons.
After all sizes (i.e. size_t) are generally assumed to be unsigned, so
these should be too.
Prompted-by: https://github.com/systemd/systemd/pull/17345#issuecomment-709402332
`route_get()` compares input with existing routes, however previously,
the input may did not have information about gateway. So, the
comparison result might be incorrect, and the foregoing set_put() might
return -EEXIST.
With the switch from log_debug() to log_debug_errno() in commit c413bb28df
systemd-update-done would fail without any error message if /etc
or /var were read-only. This restores the previous behaviour to
silently ignore these directories again.
sync() before committing a transient machine-id to disk. This will
ensure that any filesystem changes made by first-boot units will have
been persisted before the first boot is marked as completed.
Currently, a loss of power after the machine-id was written but before
all units with ConditionFirstBoot=yes ran would lead to the next boot
finding a valid machine-id, thus not being marked first boot and not
re-running these units.
To make the first boot mechanism more robust, instead of writing
/etc/machine-id very early, fill it with a marker value "uninitialized"
and overmount it with a transiently provisioned machine-id. Then, after
the first boots completes (when systemd-machine-id-commit.service runs),
write the real machine-id to disk.
This mechanism is of course only invoked on first boot. If a first boot
is not detected, the machine-id is handled as previously.
Fixes: #4511
If the first boot was aborted, /etc/machine-id might read as
"uninitialized" in some cases. Add a separate case for this
instead of printing a confusing error message.
When systemd-repart runs from initramfs, it reads out /etc/machine-id
from the rootfs as a seed for partition UUIDs. However, the machine-id
could be in an "uninitialized" state from a previous failed first boot.
In this situation the -ENOMEDIUM code-path (no machine-id set) should be
taken.
When nspawn starts an image, this image could be in any state, including
an aborted first boot. For this case, it needs to correctly handle the
situation like there was no machine-id at all.
Add a new ID128_PLAIN_OR_UNINIT format which treats the string
"uninitialized" like the file was empty and return -ENOMEDIUM. This
format should be used when reading an /etc/machine-id file from an image
that is not currently running.
p itself is never null. Because of this, we would always
call sd_notify() in cleanup, even though the intention was to only
call it if notify_start() was executed.
When /etc/machine-id contains the string "uninitialized" instead of
a valid machine-id, treat this like the file was missing and mark this
boot as the first (-> units with ConditionFirstBoot=yes will run).
Negative value means there is no match between a PCI device and any of
the slots. In the following commit we will extend this and value of 0
will indicate that there is a match between some slot and PCI device,
but that device is a PCI bridge.
let's add informational logging about each client requested signal
sending. While we are at, let's beef up error handling/log messages in
this case quite a bit: let's log errors both to syslog and report errors
back to client.
Fixes: #17254
--kill-who=main-fail never worked correctly, due to a copy and paste
mistake in ac5e3a505e, where the same item
was listed twice. The mistake was
later noticed, but fixed incorrectly, in
201f0c916d.
Let's list all *-fail types correctly, finally.
And while we are at it, add a nice comment and generate a prettier D-Bus
error about this.
Let's mark the whole /run/host hierarchy as something to ignore by PID 1
for generation of .mount units, i.e. consider it as "extrinsic".
By unifying container mgr supplied resources in one dir it's also easy
to exclude the whole lot from PID1's management inside the container.
This is the right thing to do, since from the payload's PoV these mounts
are just API and not manipulatable as they are established, managed and
owned by the container manager, not the payload.
(While we are it, also add the boot ID mount to the existing list, as
nspawn and other container managers overmount that too, typically, and
it is thus owned by the container manager and not the payload
typically.)
I can't think of any real vulnerability about this, but it still feels
better to check a variable with "secure" in its name with
secure_getenv() rather than plain getenv().
Paranoia FTW!
This might fix#17025:
> the call trace is
> bus_ensure_running -> sd_bus_process -> bus_process_internal -> process_closeing --> sd_bus_close
> |
> \-> process_match
We ended doing callouts to the Disconnected matches from bus_ensure_running()
and shouldn't. bus_ensure_running() should never do callouts. This change
should fix this however: once we notice that the connection is going down we
will now fail instantly with ENOTOCONN instead of calling any callbacks.
This should not change any behavior, as currently link_free_engines() is
always called after all addresses are dropped. But the function may be
used in other places in the future. So, let's also stop the clients.
Before this commit, event when Gateway=_dhcp4 or _ra is set, the
route was configured with 'protocol static', and other properties
specified by RouteTable=, RouteMTU=, or etc, were ignored.
This commit makes set the route protocol based on the protocol the
gateway address is obtained, and apply other settings if it is not
explicitly specified in the [Route] section.
bootctl implements three types of operation: those that work with an EFI
boot loader, those which work with any EFI boot loader that implements
the boot loader spec + interface, and finally those specific to sd-boot.
Previously the --help text and the man page mixed them all up. Let's put
them clearly in three separate sections however, to communicate clearly
what is supposed to work everywhere, and what is specific to
systemd-boot or boot loaders implementing the two specs.
This adjusts wording here and there, but is mostly just about
re-ordering existing docs, and putting them under new sections.
We would return ENOENT, which is extremely confusing. Strace is not helpful because
no *file* is actually missing. So let's add some logs at debug level and also use
a custom return code. Let all user-facing utilities print a custom error message
in that case.
When connection to the bus fails it can be mighty hard to figure out
what went wrong because we have many different connection mechanisms and
we don't log what is happenning.
The function link_acquire_conf() may make the link state 'configuring'
when DHCP6 PD is enabled. Previously link_acquire_conf() was called
before link_enter_join_netdev(), and thus the assertion in the function
might be triggered.
Fixes#17329.
This updates the "systemd-analyze syscall-filter" command to show a
special section of syscalls that are included in @known but in no other
group. Typically this should show syscalls we either should add to any
of the existing groups or where we unsure were they best fit in.
Right now, it mostly shows arch-specific compat syscalls, we probably
should move "@obsolete". This patch doesn't add thta however.
The variable is renamed to SYSTEMD_PAGERSECURE (because it's not just about
less now), and we automatically enable secure mode in certain cases, but not
otherwise.
This approach is more nuanced, but should provide a better experience for
users:
- Previusly we would set LESSSECURE=1 and trust the pager to make use of
it. But this has an effect only on less. We need to not start pagers which
are insecure when in secure mode. In particular more is like that and is a
very popular pager.
- We don't enable secure mode always, which means that those other pagers can
reasonably used.
- We do the right thing by default, but the user has ultimate control by
setting SYSTEMD_PAGERSECURE.
Fixes#5666.
v2:
- also check $PKEXEC_UID
v3:
- use 'sd_pid_get_owner_uid() != geteuid()' as the condition
A long time some function only worked when in a session, and the test
didn't execute them when sd_pid_get_session() failed. Let's always call
them to increase coverage.
While at it, let's test for ==0 not >=0 where we don't expect the function
to return anything except 0 or error.
When peer address is set, address_compare_func() (or address_equal())
does not work in link_is_static_address_configured(), as an Address object
stored in a Link does not contain peer addresses. So, we need to also
compare with in_addr element for IPv4 case.
Fixes#17304.
When doing import-environment, we shouldn't fail if some assignment is invalid.
OTOH, if the invalid assignment is specified as a positional argument, we should
keep failing.
This would also fix https://bugzilla.redhat.com/show_bug.cgi?id=1754395, by
ignoring certain variables which are not important in that scenario. It seems
like the right thing to do in general.
There was some confusion about what POSIX says about variable names:
names shall not contain the character '='. For values to be portable
across systems conforming to POSIX.1-2008, the value shall be composed
of characters from the portable character set (except NUL and as
indicated below).
i.e. it allows almost all ASCII in variable names (without NUL and DEL and
'='). OTOH, it says that *utilities* use a smaller set of characters:
Environment variable names used by the utilities in the Shell and
Utilities volume of POSIX.1-2008 consist solely of uppercase letters,
digits, and the <underscore> ( '_' ) from the characters defined in
Portable Character Set and do not begin with a digit.
When enforcing variable names in environment blocks, we need to use this
first definition, so that we can propagate all valid variables.
I think having non-printable characters in variable names is too much, so
I took out the whitespace stuff from the first definition.
OTOH, when we use *shell syntax*, for example doing variable expansion,
it seems enough to support expansion of variables that the shell would allow.
Fixes#14878,
https://bugzilla.redhat.com/show_bug.cgi?id=1754395,
https://bugzilla.redhat.com/show_bug.cgi?id=1879216.