Compare commits
26 Commits
fae403f1dc
...
1294661381
Author | SHA1 | Date |
---|---|---|
Yu Watanabe | 1294661381 | |
Zbigniew Jędrzejewski-Szmek | c450335bf7 | |
Zbigniew Jędrzejewski-Szmek | 384db814ee | |
Zbigniew Jędrzejewski-Szmek | 901d1ce8ef | |
Zbigniew Jędrzejewski-Szmek | 573e58f62f | |
Zbigniew Jędrzejewski-Szmek | ea0d0ede03 | |
Zbigniew Jędrzejewski-Szmek | 239bf9409d | |
Yu Watanabe | f05c0615f4 | |
Frantisek Sumsal | 9569e38503 | |
Zbigniew Jędrzejewski-Szmek | f2394ddb08 | |
Zbigniew Jędrzejewski-Szmek | 69f173477b | |
Zbigniew Jędrzejewski-Szmek | 823b035271 | |
Zbigniew Jędrzejewski-Szmek | 2ad988896c | |
Yu Watanabe | 641aa41200 | |
Zbigniew Jędrzejewski-Szmek | bc130b6858 | |
Lennart Poettering | 5c11632735 | |
Lennart Poettering | 6374862615 | |
Lennart Poettering | 1068447e69 | |
Lennart Poettering | f4425c72c7 | |
Lennart Poettering | 7f56982289 | |
Lennart Poettering | 95f82ae9d7 | |
Lennart Poettering | 773b1a7916 | |
Zbigniew Jędrzejewski-Szmek | 6bdd90fbcd | |
Zbigniew Jędrzejewski-Szmek | 8e92d92fb8 | |
Daan De Meyer | 5cbaf95ee3 | |
Daan De Meyer | 75cd4a5d92 |
|
@ -1 +1 @@
|
||||||
custom: ['https://spi-inc.org/projects/systemd/', 'https://www.paypal.com/donate/?token=fBGzXDOyIGobZH3oEhYQlYlA61OMRXVnF9XXQqNNehRs-nliAU5XxozIh9z-hlmE-xXC-m']
|
custom: ['https://spi-inc.org/projects/systemd/']
|
||||||
|
|
267
NEWS
267
NEWS
|
@ -1,31 +1,28 @@
|
||||||
systemd System and Service Manager
|
systemd System and Service Manager
|
||||||
|
|
||||||
CHANGES WITH 245 in spe:
|
CHANGES WITH 245:
|
||||||
|
|
||||||
* A new tool "systemd-repart" has been added, that operates as an
|
* A new tool "systemd-repart" has been added, that operates as an
|
||||||
idempotent, robust, incremental, elastic and declarative
|
idempotent declarative repartitioner for GPT partition tables.
|
||||||
repartitioner. It takes inspiration from
|
Specifically, a set of partitions that must or may exist can be
|
||||||
systemd-tmpfiles/systemd-sysusers but applies the algorithmic
|
configured via drop-in files, and during every boot the partition
|
||||||
concepts to GPT partition tables. Specifically, a set of partitions
|
table on disk is compared with these files, creating missing
|
||||||
that must or may exist can be configured via drop-in files, and
|
partitions or growing existing ones based on configurable relative
|
||||||
during every boot the partition table on disk is compared with these
|
and absolute size constraints. The tool is strictly incremental,
|
||||||
files, creating missing partitions or growing existing ones based on
|
i.e. does not delete, shrink or move partitions, but only adds and
|
||||||
configurable relative and absolute size constraints. The tool is
|
grows them. The primary use-case is OS images that ship in minimized
|
||||||
strictly incremental, i.e. does not delete, shrink or move
|
form, that on first boot are grown to the size of the underlying
|
||||||
partitions, but only adds and grows them. The primary use-case is OS
|
block device or augmented with additional partitions. For example,
|
||||||
images that shall ship in minimized form, with only a minimal boot
|
the root partition could be extended to cover the whole disk, or a
|
||||||
and root partition, that on first boot is grown to the size of the
|
swap or /home partitions could be added on first boot. It can also be
|
||||||
underlying block device or augmented with additional partitions. For
|
used for systems that use an A/B update scheme but ship images with
|
||||||
example, the root partition could be extended to cover the whole
|
just the A partition, with B added on first boot. The tool is
|
||||||
disk, or a swap or /home partitions could be added implicitly on
|
primarily intended to be run in the initrd, shortly before
|
||||||
first boot. It also has uses on systems that use an A/B update scheme
|
transitioning into the host OS, but can also be run after the
|
||||||
to allow shipping minimal images with just the A set of partition,
|
transition took place. It automatically discovers the disk backing
|
||||||
and with the B set added on first boot. The tool is primarily
|
the root file system, and should hence not require any additional
|
||||||
intended to be run in the initrd, shortly before transitioning into
|
configuration besides the partition definition drop-ins. If no
|
||||||
the host OS, but also can be run after the transition took place. It
|
configuration drop-ins are present, no action is taken.
|
||||||
automatically discovers the disk backing the root file system, and
|
|
||||||
should hence not require any additional configuration besides the
|
|
||||||
partition definition drop-ins.
|
|
||||||
|
|
||||||
* A new component "userdb" has been added, along with a small daemon
|
* A new component "userdb" has been added, along with a small daemon
|
||||||
"systemd-userdb.service" and a client tool "userdbctl". The framework
|
"systemd-userdb.service" and a client tool "userdbctl". The framework
|
||||||
|
@ -43,22 +40,21 @@ CHANGES WITH 245 in spe:
|
||||||
that for the first time resource management and various other
|
that for the first time resource management and various other
|
||||||
per-user settings can be configured in LDAP directories and then
|
per-user settings can be configured in LDAP directories and then
|
||||||
provided to systemd (specifically to systemd-logind and pam-system)
|
provided to systemd (specifically to systemd-logind and pam-system)
|
||||||
to enforce on log-in. For further details see:
|
to apply on login. For further details see:
|
||||||
|
|
||||||
https://systemd.io/USER_RECORD
|
https://systemd.io/USER_RECORD
|
||||||
https://systemd.io/GROUP_RECORD
|
https://systemd.io/GROUP_RECORD
|
||||||
https://systemd.io/USER_GROUP_API
|
https://systemd.io/USER_GROUP_API
|
||||||
|
|
||||||
* A small new service systemd-homed.service has been added, that may be
|
* A small new service systemd-homed.service has been added, that may be
|
||||||
used to securely manage home directories, with built-in encryption
|
used to securely manage home directories with built-in encryption.
|
||||||
and unifying the user's own home directory data together with
|
The complete user record data is unified with the home directory,
|
||||||
complete user record data in a single place, thus making home
|
thus making home directories naturally migratable. Its primary
|
||||||
directories naturally migratable. Its primary back-end is based on
|
back-end is based on LUKS volumes, but fscrypt, plain directories,
|
||||||
LUKS volumes, but it also supports fscrypt, plain directories and
|
and other storage schemes are also supported. This solves a couple of
|
||||||
more. It solves a couple of problems we saw with traditional ways to
|
problems we saw with traditional ways to manage home directories, in
|
||||||
manage home directories, in particular when it comes to
|
particular when it comes to encryption. For further discussion of
|
||||||
encryption. For further discussion of this, see the video of
|
this, see the video of Lennart's talk at AllSystemsGo! 2019:
|
||||||
Lennart's talk at AllSystemsGo! 2019:
|
|
||||||
|
|
||||||
https://media.ccc.de/v/ASG2019-164-reinventing-home-directories
|
https://media.ccc.de/v/ASG2019-164-reinventing-home-directories
|
||||||
|
|
||||||
|
@ -69,49 +65,49 @@ CHANGES WITH 245 in spe:
|
||||||
|
|
||||||
* systemd-journald is now multi-instantiable. In addition to the main
|
* systemd-journald is now multi-instantiable. In addition to the main
|
||||||
instance systemd-journald.service there's now a template unit
|
instance systemd-journald.service there's now a template unit
|
||||||
systemd-journald@.service that can be instantiated multiple times,
|
systemd-journald@.service, with each instance defining a new named
|
||||||
each time defining a new named log 'namespace' (whose name is
|
log 'namespace' (whose name is specified via the instance part of the
|
||||||
specified via the instance part of the instance unit name). A new
|
unit name). A new unit file setting LogNamespace= has been added,
|
||||||
unit file setting LogNamespace= has been added, taking such a
|
taking such a namespace name, that assigns services to the specified
|
||||||
namespace name, that allows assigning services to such log
|
log namespaces. As each log namespace is serviced by its own
|
||||||
namespaces. As each log namespace is serviced by its own, independent
|
independent journal daemon, this functionality may be used to improve
|
||||||
journal daemon this functionality may be use to improve performance
|
performance and increase isolation of applications, at the price of
|
||||||
and increase isolation of applications, at the price of losing global
|
losing global message ordering. Each instance of journald has a
|
||||||
message ordering. Each daemon may have a separate set of
|
separate set of configuration files, with possibly different disk
|
||||||
configuration files, with possibly different disk space settings and
|
usage limitations and other settings.
|
||||||
such. journalctl has been updated to take a new option --namespace=
|
|
||||||
which allows viewing logs from a specific log namespace. The
|
journalctl now takes a new option --namespace= to show logs from a
|
||||||
sd-journal.h API gained sd_journal_open_namespace() for opening the
|
specific log namespace. The sd-journal.h API gained
|
||||||
log stream of a specific log namespace. systemd-journald also gained
|
sd_journal_open_namespace() for opening the log stream of a specific
|
||||||
the ability to exit on idle, which is useful in the context of log
|
log namespace. systemd-journald also gained the ability to exit on
|
||||||
namespaces, as this means log daemons for log namespaces can be
|
idle, which is useful in the context of log namespaces, as this means
|
||||||
activated automatically on demand and stop automatically when no
|
log daemons for log namespaces can be activated automatically on
|
||||||
longer used, minimizing resource usage.
|
demand and will stop automatically when no longer used, minimizing
|
||||||
|
resource usage.
|
||||||
|
|
||||||
* When systemd-tmpfiles copies a file tree using the 'C' line type it
|
* When systemd-tmpfiles copies a file tree using the 'C' line type it
|
||||||
will now implicitly label every copied file matching the SELinux
|
will now label every copied file according to the SELinux database.
|
||||||
database.
|
|
||||||
|
|
||||||
* When systemd/PID 1 detects it is used in the initrd it will now boot
|
* When systemd/PID 1 detects it is used in the initrd it will now boot
|
||||||
into initrd.target rather than default.target by default. This should
|
into initrd.target rather than default.target by default. This should
|
||||||
make it simpler to build initrds with systemd as for many cases the
|
make it simpler to build initrds with systemd as for many cases the
|
||||||
only difference between a host OS image and an initrd image now is
|
only difference between a host OS image and an initrd image now is
|
||||||
the /etc/initrd-release file that identifies the initrd as one.
|
the presence of the /etc/initrd-release file.
|
||||||
|
|
||||||
* A new kernel command line option systemd.cpu_affinity= is now
|
* A new kernel command line option systemd.cpu_affinity= is now
|
||||||
understood. It's equivalent to the CPUAffinity= option in
|
understood. It's equivalent to the CPUAffinity= option in
|
||||||
/etc/systemd/system.conf and allows setting the CPU mask for PID 1
|
/etc/systemd/system.conf and allows setting the CPU mask for PID 1
|
||||||
itself and the default for all forked off processes.
|
itself and the default for all other processes.
|
||||||
|
|
||||||
* When systemd/PID 1 is reloaded (with systemctl daemon-reload or an
|
* When systemd/PID 1 is reloaded (with systemctl daemon-reload or
|
||||||
equivalent tool) the SELinux database is now reloaded, ensuring that
|
equivalent), the SELinux database is now reloaded, ensuring that
|
||||||
sockets and other file system objects are generated taking the new
|
sockets and other file system objects are generated taking the new
|
||||||
database into account.
|
database into account.
|
||||||
|
|
||||||
* The sd-event.h API now has native support for the new Linux "pidfd"
|
* The sd-event.h API gained native support for the new Linux "pidfd"
|
||||||
concept. This permits watching processes using file descriptors
|
concept. This permits watching processes using file descriptors
|
||||||
instead of PID numbers, which fixes a number of races and makes
|
instead of PID numbers, which fixes a number of races and makes
|
||||||
process supervision more robust and more efficient. All of systemd's
|
process supervision more robust and efficient. All of systemd's
|
||||||
components will now use pidfds if the kernel supports it for process
|
components will now use pidfds if the kernel supports it for process
|
||||||
watching, with the exception of PID 1 itself, unfortunately. We hope
|
watching, with the exception of PID 1 itself, unfortunately. We hope
|
||||||
to move PID 1 to exclusively using pidfds too eventually, but this
|
to move PID 1 to exclusively using pidfds too eventually, but this
|
||||||
|
@ -122,13 +118,13 @@ CHANGES WITH 245 in spe:
|
||||||
* Closely related to this, the sd-event.h API gained two new calls
|
* Closely related to this, the sd-event.h API gained two new calls
|
||||||
sd_event_source_send_child_signal() (for sending a signal to a
|
sd_event_source_send_child_signal() (for sending a signal to a
|
||||||
watched process) and sd_event_source_get_child_process_own() (for
|
watched process) and sd_event_source_get_child_process_own() (for
|
||||||
marking a process so that it is killed implicitly whenever the event
|
marking a process so that it is killed automatically whenever the
|
||||||
source watching it is freed).
|
event source watching it is freed).
|
||||||
|
|
||||||
* systemd-networkd gained support for configuring Token Bucket Filter
|
* systemd-networkd gained support for configuring Token Bucket Filter
|
||||||
(TBF) parameters in its qdisc configuration support. Similar, support
|
(TBF) parameters in its qdisc configuration support. Similarly,
|
||||||
for Stochastic Fairness Queuing (SFQ), Controlled-Delay Active
|
support for Stochastic Fairness Queuing (SFQ), Controlled-Delay
|
||||||
Queue Management (CoDel), Fair Queueing (FQ) has been added.
|
Active Queue Management (CoDel), and Fair Queue (FQ) has been added.
|
||||||
|
|
||||||
* systemd-networkd gained support for Intermediate Functional Block
|
* systemd-networkd gained support for Intermediate Functional Block
|
||||||
(IFB) network devices.
|
(IFB) network devices.
|
||||||
|
@ -136,40 +132,39 @@ CHANGES WITH 245 in spe:
|
||||||
* systemd-networkd gained support for configuring multi-path IP routes,
|
* systemd-networkd gained support for configuring multi-path IP routes,
|
||||||
using the new MultiPathRoute= setting in the [Route] section.
|
using the new MultiPathRoute= setting in the [Route] section.
|
||||||
|
|
||||||
* systemd-networkd's DHCPv4 support has been updated to support a new
|
* systemd-networkd's DHCPv4 client has been updated to support a new
|
||||||
SendDecline= option. If enabled duplicate address detection is done
|
SendDecline= option. If enabled, duplicate address detection is done
|
||||||
after a DHCP offer is received from a server. If a conflict is
|
after a DHCP offer is received from the server. If a conflict is
|
||||||
detected the address is declined. The DHCPv4 support also gained
|
detected, the address is declined. The DHCPv4 client also gained
|
||||||
support for a new RouteMTUBytes= setting that allows to configure the
|
support for a new RouteMTUBytes= setting that allows to configure the
|
||||||
MTU size to be used for routes generated from DHCPv4 leases.
|
MTU size to be used for routes generated from DHCPv4 leases.
|
||||||
|
|
||||||
* The PrefixRoute= setting in systemd-networkd's [Address] section of
|
* The PrefixRoute= setting in systemd-networkd's [Address] section of
|
||||||
.network files has been deprecated, and replaced by AddPrefixRoute=,
|
.network files has been deprecated, and replaced by AddPrefixRoute=,
|
||||||
with it's sense inverted.
|
with its sense inverted.
|
||||||
|
|
||||||
* The Gateway= setting of [Route] sections of .network files gained
|
* The Gateway= setting of [Route] sections of .network files gained
|
||||||
support for a special new value "_dhcp". If set, the configured
|
support for a special new value "_dhcp". If set, the configured
|
||||||
static route uses the gateway host configured via DHCP.
|
static route uses the gateway host configured via DHCP.
|
||||||
|
|
||||||
* A new User= setting has been implemented for the [RoutingPolicyRule]
|
* New User= and SuppressPrefixLength= settings have been implemented
|
||||||
section of .network files for configuring source routing based on UID
|
for the [RoutingPolicyRule] section of .network files to configure
|
||||||
ranges.
|
source routing based on UID ranges and prefix length, respectively.
|
||||||
|
|
||||||
* sd-bus gained a new API call sd_bus_message_sensitive() for marking a
|
* sd-bus gained a new API call sd_bus_message_sensitive() that marks a
|
||||||
D-Bus message object as "sensitive". Objects that are marked that way
|
D-Bus message object as "sensitive". Those objects are erased from
|
||||||
are erased from memory when they are freed. This concept is intended
|
memory when they are freed. This concept is intended to be used for
|
||||||
to be used for messages that contain security sensitive data that
|
messages that contain security sensitive data. A new flag
|
||||||
should be erased after use. A new flag SD_BUS_VTABLE_SENSITIVE has
|
SD_BUS_VTABLE_SENSITIVE has been introduced as well to mark methods
|
||||||
been introduced as well that allows marking method calls in sd-bus
|
in sd-bus vtables, causing any incoming and outgoing messages of
|
||||||
vtables like this, so that this new message flag is implicitly set
|
those methods to be implicitly marked as "sensitive".
|
||||||
for incoming and outgoing messages of specific methods.
|
|
||||||
|
|
||||||
* sd-bus gained a new API call sd_bus_message_dump() for dumping the
|
* sd-bus gained a new API call sd_bus_message_dump() for dumping the
|
||||||
contents of a message (or parts thereof) onto standard output, for
|
contents of a message (or parts thereof) to standard output for
|
||||||
debugging purposes.
|
debugging purposes.
|
||||||
|
|
||||||
* systemd-sysusers gained support for creating users with primary
|
* systemd-sysusers gained support for creating users with the primary
|
||||||
groups named differently than the user itself.
|
group named differently than the user.
|
||||||
|
|
||||||
* systemd-resolved's DNS-over-TLS support gained SNI validation.
|
* systemd-resolved's DNS-over-TLS support gained SNI validation.
|
||||||
|
|
||||||
|
@ -178,13 +173,13 @@ CHANGES WITH 245 in spe:
|
||||||
only ext4 and btrfs partitions.
|
only ext4 and btrfs partitions.
|
||||||
|
|
||||||
* The support for /etc/crypttab gained a new x-initrd.attach option. If
|
* The support for /etc/crypttab gained a new x-initrd.attach option. If
|
||||||
set the specified encrypted volume is unlocked in the initrd
|
set, the specified encrypted volume is unlocked already in the
|
||||||
already. This concept corresponds to the x-initrd.mount option in
|
initrd. This concept corresponds to the x-initrd.mount option in
|
||||||
/etc/fstab.
|
/etc/fstab.
|
||||||
|
|
||||||
* systemd-cryptsetup gained native support for unlocking encrypted
|
* systemd-cryptsetup gained native support for unlocking encrypted
|
||||||
volumes utilizing PKCS#11 smartcards, i.e. for example to bind
|
volumes utilizing PKCS#11 smartcards, i.e. for example to bind
|
||||||
encryption of volumes to YubiKeys.This is exposed in the new
|
encryption of volumes to YubiKeys. This is exposed in the new
|
||||||
pkcs11-uri= option in /etc/crypttab.
|
pkcs11-uri= option in /etc/crypttab.
|
||||||
|
|
||||||
* The /etc/fstab support in systemd now supports two new mount options
|
* The /etc/fstab support in systemd now supports two new mount options
|
||||||
|
@ -194,42 +189,41 @@ CHANGES WITH 245 in spe:
|
||||||
|
|
||||||
* The https://systemd.io/ web site has been relaunched, directly
|
* The https://systemd.io/ web site has been relaunched, directly
|
||||||
populated with most of the documentation included in the systemd
|
populated with most of the documentation included in the systemd
|
||||||
repository. In particular, systemd acquired a new logo, thanks to
|
repository. systemd also acquired a new logo, thanks to Tobias
|
||||||
Tobias Bernard.
|
Bernard.
|
||||||
|
|
||||||
* systemd-udevd gained support for managing "alternative" network
|
* systemd-udevd gained support for managing "alternative" network
|
||||||
interface names, as supported by new Linux kernels. For the first
|
interface names, as supported by new Linux kernels. For the first
|
||||||
time this permits assigning multiple (and longer!) names to a network
|
time this permits assigning multiple (and longer!) names to a network
|
||||||
interface. systemd-udevd will now by default assign the names
|
interface. systemd-udevd will now by default assign the names
|
||||||
generated via all supported naming schemes to each interface in
|
generated via all supported naming schemes to each interface. This
|
||||||
parallel. This may be further tweaked with .link drop-in files, and
|
may be further tweaked with .link files and the AlternativeName= and
|
||||||
the AlternativeName= and AlternativeNamesPolicy= settings. All other
|
AlternativeNamesPolicy= settings. Other components of systemd have
|
||||||
components of systemd have been updated to support the new
|
been updated to support the new alternative names wherever
|
||||||
alternative names too, wherever that is appropriate. For example,
|
appropriate. For example, systemd-nspawn will now generate
|
||||||
systemd-nspawn will now generate alternative interface names for the
|
alternative interface names for the host-facing side of container
|
||||||
host-facing side of container veth links based on the full container
|
veth links based on the full container name without truncation.
|
||||||
name without truncation.
|
|
||||||
|
|
||||||
* systemd-nspawn interface naming logic has been updated in another way
|
* systemd-nspawn interface naming logic has been updated in another way
|
||||||
too: if the main interface name (i.e. as opposed to new-style
|
too: if the main interface name (i.e. as opposed to new-style
|
||||||
"alternative" names) is the truncated result of container name a
|
"alternative" names) based on the container name is truncated, a
|
||||||
simple hashing scheme is used that ensures that multiple containers
|
simple hashing scheme is used to give different interface names to
|
||||||
whose name all begin the same are likely resulting in different
|
multiple containers whose names all begin with the same prefix. Since
|
||||||
interface names. Since this changes the primary interface names
|
this changes the primary interface names pointing to containers if
|
||||||
pointing to containers if truncation happens the old scheme may still
|
truncation happens, the old scheme may still be requested by
|
||||||
be requested by selecting a different naming scheme than the v245
|
selecting an older naming scheme, via the net.naming-scheme= kernel
|
||||||
one, via the net.naming-scheme= kernel command line option.
|
command line option.
|
||||||
|
|
||||||
* PrivateUsers= in service files now works in services run by the
|
* PrivateUsers= in service files now works in services run by the
|
||||||
systemd --user per-user instance of the service manager.
|
systemd --user per-user instance of the service manager.
|
||||||
|
|
||||||
* A new per-service sandboxing option ProtectClock= has been added that
|
* A new per-service sandboxing option ProtectClock= has been added that
|
||||||
locks down write access to the system clock. It takes away device
|
locks down write access to the system clock. It takes away device
|
||||||
node access to /dev/rtc as well as the system calls that allow to set
|
node access to /dev/rtc as well as the system calls that set the
|
||||||
the system clock. It also removes the CAP_SYS_TIME and CAP_WAKE_ALARM
|
system clock and the CAP_SYS_TIME and CAP_WAKE_ALARM capabilities.
|
||||||
capabilities. Note that this option does not affect access to
|
Note that this option does not affect access to auxiliary services
|
||||||
auxiliary services that allow changing the clock, for example access
|
that allow changing the clock, for example access to
|
||||||
to systemd-timedated.
|
systemd-timedated.
|
||||||
|
|
||||||
* The systemd-id128 tool gained a new "show" verb for listing or
|
* The systemd-id128 tool gained a new "show" verb for listing or
|
||||||
resolving a number of well-known UUIDs/128bit IDs, currently mostly
|
resolving a number of well-known UUIDs/128bit IDs, currently mostly
|
||||||
|
@ -252,20 +246,54 @@ CHANGES WITH 245 in spe:
|
||||||
* networkctl gained support for showing per-interface logs in its
|
* networkctl gained support for showing per-interface logs in its
|
||||||
"status" output.
|
"status" output.
|
||||||
|
|
||||||
|
* systemd-networkd-wait-online gain support for specifying the maximum
|
||||||
|
operational state to wait for, and to wait for interfaces to
|
||||||
|
disappear.
|
||||||
|
|
||||||
* The [Match] section of .link and .network files now supports a new
|
* The [Match] section of .link and .network files now supports a new
|
||||||
option PermanentMACAddress= which may be used to check against the
|
option PermanentMACAddress= which may be used to check against the
|
||||||
permanent MAC address of a network device even if a randomized MAC
|
permanent MAC address of a network device even if a randomized MAC
|
||||||
address is used.
|
address is used.
|
||||||
|
|
||||||
* systemd-logind will now validate access to the operation for changing
|
* The [TrafficControlQueueingDiscipline] section in .network files has
|
||||||
virtual terminals via a PolicyKit action. By default only users with
|
been renamed to [NetworkEmulator] with the "NetworkEmulator" prefix
|
||||||
at least one session on a local VT will get access to the method call.
|
dropped from the individual setting names.
|
||||||
|
|
||||||
* When systemd sets up PAM sessions that invoked service processes shall
|
* Any .link and .network files that have an empty [Match] section (this
|
||||||
run in, the pam_setcred() API is now invoked, thus permitting PAM
|
also includes empty and commented-out files) will now be
|
||||||
modules to set additional credentials for the processes.
|
rejected. systemd-udev and systemd-networkd started warning about
|
||||||
|
such files in version 243.
|
||||||
|
|
||||||
…
|
* systemd-logind will now validate access to the operation of changing
|
||||||
|
the virtual terminal via a PolicyKit action. By default, only users
|
||||||
|
with at least one session on a local VT are granted permission.
|
||||||
|
|
||||||
|
* When systemd sets up PAM sessions that invoked service processes
|
||||||
|
shall run in, the pam_setcred() API is now invoked, thus permitting
|
||||||
|
PAM modules to set additional credentials for the processes.
|
||||||
|
|
||||||
|
Contributions from: AJ Bagwell, Andreas Rammhold, Anita Zhang, Ansgar
|
||||||
|
Burchardt, Antonio Russo, Arian van Putten, Ashley Davis, Bart Willems,
|
||||||
|
Bastien Nocera, Benjamin Dahlhoff, Charles (Chas) Williams, cheese1,
|
||||||
|
Chris Down, Christian Ehrhardt, Christian Göttsche, cvoinf, Daan De
|
||||||
|
Meyer, Daniele Medri, Daniel Rusek, Daniel Shahaf, dann frazier, Dan
|
||||||
|
Streetman, Dariusz Gadomski, David Michael, Dimitri John Ledkov,
|
||||||
|
Emmanuel Bourg, Evgeny Vereshchagin, ezst036, Felipe Sateler, Filipe
|
||||||
|
Brandenburger, Florian Klink, Franck Bui, Fran Dieguez, Frantisek
|
||||||
|
Sumsal, Greg "GothAck" Miell, Guilhem Lettron, Hans de Goede, HATAYAMA
|
||||||
|
Daisuke, Iain Lane, Jan Alexander Steffens (heftig), Jérémy Rosen, Jin
|
||||||
|
Park, Jun'ichi Nomura, Kai Krakow, Kevin Kuehler, Lennart Poettering,
|
||||||
|
Leonid Bloch, Leonid Evdokimov, lothrond, Luca Boccassi, Michael Biebl,
|
||||||
|
Mike Auty, Mike Gilbert, mtron, nabijaczleweli, Naïm Favier, Paul
|
||||||
|
Davey, Piotr Drąg, Rafa Couto, Raphael, rhn, Robert Scheck, Sascha
|
||||||
|
Dewald, Shengjing Zhu, Slava Kardakov, Spencer Michaels, splantefeve,
|
||||||
|
Stanislav Angelovič, Susant Sahani, Thomas Haller, Thomas Schmitt, Timo
|
||||||
|
Schlüßler, Timo Wilken, Tobias Bernard, Tobias Klauser, Tobias
|
||||||
|
Stoeckmann, Topi Miettinen, WataruMatsuoka, Wieland Hoffmann, Wilhelm
|
||||||
|
Schuster, xduugu, Yong Cong Sin, Yu Watanabe, Zach Smith, Zbigniew
|
||||||
|
Jędrzejewski-Szmek, Zeyu DONG
|
||||||
|
|
||||||
|
– Warsaw, 2020-02-05
|
||||||
|
|
||||||
CHANGES WITH 244:
|
CHANGES WITH 244:
|
||||||
|
|
||||||
|
@ -7181,10 +7209,9 @@ CHANGES WITH 213:
|
||||||
* A new fsck.repair= kernel option has been added to control
|
* A new fsck.repair= kernel option has been added to control
|
||||||
how fsck shall deal with unclean file systems at boot.
|
how fsck shall deal with unclean file systems at boot.
|
||||||
|
|
||||||
* The (.ini) configuration file parser will now silently
|
* The (.ini) configuration file parser will now silently ignore
|
||||||
ignore sections whose name begins with "X-". This may be
|
sections whose names begin with "X-". This may be used to maintain
|
||||||
used to maintain application-specific extension sections in unit
|
application-specific extension sections in unit files.
|
||||||
files.
|
|
||||||
|
|
||||||
* machined gained a new API to query the IP addresses of
|
* machined gained a new API to query the IP addresses of
|
||||||
registered containers. "machinectl status" has been updated
|
registered containers. "machinectl status" has been updated
|
||||||
|
|
2
TODO
2
TODO
|
@ -328,7 +328,7 @@ Features:
|
||||||
|
|
||||||
* the a-posteriori stopping of units bound to units that disappeared logic
|
* the a-posteriori stopping of units bound to units that disappeared logic
|
||||||
should be reworked: there should be a queue of units, and we should only
|
should be reworked: there should be a queue of units, and we should only
|
||||||
enqeue stop jobs from a defer event that processes queue instead of
|
enqueue stop jobs from a defer event that processes queue instead of
|
||||||
right-away when we find a unit that is bound to one that doesn't exist
|
right-away when we find a unit that is bound to one that doesn't exist
|
||||||
anymore. (similar to how the stop-unneeded queue has been reworked the same
|
anymore. (similar to how the stop-unneeded queue has been reworked the same
|
||||||
way)
|
way)
|
||||||
|
|
|
@ -69,6 +69,12 @@
|
||||||
|
|
||||||
<para>The operational status is one of the following:
|
<para>The operational status is one of the following:
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>missing</term>
|
||||||
|
<listitem>
|
||||||
|
<para>the device is missing</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>off</term>
|
<term>off</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -195,6 +195,7 @@ manpages = [
|
||||||
'sd_bus_open_user_with_description',
|
'sd_bus_open_user_with_description',
|
||||||
'sd_bus_open_with_description'],
|
'sd_bus_open_with_description'],
|
||||||
''],
|
''],
|
||||||
|
['sd_bus_enqueue_for_read', '3', [], ''],
|
||||||
['sd_bus_error',
|
['sd_bus_error',
|
||||||
'3',
|
'3',
|
||||||
['SD_BUS_ERROR_MAKE_CONST',
|
['SD_BUS_ERROR_MAKE_CONST',
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
<!-- SPDX-License-Identifier: LGPL-2.1+ -->
|
||||||
|
|
||||||
|
<refentry id="sd_bus_enqueue_for_read"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd_bus_enqueue_for_read</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd_bus_enqueue_for_read</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd_bus_enqueue_for_read</refname>
|
||||||
|
|
||||||
|
<refpurpose>Re-enqueue a bus message on a bus connection, for reading.</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_bus_enqueue_for_read</function></funcdef>
|
||||||
|
<paramdef>sd_bus *<parameter>bus</parameter></paramdef>
|
||||||
|
<paramdef>sd_bus_message *<parameter>message</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><function>sd_bus_enqueue_for_read()</function> may be used to re-enqueue an incoming bus message on
|
||||||
|
the local read queue, so that it is processed and dispatched locally again, similar to how an incoming
|
||||||
|
message from the peer is processed. Takes a bus connection object and the message to enqueue. A reference
|
||||||
|
is taken of the message and the caller's reference thus remains in possession of the caller. The message
|
||||||
|
is enqueued at the end of the queue, thus will be dispatched after all other already queued messages are
|
||||||
|
dispatched.</para>
|
||||||
|
|
||||||
|
<para>This call is primarily useful for dealing with incoming method calls that may be processed only
|
||||||
|
after an additional asynchronous operation completes. One example are PolicyKit authorization requests
|
||||||
|
that are determined to be necessary to authorize a newly incoming method call: when the PolicyKit response
|
||||||
|
is received the original method call may be re-enqueued to process it again, this time with the
|
||||||
|
authorization result known.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>On success, this function return 0 or a positive integer. On failure, it returns a negative errno-style
|
||||||
|
error code.</para>
|
||||||
|
|
||||||
|
<refsect2>
|
||||||
|
<title>Errors</title>
|
||||||
|
|
||||||
|
<para>Returned errors may indicate the following problems:</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><constant>-ECHILD</constant></term>
|
||||||
|
|
||||||
|
<listitem><para>The bus connection has been created in a different process.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect2>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<xi:include href="libsystemd-pkgconfig.xml" />
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
|
@ -47,16 +47,16 @@
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-i</option> <replaceable>INTERFACE</replaceable><optional>:<replaceable>OPERSTATE</replaceable></optional></term>
|
<term><option>-i</option> <replaceable>INTERFACE</replaceable><optional>:<replaceable>MIN_OPERSTATE</replaceable><optional>:<replaceable>MAX_OPERSTATE</replaceable></optional></optional></term>
|
||||||
<term><option>--interface=</option><replaceable>INTERFACE</replaceable><optional>:<replaceable>OPERSTATE</replaceable></optional></term>
|
<term><option>--interface=</option><replaceable>INTERFACE</replaceable><optional>:<replaceable>MIN_OPERSTATE</replaceable><optional>:<replaceable>MAX_OPERSTATE</replaceable></optional></optional></term>
|
||||||
|
|
||||||
<listitem><para>Network interface to wait for before deciding if the system is online. This
|
<listitem><para>Network interface to wait for before deciding if the system is online. This
|
||||||
is useful when a system has several interfaces which will be configured, but a particular
|
is useful when a system has several interfaces which will be configured, but a particular
|
||||||
one is necessary to access some network resources. When used, all other interfaces are ignored.
|
one is necessary to access some network resources. When used, all other interfaces are ignored.
|
||||||
This option may be used more than once to wait for multiple network interfaces. When this
|
This option may be used more than once to wait for multiple network interfaces. When this
|
||||||
option is specified multiple times, then <command>systemd-networkd-wait-online</command> waits
|
option is specified multiple times, then <command>systemd-networkd-wait-online</command> waits
|
||||||
for all specified interfaces to be online. Optionally, required minimum operational state can be
|
for all specified interfaces to be online. Optionally, required minimum and maximum operational
|
||||||
specified after a colon <literal>:</literal>. Please see
|
states can be specified after a colon <literal>:</literal>. Please see
|
||||||
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
for possible operational states. If the operational state is not specified here, then
|
for possible operational states. If the operational state is not specified here, then
|
||||||
the value from <varname>RequiredForOnline=</varname> in the corresponding
|
the value from <varname>RequiredForOnline=</varname> in the corresponding
|
||||||
|
@ -74,11 +74,11 @@
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-o</option> <replaceable>OPERSTATE</replaceable></term>
|
<term><option>-o</option> <replaceable>MIN_OPERSTATE</replaceable><optional>:<replaceable>MAX_OPERSTATE</replaceable></optional></term>
|
||||||
<term><option>--operational-state=</option><replaceable>OPERSTATE</replaceable></term>
|
<term><option>--operational-state=</option><replaceable>MIN_OPERSTATE</replaceable><optional>:<replaceable>MAX_OPERSTATE</replaceable></optional></term>
|
||||||
|
|
||||||
<listitem><para>Takes an operational state. Please see
|
<listitem><para>Takes a minimum operational state and an optional maximum operational state.
|
||||||
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
Please see <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
for possible operational states. If set, the specified value overrides
|
for possible operational states. If set, the specified value overrides
|
||||||
<varname>RequiredForOnline=</varname> settings in <filename>.network</filename> files.
|
<varname>RequiredForOnline=</varname> settings in <filename>.network</filename> files.
|
||||||
But this does not override operational states specified in <option>--interface=</option> option.
|
But this does not override operational states specified in <option>--interface=</option> option.
|
||||||
|
|
|
@ -206,13 +206,14 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>RequiredForOnline=</varname></term>
|
<term><varname>RequiredForOnline=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Takes a boolean or operational state. Please see
|
<para>Takes a boolean or a minimum operational state and an optional maximum operational state.
|
||||||
<citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
Please see <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
for possible operational states. When <literal>yes</literal>, the network is deemed required when
|
for possible operational states. When <literal>yes</literal>, the network is deemed required when
|
||||||
determining whether the system is online when running
|
determining whether the system is online when running
|
||||||
<command>systemd-networkd-wait-online</command>. When <literal>no</literal>, the network is ignored
|
<command>systemd-networkd-wait-online</command>. When <literal>no</literal>, the network is ignored
|
||||||
when checking for online state. When an operational state is set, <literal>yes</literal> is implied,
|
when checking for online state. When a minimum operational state and an optional maximum operational
|
||||||
and this controls the operational state required for the network interface to be considered online.
|
state are set, <literal>yes</literal> is implied, and this controls the minimum and maximum
|
||||||
|
operational state required for the network interface to be considered online.
|
||||||
Defaults to <literal>yes</literal>.</para>
|
Defaults to <literal>yes</literal>.</para>
|
||||||
|
|
||||||
<para>The network will be brought up normally in all cases, but in
|
<para>The network will be brought up normally in all cases, but in
|
||||||
|
|
|
@ -848,20 +848,19 @@
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><filename>blockdev@.target</filename></term>
|
<term><filename>blockdev@.target</filename></term>
|
||||||
<listitem><para>This template unit may be used to order mount units and other consumers of block
|
<listitem><para>This template unit is used to order mount units and other consumers of block
|
||||||
devices against services that synthesize these block devices. This is intended to be used to order
|
devices after services that synthesize these block devices. In particular, this is intended to be
|
||||||
storage services (such as
|
used with storage services (such as
|
||||||
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
|
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
|
||||||
that allocate and manage a virtual block device against mount units and other consumers of
|
that allocate and manage a virtual block device. Storage services are ordered before an instance of
|
||||||
it. Specifically, the storage services are supposed to be orderd before an instance of
|
<filename>blockdev@.target</filename>, and the consumer units after it. The ordering is
|
||||||
<filename>blockdev@.target</filename>, and the mount unit (or other consuming unit, such as a swap
|
particularly relevant during shutdown, as it ensures that the mount is deactivated first and the
|
||||||
unit) after it. The ordering is particular relevant during shutdown, as it ensures that the mount
|
service backing the mount later. The <filename>blockdev@.target</filename> instance should be
|
||||||
is deactivated first and the service backing the mount only deactivated after that completed. The
|
pulled in via a <option>Wants=</option> dependency of the storage daemon and thus generally not be
|
||||||
<filename>blockdev@.target</filename> instance should be pulled in via a <option>Wants=</option>
|
part of any transaction unless a storage daemon is used. The instance name for instances of this
|
||||||
dependency of the storage daemon and thus generally not be part of any transaction unless a storage
|
template unit must be a properly escaped block device node path, e.g.
|
||||||
daemon is used. The instance name for instances of this template unit is supposed to be the
|
<filename>blockdev@dev-mapper-foobar.target</filename> for the storage device
|
||||||
properly escaped bock device node path, e.g. <filename>blockdev@dev-mapper-foobar.target</filename>
|
<filename>/dev/mapper/foobar</filename>.</para></listitem>
|
||||||
for a storage device <filename>/dev/mapper/foobar</filename>.</para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><filename>cryptsetup-pre.target</filename></term>
|
<term><filename>cryptsetup-pre.target</filename></term>
|
||||||
|
|
|
@ -25,6 +25,16 @@
|
||||||
<para><filename>/etc/sysusers.d/*.conf</filename></para>
|
<para><filename>/etc/sysusers.d/*.conf</filename></para>
|
||||||
<para><filename>/run/sysusers.d/*.conf</filename></para>
|
<para><filename>/run/sysusers.d/*.conf</filename></para>
|
||||||
<para><filename>/usr/lib/sysusers.d/*.conf</filename></para>
|
<para><filename>/usr/lib/sysusers.d/*.conf</filename></para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
#Type Name ID GECOS Home directory Shell
|
||||||
|
u user_name uid "User Description" /path/to/shell
|
||||||
|
u user_name uid:gid - -
|
||||||
|
u user_name /file/owned/by/user - -
|
||||||
|
g group_name gid "Group Description"
|
||||||
|
g group_name /file/owned/by/group -
|
||||||
|
m user_name group_name
|
||||||
|
r - lowest-highest</programlisting>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -81,11 +91,13 @@
|
||||||
|
|
||||||
<programlisting>#Type Name ID GECOS Home directory Shell
|
<programlisting>#Type Name ID GECOS Home directory Shell
|
||||||
u httpd 404 "HTTP User"
|
u httpd 404 "HTTP User"
|
||||||
u authd /usr/bin/authd "Authorization user"
|
u _authd /usr/bin/authd "Authorization user"
|
||||||
u postgres - "Postgresql Database" /var/lib/pgsql /usr/libexec/postgresdb
|
u postgres - "Postgresql Database" /var/lib/pgsql /usr/libexec/postgresdb
|
||||||
g input - -
|
g input - -
|
||||||
m authd input
|
m _authd input
|
||||||
u root 0 "Superuser" /root /bin/zsh</programlisting>
|
u root 0 "Superuser" /root /bin/zsh
|
||||||
|
r - 500-900
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
<para>Empty lines and lines beginning with the <literal>#</literal> character are ignored, and may be used for
|
<para>Empty lines and lines beginning with the <literal>#</literal> character are ignored, and may be used for
|
||||||
commenting.</para>
|
commenting.</para>
|
||||||
|
@ -109,7 +121,7 @@ u root 0 "Superuser" /root /bin/zsh</pro
|
||||||
<term><varname>g</varname></term>
|
<term><varname>g</varname></term>
|
||||||
<listitem><para>Create a system group of the specified name
|
<listitem><para>Create a system group of the specified name
|
||||||
should it not exist yet. Note that <varname>u</varname>
|
should it not exist yet. Note that <varname>u</varname>
|
||||||
implicitly create a matching group. The group will be
|
implicitly creates a matching group. The group will be
|
||||||
created with no password set.</para></listitem>
|
created with no password set.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-License-Identifier: LGPL-2.1+
|
# SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
|
||||||
project('systemd', 'c',
|
project('systemd', 'c',
|
||||||
version : '244',
|
version : '245',
|
||||||
license : 'LGPLv2+',
|
license : 'LGPLv2+',
|
||||||
default_options: [
|
default_options: [
|
||||||
'c_std=gnu99',
|
'c_std=gnu99',
|
||||||
|
@ -13,8 +13,8 @@ project('systemd', 'c',
|
||||||
meson_version : '>= 0.46',
|
meson_version : '>= 0.46',
|
||||||
)
|
)
|
||||||
|
|
||||||
libsystemd_version = '0.27.1'
|
libsystemd_version = '0.28.0'
|
||||||
libudev_version = '1.6.16'
|
libudev_version = '1.6.17'
|
||||||
|
|
||||||
# We need the same data in two different formats, ugh!
|
# We need the same data in two different formats, ugh!
|
||||||
# Also, for hysterical reasons, we use different variable
|
# Also, for hysterical reasons, we use different variable
|
||||||
|
|
|
@ -685,6 +685,7 @@ global:
|
||||||
|
|
||||||
LIBSYSTEMD_245 {
|
LIBSYSTEMD_245 {
|
||||||
global:
|
global:
|
||||||
|
sd_bus_enqueue_for_read;
|
||||||
sd_bus_message_dump;
|
sd_bus_message_dump;
|
||||||
sd_bus_message_sensitive;
|
sd_bus_message_sensitive;
|
||||||
sd_event_add_child_pidfd;
|
sd_event_add_child_pidfd;
|
||||||
|
|
|
@ -4207,3 +4207,27 @@ _public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
|
||||||
|
|
||||||
return bus->close_on_exit;
|
return bus->close_on_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert_return(bus, -EINVAL);
|
||||||
|
assert_return(bus = bus_resolve(bus), -ENOPKG);
|
||||||
|
assert_return(m, -EINVAL);
|
||||||
|
assert_return(m->sealed, -EINVAL);
|
||||||
|
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||||
|
|
||||||
|
if (!BUS_IS_OPEN(bus->state))
|
||||||
|
return -ENOTCONN;
|
||||||
|
|
||||||
|
/* Re-enqueue a message for reading. This is primarily useful for PolicyKit-style authentication,
|
||||||
|
* where we accept a message, then determine we need to interactively authenticate the user, and then
|
||||||
|
* we want to process the message again. */
|
||||||
|
|
||||||
|
r = bus_rqueue_make_room(bus);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ bool network_is_online(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
|
static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
|
||||||
|
[LINK_OPERSTATE_MISSING] = "missing",
|
||||||
[LINK_OPERSTATE_OFF] = "off",
|
[LINK_OPERSTATE_OFF] = "off",
|
||||||
[LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
|
[LINK_OPERSTATE_NO_CARRIER] = "no-carrier",
|
||||||
[LINK_OPERSTATE_DORMANT] = "dormant",
|
[LINK_OPERSTATE_DORMANT] = "dormant",
|
||||||
|
@ -56,3 +57,49 @@ static const char* const link_address_state_table[_LINK_ADDRESS_STATE_MAX] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(link_address_state, LinkAddressState);
|
DEFINE_STRING_TABLE_LOOKUP(link_address_state, LinkAddressState);
|
||||||
|
|
||||||
|
int parse_operational_state_range(const char *str, LinkOperationalStateRange *out) {
|
||||||
|
LinkOperationalStateRange range = { _LINK_OPERSTATE_INVALID, _LINK_OPERSTATE_INVALID };
|
||||||
|
_cleanup_free_ const char *min = NULL;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
assert(str);
|
||||||
|
assert(out);
|
||||||
|
|
||||||
|
p = strchr(str, ':');
|
||||||
|
if (p) {
|
||||||
|
min = strndup(str, p - str);
|
||||||
|
|
||||||
|
if (!isempty(p + 1)) {
|
||||||
|
range.max = link_operstate_from_string(p + 1);
|
||||||
|
if (range.max < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
min = strdup(str);
|
||||||
|
|
||||||
|
if (!min)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (!isempty(min)) {
|
||||||
|
range.min = link_operstate_from_string(min);
|
||||||
|
if (range.min < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fail on empty strings. */
|
||||||
|
if (range.min == _LINK_OPERSTATE_INVALID && range.max == _LINK_OPERSTATE_INVALID)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (range.min == _LINK_OPERSTATE_INVALID)
|
||||||
|
range.min = LINK_OPERSTATE_MISSING;
|
||||||
|
if (range.max == _LINK_OPERSTATE_INVALID)
|
||||||
|
range.max = LINK_OPERSTATE_ROUTABLE;
|
||||||
|
|
||||||
|
if (range.min > range.max)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*out = range;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
bool network_is_online(void);
|
bool network_is_online(void);
|
||||||
|
|
||||||
typedef enum LinkOperationalState {
|
typedef enum LinkOperationalState {
|
||||||
|
LINK_OPERSTATE_MISSING,
|
||||||
LINK_OPERSTATE_OFF,
|
LINK_OPERSTATE_OFF,
|
||||||
LINK_OPERSTATE_NO_CARRIER,
|
LINK_OPERSTATE_NO_CARRIER,
|
||||||
LINK_OPERSTATE_DORMANT,
|
LINK_OPERSTATE_DORMANT,
|
||||||
|
@ -47,3 +48,13 @@ LinkCarrierState link_carrier_state_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
const char* link_address_state_to_string(LinkAddressState s) _const_;
|
const char* link_address_state_to_string(LinkAddressState s) _const_;
|
||||||
LinkAddressState link_address_state_from_string(const char *s) _pure_;
|
LinkAddressState link_address_state_from_string(const char *s) _pure_;
|
||||||
|
|
||||||
|
typedef struct LinkOperationalStateRange {
|
||||||
|
LinkOperationalState min;
|
||||||
|
LinkOperationalState max;
|
||||||
|
} LinkOperationalStateRange;
|
||||||
|
|
||||||
|
#define LINK_OPERSTATE_RANGE_DEFAULT (LinkOperationalStateRange) { LINK_OPERSTATE_DEGRADED, \
|
||||||
|
LINK_OPERSTATE_ROUTABLE }
|
||||||
|
|
||||||
|
int parse_operational_state_range(const char *str, LinkOperationalStateRange *out);
|
||||||
|
|
|
@ -3957,8 +3957,14 @@ int link_save(Link *link) {
|
||||||
fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
|
fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
|
||||||
yes_no(link->network->required_for_online));
|
yes_no(link->network->required_for_online));
|
||||||
|
|
||||||
fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s\n",
|
fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s",
|
||||||
strempty(link_operstate_to_string(link->network->required_operstate_for_online)));
|
strempty(link_operstate_to_string(link->network->required_operstate_for_online.min)));
|
||||||
|
|
||||||
|
if (link->network->required_operstate_for_online.max != LINK_OPERSTATE_RANGE_DEFAULT.max)
|
||||||
|
fprintf(f, ":%s",
|
||||||
|
strempty(link_operstate_to_string(link->network->required_operstate_for_online.max)));
|
||||||
|
|
||||||
|
fprintf(f, "\n");
|
||||||
|
|
||||||
if (link->dhcp6_client) {
|
if (link->dhcp6_client) {
|
||||||
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
|
r = sd_dhcp6_client_get_lease(link->dhcp6_client, &dhcp6_lease);
|
||||||
|
|
|
@ -375,7 +375,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||||
.n_ref = 1,
|
.n_ref = 1,
|
||||||
|
|
||||||
.required_for_online = true,
|
.required_for_online = true,
|
||||||
.required_operstate_for_online = LINK_OPERSTATE_DEGRADED,
|
.required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT,
|
||||||
.dhcp = ADDRESS_FAMILY_NO,
|
.dhcp = ADDRESS_FAMILY_NO,
|
||||||
.dhcp_critical = -1,
|
.dhcp_critical = -1,
|
||||||
.dhcp_use_ntp = true,
|
.dhcp_use_ntp = true,
|
||||||
|
@ -1306,18 +1306,18 @@ int config_parse_required_for_online(
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
Network *network = data;
|
Network *network = data;
|
||||||
LinkOperationalState s;
|
LinkOperationalStateRange range;
|
||||||
bool required = true;
|
bool required = true;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (isempty(rvalue)) {
|
if (isempty(rvalue)) {
|
||||||
network->required_for_online = true;
|
network->required_for_online = true;
|
||||||
network->required_operstate_for_online = LINK_OPERSTATE_DEGRADED;
|
network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = link_operstate_from_string(rvalue);
|
r = parse_operational_state_range(rvalue, &range);
|
||||||
if (s < 0) {
|
if (r < 0) {
|
||||||
r = parse_boolean(rvalue);
|
r = parse_boolean(rvalue);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
@ -1327,11 +1327,11 @@ int config_parse_required_for_online(
|
||||||
}
|
}
|
||||||
|
|
||||||
required = r;
|
required = r;
|
||||||
s = LINK_OPERSTATE_DEGRADED;
|
range = LINK_OPERSTATE_RANGE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
network->required_for_online = required;
|
network->required_for_online = required;
|
||||||
network->required_operstate_for_online = s;
|
network->required_operstate_for_online = range;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,7 +237,7 @@ struct Network {
|
||||||
bool iaid_set;
|
bool iaid_set;
|
||||||
|
|
||||||
bool required_for_online; /* Is this network required to be considered online? */
|
bool required_for_online; /* Is this network required to be considered online? */
|
||||||
LinkOperationalState required_operstate_for_online;
|
LinkOperationalStateRange required_operstate_for_online;
|
||||||
|
|
||||||
LLDPMode lldp_mode; /* LLDP reception */
|
LLDPMode lldp_mode; /* LLDP reception */
|
||||||
LLDPEmit lldp_emit; /* LLDP transmission */
|
LLDPEmit lldp_emit; /* LLDP transmission */
|
||||||
|
|
|
@ -36,7 +36,7 @@ int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) {
|
||||||
.manager = m,
|
.manager = m,
|
||||||
.ifname = TAKE_PTR(n),
|
.ifname = TAKE_PTR(n),
|
||||||
.ifindex = ifindex,
|
.ifindex = ifindex,
|
||||||
.required_operstate = LINK_OPERSTATE_DEGRADED,
|
.required_operstate = LINK_OPERSTATE_RANGE_DEFAULT,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = hashmap_put(m->links_by_name, l->ifname, l);
|
r = hashmap_put(m->links_by_name, l->ifname, l);
|
||||||
|
@ -105,7 +105,6 @@ int link_update_rtnl(Link *l, sd_netlink_message *m) {
|
||||||
|
|
||||||
int link_update_monitor(Link *l) {
|
int link_update_monitor(Link *l) {
|
||||||
_cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *state = NULL;
|
_cleanup_free_ char *operstate = NULL, *required_operstate = NULL, *state = NULL;
|
||||||
LinkOperationalState s;
|
|
||||||
int r, ret = 0;
|
int r, ret = 0;
|
||||||
|
|
||||||
assert(l);
|
assert(l);
|
||||||
|
@ -121,19 +120,21 @@ int link_update_monitor(Link *l) {
|
||||||
r = sd_network_link_get_required_operstate_for_online(l->ifindex, &required_operstate);
|
r = sd_network_link_get_required_operstate_for_online(l->ifindex, &required_operstate);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
ret = log_link_debug_errno(l, r, "Failed to get required operational state, ignoring: %m");
|
ret = log_link_debug_errno(l, r, "Failed to get required operational state, ignoring: %m");
|
||||||
|
else if (isempty(required_operstate))
|
||||||
|
l->required_operstate = LINK_OPERSTATE_RANGE_DEFAULT;
|
||||||
else {
|
else {
|
||||||
s = link_operstate_from_string(required_operstate);
|
r = parse_operational_state_range(required_operstate, &l->required_operstate);
|
||||||
if (s < 0)
|
if (r < 0)
|
||||||
ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
|
ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
|
||||||
"Failed to parse required operational state, ignoring: %m");
|
"Failed to parse required operational state, ignoring: %m");
|
||||||
else
|
|
||||||
l->required_operstate = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_network_link_get_operational_state(l->ifindex, &operstate);
|
r = sd_network_link_get_operational_state(l->ifindex, &operstate);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
ret = log_link_debug_errno(l, r, "Failed to get operational state, ignoring: %m");
|
ret = log_link_debug_errno(l, r, "Failed to get operational state, ignoring: %m");
|
||||||
else {
|
else {
|
||||||
|
LinkOperationalState s;
|
||||||
|
|
||||||
s = link_operstate_from_string(operstate);
|
s = link_operstate_from_string(operstate);
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
|
ret = log_link_debug_errno(l, SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct Link {
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
|
||||||
bool required_for_online;
|
bool required_for_online;
|
||||||
LinkOperationalState required_operstate;
|
LinkOperationalStateRange required_operstate;
|
||||||
LinkOperationalState operational_state;
|
LinkOperationalState operational_state;
|
||||||
char *state;
|
char *state;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,7 @@ static bool manager_ignore_link(Manager *m, Link *link) {
|
||||||
return strv_fnmatch(m->ignore, link->ifname);
|
return strv_fnmatch(m->ignore, link->ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manager_link_is_online(Manager *m, Link *l, LinkOperationalState s) {
|
static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange s) {
|
||||||
/* This returns the following:
|
/* This returns the following:
|
||||||
* -EAGAIN: not processed by udev or networkd
|
* -EAGAIN: not processed by udev or networkd
|
||||||
* 0: operstate is not enough
|
* 0: operstate is not enough
|
||||||
|
@ -46,13 +46,18 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalState s) {
|
||||||
return log_link_debug_errno(l, SYNTHETIC_ERRNO(EAGAIN),
|
return log_link_debug_errno(l, SYNTHETIC_ERRNO(EAGAIN),
|
||||||
"link is being processed by networkd");
|
"link is being processed by networkd");
|
||||||
|
|
||||||
if (s < 0)
|
if (s.min < 0)
|
||||||
s = m->required_operstate >= 0 ? m->required_operstate : l->required_operstate;
|
s.min = m->required_operstate.min >= 0 ? m->required_operstate.min
|
||||||
|
: l->required_operstate.min;
|
||||||
|
|
||||||
if (l->operational_state < s) {
|
if (s.max < 0)
|
||||||
log_link_debug(l, "Operational state '%s' is below '%s'",
|
s.max = m->required_operstate.max >= 0 ? m->required_operstate.max
|
||||||
|
: l->required_operstate.max;
|
||||||
|
|
||||||
|
if (l->operational_state < s.min || l->operational_state > s.max) {
|
||||||
|
log_link_debug(l, "Operational state '%s' is not in range ['%s':'%s']",
|
||||||
link_operstate_to_string(l->operational_state),
|
link_operstate_to_string(l->operational_state),
|
||||||
link_operstate_to_string(s));
|
link_operstate_to_string(s.min), link_operstate_to_string(s.max));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +75,14 @@ bool manager_configured(Manager *m) {
|
||||||
if (!hashmap_isempty(m->interfaces)) {
|
if (!hashmap_isempty(m->interfaces)) {
|
||||||
/* wait for all the links given on the command line to appear */
|
/* wait for all the links given on the command line to appear */
|
||||||
HASHMAP_FOREACH_KEY(p, ifname, m->interfaces, i) {
|
HASHMAP_FOREACH_KEY(p, ifname, m->interfaces, i) {
|
||||||
LinkOperationalState s = PTR_TO_INT(p);
|
LinkOperationalStateRange *range = p;
|
||||||
|
|
||||||
l = hashmap_get(m->links_by_name, ifname);
|
l = hashmap_get(m->links_by_name, ifname);
|
||||||
|
if (!l && range->min == LINK_OPERSTATE_MISSING) {
|
||||||
|
one_ready = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!l) {
|
if (!l) {
|
||||||
log_debug("still waiting for %s", ifname);
|
log_debug("still waiting for %s", ifname);
|
||||||
if (!m->any)
|
if (!m->any)
|
||||||
|
@ -80,7 +90,7 @@ bool manager_configured(Manager *m) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manager_link_is_online(m, l, s) <= 0) {
|
if (manager_link_is_online(m, l, *range) <= 0) {
|
||||||
if (!m->any)
|
if (!m->any)
|
||||||
return false;
|
return false;
|
||||||
continue;
|
continue;
|
||||||
|
@ -102,7 +112,9 @@ bool manager_configured(Manager *m) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = manager_link_is_online(m, l, _LINK_OPERSTATE_INVALID);
|
r = manager_link_is_online(m, l,
|
||||||
|
(LinkOperationalStateRange) { _LINK_OPERSTATE_INVALID,
|
||||||
|
_LINK_OPERSTATE_INVALID });
|
||||||
if (r < 0 && !m->any)
|
if (r < 0 && !m->any)
|
||||||
return false;
|
return false;
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
|
@ -289,7 +301,7 @@ static int manager_network_monitor_listen(Manager *m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||||
LinkOperationalState required_operstate,
|
LinkOperationalStateRange required_operstate,
|
||||||
bool any, usec_t timeout) {
|
bool any, usec_t timeout) {
|
||||||
_cleanup_(manager_freep) Manager *m = NULL;
|
_cleanup_(manager_freep) Manager *m = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct Manager {
|
||||||
Hashmap *interfaces;
|
Hashmap *interfaces;
|
||||||
char **ignore;
|
char **ignore;
|
||||||
|
|
||||||
LinkOperationalState required_operstate;
|
LinkOperationalStateRange required_operstate;
|
||||||
bool any;
|
bool any;
|
||||||
|
|
||||||
sd_netlink *rtnl;
|
sd_netlink *rtnl;
|
||||||
|
@ -34,7 +34,7 @@ struct Manager {
|
||||||
|
|
||||||
void manager_free(Manager *m);
|
void manager_free(Manager *m);
|
||||||
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
int manager_new(Manager **ret, Hashmap *interfaces, char **ignore,
|
||||||
LinkOperationalState required_operstate,
|
LinkOperationalStateRange required_operstate,
|
||||||
bool any, usec_t timeout);
|
bool any, usec_t timeout);
|
||||||
|
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||||
|
|
|
@ -18,10 +18,10 @@ static bool arg_quiet = false;
|
||||||
static usec_t arg_timeout = 120 * USEC_PER_SEC;
|
static usec_t arg_timeout = 120 * USEC_PER_SEC;
|
||||||
static Hashmap *arg_interfaces = NULL;
|
static Hashmap *arg_interfaces = NULL;
|
||||||
static char **arg_ignore = NULL;
|
static char **arg_ignore = NULL;
|
||||||
static LinkOperationalState arg_required_operstate = _LINK_OPERSTATE_INVALID;
|
static LinkOperationalStateRange arg_required_operstate = { _LINK_OPERSTATE_INVALID, _LINK_OPERSTATE_INVALID };
|
||||||
static bool arg_any = false;
|
static bool arg_any = false;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_keyp);
|
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_ignore, strv_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_ignore, strv_freep);
|
||||||
|
|
||||||
static int help(void) {
|
static int help(void) {
|
||||||
|
@ -37,10 +37,10 @@ static int help(void) {
|
||||||
" -h --help Show this help\n"
|
" -h --help Show this help\n"
|
||||||
" --version Print version string\n"
|
" --version Print version string\n"
|
||||||
" -q --quiet Do not show status information\n"
|
" -q --quiet Do not show status information\n"
|
||||||
" -i --interface=INTERFACE[:OPERSTATE]\n"
|
" -i --interface=INTERFACE[:MIN_OPERSTATE[:MAX_OPERSTATE]]\n"
|
||||||
" Block until at least these interfaces have appeared\n"
|
" Block until at least these interfaces have appeared\n"
|
||||||
" --ignore=INTERFACE Don't take these interfaces into account\n"
|
" --ignore=INTERFACE Don't take these interfaces into account\n"
|
||||||
" -o --operational-state=OPERSTATE\n"
|
" -o --operational-state=MIN_OPERSTATE[:MAX_OPERSTATE]\n"
|
||||||
" Required operational state\n"
|
" Required operational state\n"
|
||||||
" --any Wait until at least one of the interfaces is online\n"
|
" --any Wait until at least one of the interfaces is online\n"
|
||||||
" --timeout=SECS Maximum time to wait for network connectivity\n"
|
" --timeout=SECS Maximum time to wait for network connectivity\n"
|
||||||
|
@ -52,28 +52,28 @@ static int help(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_interface_with_operstate(const char *str) {
|
static int parse_interface_with_operstate_range(const char *str) {
|
||||||
_cleanup_free_ char *ifname = NULL;
|
_cleanup_free_ char *ifname = NULL;
|
||||||
LinkOperationalState s;
|
_cleanup_free_ LinkOperationalStateRange *range;
|
||||||
const char *p;
|
const char *p;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(str);
|
assert(str);
|
||||||
|
|
||||||
|
range = new(LinkOperationalStateRange, 1);
|
||||||
|
if (!range)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
p = strchr(str, ':');
|
p = strchr(str, ':');
|
||||||
if (p) {
|
if (p) {
|
||||||
if (isempty(p + 1))
|
r = parse_operational_state_range(p + 1, range);
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
if (r < 0)
|
||||||
"Operational state is empty.");
|
log_error_errno(r, "Invalid operational state range '%s'", p + 1);
|
||||||
|
|
||||||
s = link_operstate_from_string(p + 1);
|
|
||||||
if (s < 0)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Invalid operational state '%s'", p + 1);
|
|
||||||
|
|
||||||
ifname = strndup(optarg, p - optarg);
|
ifname = strndup(optarg, p - optarg);
|
||||||
} else {
|
} else {
|
||||||
s = _LINK_OPERSTATE_INVALID;
|
range->min = _LINK_OPERSTATE_INVALID;
|
||||||
|
range->max = _LINK_OPERSTATE_INVALID;
|
||||||
ifname = strdup(str);
|
ifname = strdup(str);
|
||||||
}
|
}
|
||||||
if (!ifname)
|
if (!ifname)
|
||||||
|
@ -87,7 +87,7 @@ static int parse_interface_with_operstate(const char *str) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = hashmap_put(arg_interfaces, ifname, INT_TO_PTR(s));
|
r = hashmap_put(arg_interfaces, ifname, TAKE_PTR(range));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to store interface name: %m");
|
return log_error_errno(r, "Failed to store interface name: %m");
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
|
@ -140,7 +140,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
return version();
|
return version();
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
r = parse_interface_with_operstate(optarg);
|
r = parse_interface_with_operstate_range(optarg);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
@ -152,14 +152,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o': {
|
case 'o': {
|
||||||
LinkOperationalState s;
|
LinkOperationalStateRange range;
|
||||||
|
|
||||||
s = link_operstate_from_string(optarg);
|
r = parse_operational_state_range(optarg, &range);
|
||||||
if (s < 0)
|
if (r < 0)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(r, "Invalid operational state range '%s'", optarg);
|
||||||
"Invalid operational state '%s'", optarg);
|
|
||||||
|
arg_required_operstate = range;
|
||||||
|
|
||||||
arg_required_operstate = s;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARG_ANY:
|
case ARG_ANY:
|
||||||
|
|
|
@ -30,6 +30,34 @@ static int check_good_user(sd_bus_message *m, uid_t good_user) {
|
||||||
return sender_uid == good_user;
|
return sender_uid == good_user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_POLKIT
|
||||||
|
static int bus_message_append_strv_key_value(
|
||||||
|
sd_bus_message *m,
|
||||||
|
const char **l) {
|
||||||
|
|
||||||
|
const char **k, **v;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
r = sd_bus_message_open_container(m, 'a', "{ss}");
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
STRV_FOREACH_PAIR(k, v, l) {
|
||||||
|
r = sd_bus_message_append(m, "{ss}", *k, *v);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_bus_message_close_container(m);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int bus_test_polkit(
|
int bus_test_polkit(
|
||||||
sd_bus_message *call,
|
sd_bus_message *call,
|
||||||
int capability,
|
int capability,
|
||||||
|
@ -37,7 +65,7 @@ int bus_test_polkit(
|
||||||
const char **details,
|
const char **details,
|
||||||
uid_t good_user,
|
uid_t good_user,
|
||||||
bool *_challenge,
|
bool *_challenge,
|
||||||
sd_bus_error *e) {
|
sd_bus_error *ret_error) {
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -60,7 +88,7 @@ int bus_test_polkit(
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||||
int authorized = false, challenge = false;
|
int authorized = false, challenge = false;
|
||||||
const char *sender, **k, **v;
|
const char *sender;
|
||||||
|
|
||||||
sender = sd_bus_message_get_sender(call);
|
sender = sd_bus_message_get_sender(call);
|
||||||
if (!sender)
|
if (!sender)
|
||||||
|
@ -84,17 +112,7 @@ int bus_test_polkit(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_bus_message_open_container(request, 'a', "{ss}");
|
r = bus_message_append_strv_key_value(request, details);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
STRV_FOREACH_PAIR(k, v, details) {
|
|
||||||
r = sd_bus_message_append(request, "{ss}", *k, *v);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_bus_message_close_container(request);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -102,11 +120,11 @@ int bus_test_polkit(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_bus_call(call->bus, request, 0, e, &reply);
|
r = sd_bus_call(call->bus, request, 0, ret_error, &reply);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
/* Treat no PK available as access denied */
|
/* Treat no PK available as access denied */
|
||||||
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
|
if (sd_bus_error_has_name(ret_error, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
|
||||||
sd_bus_error_free(e);
|
sd_bus_error_free(ret_error);
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,15 +155,17 @@ int bus_test_polkit(
|
||||||
#if ENABLE_POLKIT
|
#if ENABLE_POLKIT
|
||||||
|
|
||||||
typedef struct AsyncPolkitQuery {
|
typedef struct AsyncPolkitQuery {
|
||||||
|
char *action;
|
||||||
|
char **details;
|
||||||
|
|
||||||
sd_bus_message *request, *reply;
|
sd_bus_message *request, *reply;
|
||||||
sd_bus_message_handler_t callback;
|
|
||||||
void *userdata;
|
|
||||||
sd_bus_slot *slot;
|
sd_bus_slot *slot;
|
||||||
|
|
||||||
Hashmap *registry;
|
Hashmap *registry;
|
||||||
|
sd_event_source *defer_event_source;
|
||||||
} AsyncPolkitQuery;
|
} AsyncPolkitQuery;
|
||||||
|
|
||||||
static void async_polkit_query_free(AsyncPolkitQuery *q) {
|
static void async_polkit_query_free(AsyncPolkitQuery *q) {
|
||||||
|
|
||||||
if (!q)
|
if (!q)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -157,32 +177,72 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) {
|
||||||
sd_bus_message_unref(q->request);
|
sd_bus_message_unref(q->request);
|
||||||
sd_bus_message_unref(q->reply);
|
sd_bus_message_unref(q->reply);
|
||||||
|
|
||||||
|
free(q->action);
|
||||||
|
strv_free(q->details);
|
||||||
|
|
||||||
|
sd_event_source_disable_unref(q->defer_event_source);
|
||||||
free(q);
|
free(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int async_polkit_defer(sd_event_source *s, void *userdata) {
|
||||||
|
AsyncPolkitQuery *q = userdata;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
/* This is called as idle event source after we processed the async polkit reply, hopefully after the
|
||||||
|
* method call we re-enqueued has been properly processed. */
|
||||||
|
|
||||||
|
async_polkit_query_free(q);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
|
static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
|
|
||||||
AsyncPolkitQuery *q = userdata;
|
AsyncPolkitQuery *q = userdata;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(reply);
|
assert(reply);
|
||||||
assert(q);
|
assert(q);
|
||||||
|
|
||||||
|
assert(q->slot);
|
||||||
q->slot = sd_bus_slot_unref(q->slot);
|
q->slot = sd_bus_slot_unref(q->slot);
|
||||||
|
|
||||||
|
assert(!q->reply);
|
||||||
q->reply = sd_bus_message_ref(reply);
|
q->reply = sd_bus_message_ref(reply);
|
||||||
|
|
||||||
|
/* Now, let's dispatch the original message a second time be re-enqueing. This will then traverse the
|
||||||
|
* whole message processing again, and thus re-validating and re-retrieving the "userdata" field
|
||||||
|
* again.
|
||||||
|
*
|
||||||
|
* We install an idle event loop event to clean-up the PolicyKit request data when we are idle again,
|
||||||
|
* i.e. after the second time the message is processed is complete. */
|
||||||
|
|
||||||
|
assert(!q->defer_event_source);
|
||||||
|
r = sd_event_add_defer(sd_bus_get_event(sd_bus_message_get_bus(reply)), &q->defer_event_source, async_polkit_defer, q);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
r = sd_event_source_set_priority(q->defer_event_source, SD_EVENT_PRIORITY_IDLE);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
r = sd_event_source_set_enabled(q->defer_event_source, SD_EVENT_ONESHOT);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
r = sd_bus_message_rewind(q->request, true);
|
r = sd_bus_message_rewind(q->request, true);
|
||||||
if (r < 0) {
|
if (r < 0)
|
||||||
r = sd_bus_reply_method_errno(q->request, r, NULL);
|
goto fail;
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = q->callback(q->request, q->userdata, &error_buffer);
|
r = sd_bus_enqueue_for_read(sd_bus_message_get_bus(q->request), q->request);
|
||||||
r = bus_maybe_reply_error(q->request, r, &error_buffer);
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
finish:
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
log_debug_errno(r, "Processing asynchronous PolicyKit reply failed, ignoring: %m");
|
||||||
|
(void) sd_bus_reply_method_errno(q->request, r, NULL);
|
||||||
async_polkit_query_free(q);
|
async_polkit_query_free(q);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,16 +256,14 @@ int bus_verify_polkit_async(
|
||||||
bool interactive,
|
bool interactive,
|
||||||
uid_t good_user,
|
uid_t good_user,
|
||||||
Hashmap **registry,
|
Hashmap **registry,
|
||||||
sd_bus_error *error) {
|
sd_bus_error *ret_error) {
|
||||||
|
|
||||||
#if ENABLE_POLKIT
|
#if ENABLE_POLKIT
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
|
||||||
AsyncPolkitQuery *q;
|
AsyncPolkitQuery *q;
|
||||||
const char *sender, **k, **v;
|
|
||||||
sd_bus_message_handler_t callback;
|
|
||||||
void *userdata;
|
|
||||||
int c;
|
int c;
|
||||||
#endif
|
#endif
|
||||||
|
const char *sender;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(call);
|
assert(call);
|
||||||
|
@ -221,11 +279,17 @@ int bus_verify_polkit_async(
|
||||||
if (q) {
|
if (q) {
|
||||||
int authorized, challenge;
|
int authorized, challenge;
|
||||||
|
|
||||||
/* This is the second invocation of this function, and
|
/* This is the second invocation of this function, and there's already a response from
|
||||||
* there's already a response from polkit, let's
|
* polkit, let's process it */
|
||||||
* process it */
|
|
||||||
assert(q->reply);
|
assert(q->reply);
|
||||||
|
|
||||||
|
/* If the operation we want to authenticate changed between the first and the second time,
|
||||||
|
* let's not use this authentication, it might be out of date as the object and context we
|
||||||
|
* operate on might have changed. */
|
||||||
|
if (!streq(q->action, action) ||
|
||||||
|
!strv_equal(q->details, (char**) details))
|
||||||
|
return -ESTALE;
|
||||||
|
|
||||||
if (sd_bus_message_is_method_error(q->reply, NULL)) {
|
if (sd_bus_message_is_method_error(q->reply, NULL)) {
|
||||||
const sd_bus_error *e;
|
const sd_bus_error *e;
|
||||||
|
|
||||||
|
@ -237,7 +301,7 @@ int bus_verify_polkit_async(
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
/* Copy error from polkit reply */
|
/* Copy error from polkit reply */
|
||||||
sd_bus_error_copy(error, e);
|
sd_bus_error_copy(ret_error, e);
|
||||||
return -sd_bus_error_get_errno(e);
|
return -sd_bus_error_get_errno(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +315,7 @@ int bus_verify_polkit_async(
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (challenge)
|
if (challenge)
|
||||||
return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
|
return sd_bus_error_set(ret_error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
|
||||||
|
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
@ -263,20 +327,11 @@ int bus_verify_polkit_async(
|
||||||
else if (r > 0)
|
else if (r > 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#if ENABLE_POLKIT
|
|
||||||
if (sd_bus_get_current_message(call->bus) != call)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
callback = sd_bus_get_current_handler(call->bus);
|
|
||||||
if (!callback)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
userdata = sd_bus_get_current_userdata(call->bus);
|
|
||||||
|
|
||||||
sender = sd_bus_message_get_sender(call);
|
sender = sd_bus_message_get_sender(call);
|
||||||
if (!sender)
|
if (!sender)
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
|
#if ENABLE_POLKIT
|
||||||
c = sd_bus_message_get_allow_interactive_authorization(call);
|
c = sd_bus_message_get_allow_interactive_authorization(call);
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
return c;
|
return c;
|
||||||
|
@ -305,17 +360,7 @@ int bus_verify_polkit_async(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_bus_message_open_container(pk, 'a', "{ss}");
|
r = bus_message_append_strv_key_value(pk, details);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
STRV_FOREACH_PAIR(k, v, details) {
|
|
||||||
r = sd_bus_message_append(pk, "{ss}", *k, *v);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_bus_message_close_container(pk);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -323,13 +368,25 @@ int bus_verify_polkit_async(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
q = new0(AsyncPolkitQuery, 1);
|
q = new(AsyncPolkitQuery, 1);
|
||||||
if (!q)
|
if (!q)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
q->request = sd_bus_message_ref(call);
|
*q = (AsyncPolkitQuery) {
|
||||||
q->callback = callback;
|
.request = sd_bus_message_ref(call),
|
||||||
q->userdata = userdata;
|
};
|
||||||
|
|
||||||
|
q->action = strdup(action);
|
||||||
|
if (!q->action) {
|
||||||
|
async_polkit_query_free(q);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
q->details = strv_copy((char**) details);
|
||||||
|
if (!q->details) {
|
||||||
|
async_polkit_query_free(q);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
r = hashmap_put(*registry, call, q);
|
r = hashmap_put(*registry, call, q);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
|
|
@ -207,6 +207,7 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r);
|
||||||
int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r);
|
int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r);
|
||||||
int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec);
|
int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec);
|
||||||
int sd_bus_flush(sd_bus *bus);
|
int sd_bus_flush(sd_bus *bus);
|
||||||
|
int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m);
|
||||||
|
|
||||||
sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus);
|
sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus);
|
||||||
sd_bus_message* sd_bus_get_current_message(sd_bus *bus);
|
sd_bus_message* sd_bus_get_current_message(sd_bus *bus);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Description=Test for CapabilityBoundingSet
|
Description=Test for CapabilityBoundingSet
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | grep "^Bounding set .*cap_chown"'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep "^Bounding set .*cap_chown"'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
CapabilityBoundingSet=~CAP_CHOWN
|
CapabilityBoundingSet=~CAP_CHOWN
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=no
|
PrivateDevices=no
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_mknod'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=no
|
PrivateDevices=no
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_rawio'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=yes
|
PrivateDevices=yes
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_mknod'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=yes
|
PrivateDevices=yes
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_rawio'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_SYSLOG for ProtectKernelLogs=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelLogs=no
|
ProtectKernelLogs=no
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_syslog'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_syslog'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_SYSLOG for ProtectKernelLogs=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelLogs=yes
|
ProtectKernelLogs=yes
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_syslog'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_syslog'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_SYS_MODULE ProtectKernelModules=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelModules=no
|
ProtectKernelModules=no
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_module'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,5 +3,6 @@ Description=Test CAP_SYS_MODULE for ProtectKernelModules=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelModules=yes
|
ProtectKernelModules=yes
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_module'
|
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
||||||
|
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module'
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -27,6 +27,7 @@ which_paths=':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(':
|
||||||
|
|
||||||
networkd_bin=shutil.which('systemd-networkd', path=which_paths)
|
networkd_bin=shutil.which('systemd-networkd', path=which_paths)
|
||||||
resolved_bin=shutil.which('systemd-resolved', path=which_paths)
|
resolved_bin=shutil.which('systemd-resolved', path=which_paths)
|
||||||
|
udevd_bin=shutil.which('systemd-udevd', path=which_paths)
|
||||||
wait_online_bin=shutil.which('systemd-networkd-wait-online', path=which_paths)
|
wait_online_bin=shutil.which('systemd-networkd-wait-online', path=which_paths)
|
||||||
networkctl_bin=shutil.which('networkctl', path=which_paths)
|
networkctl_bin=shutil.which('networkctl', path=which_paths)
|
||||||
resolvectl_bin=shutil.which('resolvectl', path=which_paths)
|
resolvectl_bin=shutil.which('resolvectl', path=which_paths)
|
||||||
|
@ -164,7 +165,7 @@ def setUpModule():
|
||||||
shutil.rmtree(networkd_ci_path)
|
shutil.rmtree(networkd_ci_path)
|
||||||
copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
|
copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
|
||||||
|
|
||||||
for u in ['systemd-networkd.socket', 'systemd-networkd.service', 'systemd-resolved.service', 'firewalld.service']:
|
for u in ['systemd-networkd.socket', 'systemd-networkd.service', 'systemd-resolved.service', 'systemd-udevd.service', 'firewalld.service']:
|
||||||
if call(f'systemctl is-active --quiet {u}') == 0:
|
if call(f'systemctl is-active --quiet {u}') == 0:
|
||||||
check_output(f'systemctl stop {u}')
|
check_output(f'systemctl stop {u}')
|
||||||
running_units.append(u)
|
running_units.append(u)
|
||||||
|
@ -226,21 +227,34 @@ def setUpModule():
|
||||||
with open('/run/systemd/system/systemd-resolved.service.d/00-override.conf', mode='w') as f:
|
with open('/run/systemd/system/systemd-resolved.service.d/00-override.conf', mode='w') as f:
|
||||||
f.write('\n'.join(drop_in))
|
f.write('\n'.join(drop_in))
|
||||||
|
|
||||||
|
drop_in = [
|
||||||
|
'[Service]',
|
||||||
|
'ExecStart=',
|
||||||
|
'ExecStart=!!' + udevd_bin,
|
||||||
|
]
|
||||||
|
|
||||||
|
os.makedirs('/run/systemd/system/systemd-udevd.service.d', exist_ok=True)
|
||||||
|
with open('/run/systemd/system/systemd-udevd.service.d/00-override.conf', mode='w') as f:
|
||||||
|
f.write('\n'.join(drop_in))
|
||||||
|
|
||||||
check_output('systemctl daemon-reload')
|
check_output('systemctl daemon-reload')
|
||||||
print(check_output('systemctl cat systemd-networkd.service'))
|
print(check_output('systemctl cat systemd-networkd.service'))
|
||||||
print(check_output('systemctl cat systemd-resolved.service'))
|
print(check_output('systemctl cat systemd-resolved.service'))
|
||||||
|
print(check_output('systemctl cat systemd-udevd.service'))
|
||||||
check_output('systemctl restart systemd-resolved')
|
check_output('systemctl restart systemd-resolved')
|
||||||
|
check_output('systemctl restart systemd-udevd')
|
||||||
|
|
||||||
def tearDownModule():
|
def tearDownModule():
|
||||||
global running_units
|
global running_units
|
||||||
|
|
||||||
shutil.rmtree(networkd_ci_path)
|
shutil.rmtree(networkd_ci_path)
|
||||||
|
|
||||||
for u in ['systemd-networkd.service', 'systemd-resolved.service']:
|
for u in ['systemd-networkd.service', 'systemd-resolved.service', 'systemd-udevd.service']:
|
||||||
check_output(f'systemctl stop {u}')
|
check_output(f'systemctl stop {u}')
|
||||||
|
|
||||||
shutil.rmtree('/run/systemd/system/systemd-networkd.service.d')
|
shutil.rmtree('/run/systemd/system/systemd-networkd.service.d')
|
||||||
shutil.rmtree('/run/systemd/system/systemd-resolved.service.d')
|
shutil.rmtree('/run/systemd/system/systemd-resolved.service.d')
|
||||||
|
shutil.rmtree('/run/systemd/system/systemd-udevd.service.d')
|
||||||
check_output('systemctl daemon-reload')
|
check_output('systemctl daemon-reload')
|
||||||
|
|
||||||
for u in running_units:
|
for u in running_units:
|
||||||
|
@ -3568,6 +3582,7 @@ if __name__ == '__main__':
|
||||||
parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
|
parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
|
||||||
parser.add_argument('--networkd', help='Path to systemd-networkd', dest='networkd_bin')
|
parser.add_argument('--networkd', help='Path to systemd-networkd', dest='networkd_bin')
|
||||||
parser.add_argument('--resolved', help='Path to systemd-resolved', dest='resolved_bin')
|
parser.add_argument('--resolved', help='Path to systemd-resolved', dest='resolved_bin')
|
||||||
|
parser.add_argument('--udevd', help='Path to systemd-udevd', dest='udevd_bin')
|
||||||
parser.add_argument('--wait-online', help='Path to systemd-networkd-wait-online', dest='wait_online_bin')
|
parser.add_argument('--wait-online', help='Path to systemd-networkd-wait-online', dest='wait_online_bin')
|
||||||
parser.add_argument('--networkctl', help='Path to networkctl', dest='networkctl_bin')
|
parser.add_argument('--networkctl', help='Path to networkctl', dest='networkctl_bin')
|
||||||
parser.add_argument('--resolvectl', help='Path to resolvectl', dest='resolvectl_bin')
|
parser.add_argument('--resolvectl', help='Path to resolvectl', dest='resolvectl_bin')
|
||||||
|
@ -3580,10 +3595,11 @@ if __name__ == '__main__':
|
||||||
ns, args = parser.parse_known_args(namespace=unittest)
|
ns, args = parser.parse_known_args(namespace=unittest)
|
||||||
|
|
||||||
if ns.build_dir:
|
if ns.build_dir:
|
||||||
if ns.networkd_bin or ns.resolved_bin or ns.wait_online_bin or ns.networkctl_bin or ns.resolvectl_bin or ns.timedatectl_bin:
|
if ns.networkd_bin or ns.resolved_bin or ns.udevd_bin or ns.wait_online_bin or ns.networkctl_bin or ns.resolvectl_bin or ns.timedatectl_bin:
|
||||||
print('WARNING: --networkd, --resolved, --wait-online, --networkctl, --resolvectl, or --timedatectl options are ignored when --build-dir is specified.')
|
print('WARNING: --networkd, --resolved, --wait-online, --networkctl, --resolvectl, or --timedatectl options are ignored when --build-dir is specified.')
|
||||||
networkd_bin = os.path.join(ns.build_dir, 'systemd-networkd')
|
networkd_bin = os.path.join(ns.build_dir, 'systemd-networkd')
|
||||||
resolved_bin = os.path.join(ns.build_dir, 'systemd-resolved')
|
resolved_bin = os.path.join(ns.build_dir, 'systemd-resolved')
|
||||||
|
udevd_bin = os.path.join(ns.build_dir, 'systemd-udevd')
|
||||||
wait_online_bin = os.path.join(ns.build_dir, 'systemd-networkd-wait-online')
|
wait_online_bin = os.path.join(ns.build_dir, 'systemd-networkd-wait-online')
|
||||||
networkctl_bin = os.path.join(ns.build_dir, 'networkctl')
|
networkctl_bin = os.path.join(ns.build_dir, 'networkctl')
|
||||||
resolvectl_bin = os.path.join(ns.build_dir, 'resolvectl')
|
resolvectl_bin = os.path.join(ns.build_dir, 'resolvectl')
|
||||||
|
@ -3593,6 +3609,8 @@ if __name__ == '__main__':
|
||||||
networkd_bin = ns.networkd_bin
|
networkd_bin = ns.networkd_bin
|
||||||
if ns.resolved_bin:
|
if ns.resolved_bin:
|
||||||
resolved_bin = ns.resolved_bin
|
resolved_bin = ns.resolved_bin
|
||||||
|
if ns.udevd_bin:
|
||||||
|
udevd_bin = ns.udevd_bin
|
||||||
if ns.wait_online_bin:
|
if ns.wait_online_bin:
|
||||||
wait_online_bin = ns.wait_online_bin
|
wait_online_bin = ns.wait_online_bin
|
||||||
if ns.networkctl_bin:
|
if ns.networkctl_bin:
|
||||||
|
|
Loading…
Reference in New Issue