Compare commits
No commits in common. "129466138124f922319dc3bb4647f6392882b86b" and "fae403f1dc2e5ff15ce9096c7ba318a5bd9ee878" have entirely different histories.
1294661381
...
fae403f1dc
|
@ -1 +1 @@
|
||||||
custom: ['https://spi-inc.org/projects/systemd/']
|
custom: ['https://spi-inc.org/projects/systemd/', 'https://www.paypal.com/donate/?token=fBGzXDOyIGobZH3oEhYQlYlA61OMRXVnF9XXQqNNehRs-nliAU5XxozIh9z-hlmE-xXC-m']
|
||||||
|
|
265
NEWS
265
NEWS
|
@ -1,28 +1,31 @@
|
||||||
systemd System and Service Manager
|
systemd System and Service Manager
|
||||||
|
|
||||||
CHANGES WITH 245:
|
CHANGES WITH 245 in spe:
|
||||||
|
|
||||||
* 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 declarative repartitioner for GPT partition tables.
|
idempotent, robust, incremental, elastic and declarative
|
||||||
Specifically, a set of partitions that must or may exist can be
|
repartitioner. It takes inspiration from
|
||||||
configured via drop-in files, and during every boot the partition
|
systemd-tmpfiles/systemd-sysusers but applies the algorithmic
|
||||||
table on disk is compared with these files, creating missing
|
concepts to GPT partition tables. Specifically, a set of partitions
|
||||||
partitions or growing existing ones based on configurable relative
|
that must or may exist can be configured via drop-in files, and
|
||||||
and absolute size constraints. The tool is strictly incremental,
|
during every boot the partition table on disk is compared with these
|
||||||
i.e. does not delete, shrink or move partitions, but only adds and
|
files, creating missing partitions or growing existing ones based on
|
||||||
grows them. The primary use-case is OS images that ship in minimized
|
configurable relative and absolute size constraints. The tool is
|
||||||
form, that on first boot are grown to the size of the underlying
|
strictly incremental, i.e. does not delete, shrink or move
|
||||||
block device or augmented with additional partitions. For example,
|
partitions, but only adds and grows them. The primary use-case is OS
|
||||||
the root partition could be extended to cover the whole disk, or a
|
images that shall ship in minimized form, with only a minimal boot
|
||||||
swap or /home partitions could be added on first boot. It can also be
|
and root partition, that on first boot is grown to the size of the
|
||||||
used for systems that use an A/B update scheme but ship images with
|
underlying block device or augmented with additional partitions. For
|
||||||
just the A partition, with B added on first boot. The tool is
|
example, the root partition could be extended to cover the whole
|
||||||
primarily intended to be run in the initrd, shortly before
|
disk, or a swap or /home partitions could be added implicitly on
|
||||||
transitioning into the host OS, but can also be run after the
|
first boot. It also has uses on systems that use an A/B update scheme
|
||||||
transition took place. It automatically discovers the disk backing
|
to allow shipping minimal images with just the A set of partition,
|
||||||
the root file system, and should hence not require any additional
|
and with the B set added on first boot. The tool is primarily
|
||||||
configuration besides the partition definition drop-ins. If no
|
intended to be run in the initrd, shortly before transitioning into
|
||||||
configuration drop-ins are present, no action is taken.
|
the host OS, but also can be run after the transition took place. It
|
||||||
|
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
|
||||||
|
@ -40,21 +43,22 @@ CHANGES WITH 245:
|
||||||
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 apply on login. For further details see:
|
to enforce on log-in. 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
|
||||||
The complete user record data is unified with the home directory,
|
and unifying the user's own home directory data together with
|
||||||
thus making home directories naturally migratable. Its primary
|
complete user record data in a single place, thus making home
|
||||||
back-end is based on LUKS volumes, but fscrypt, plain directories,
|
directories naturally migratable. Its primary back-end is based on
|
||||||
and other storage schemes are also supported. This solves a couple of
|
LUKS volumes, but it also supports fscrypt, plain directories and
|
||||||
problems we saw with traditional ways to manage home directories, in
|
more. It solves a couple of problems we saw with traditional ways to
|
||||||
particular when it comes to encryption. For further discussion of
|
manage home directories, in particular when it comes to
|
||||||
this, see the video of Lennart's talk at AllSystemsGo! 2019:
|
encryption. For further discussion of this, see the video of
|
||||||
|
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
|
||||||
|
|
||||||
|
@ -65,49 +69,49 @@ CHANGES WITH 245:
|
||||||
|
|
||||||
* 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, with each instance defining a new named
|
systemd-journald@.service that can be instantiated multiple times,
|
||||||
log 'namespace' (whose name is specified via the instance part of the
|
each time defining a new named log 'namespace' (whose name is
|
||||||
unit name). A new unit file setting LogNamespace= has been added,
|
specified via the instance part of the instance unit name). A new
|
||||||
taking such a namespace name, that assigns services to the specified
|
unit file setting LogNamespace= has been added, taking such a
|
||||||
log namespaces. As each log namespace is serviced by its own
|
namespace name, that allows assigning services to such log
|
||||||
independent journal daemon, this functionality may be used to improve
|
namespaces. As each log namespace is serviced by its own, independent
|
||||||
performance and increase isolation of applications, at the price of
|
journal daemon this functionality may be use to improve performance
|
||||||
losing global message ordering. Each instance of journald has a
|
and increase isolation of applications, at the price of losing global
|
||||||
separate set of configuration files, with possibly different disk
|
message ordering. Each daemon may have a separate set of
|
||||||
usage limitations and other settings.
|
configuration files, with possibly different disk space settings and
|
||||||
|
such. journalctl has been updated to take a new option --namespace=
|
||||||
journalctl now takes a new option --namespace= to show logs from a
|
which allows viewing logs from a specific log namespace. The
|
||||||
specific log namespace. The sd-journal.h API gained
|
sd-journal.h API gained sd_journal_open_namespace() for opening the
|
||||||
sd_journal_open_namespace() for opening the log stream of a specific
|
log stream of a specific log namespace. systemd-journald also gained
|
||||||
log namespace. systemd-journald also gained the ability to exit on
|
the ability to exit on idle, which is useful in the context of log
|
||||||
idle, which is useful in the context of log namespaces, as this means
|
namespaces, as this means log daemons for log namespaces can be
|
||||||
log daemons for log namespaces can be activated automatically on
|
activated automatically on demand and stop automatically when no
|
||||||
demand and will stop automatically when no longer used, minimizing
|
longer used, minimizing resource usage.
|
||||||
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 label every copied file according to the SELinux database.
|
will now implicitly label every copied file matching the SELinux
|
||||||
|
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 presence of the /etc/initrd-release file.
|
the /etc/initrd-release file that identifies the initrd as one.
|
||||||
|
|
||||||
* 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 other processes.
|
itself and the default for all forked off processes.
|
||||||
|
|
||||||
* When systemd/PID 1 is reloaded (with systemctl daemon-reload or
|
* When systemd/PID 1 is reloaded (with systemctl daemon-reload or an
|
||||||
equivalent), the SELinux database is now reloaded, ensuring that
|
equivalent tool) 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 gained native support for the new Linux "pidfd"
|
* The sd-event.h API now has 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 efficient. All of systemd's
|
process supervision more robust and more 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
|
||||||
|
@ -118,13 +122,13 @@ CHANGES WITH 245:
|
||||||
* 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 automatically whenever the
|
marking a process so that it is killed implicitly whenever the event
|
||||||
event source watching it is freed).
|
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. Similarly,
|
(TBF) parameters in its qdisc configuration support. Similar, support
|
||||||
support for Stochastic Fairness Queuing (SFQ), Controlled-Delay
|
for Stochastic Fairness Queuing (SFQ), Controlled-Delay Active
|
||||||
Active Queue Management (CoDel), and Fair Queue (FQ) has been added.
|
Queue Management (CoDel), Fair Queueing (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.
|
||||||
|
@ -132,39 +136,40 @@ CHANGES WITH 245:
|
||||||
* 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 client has been updated to support a new
|
* systemd-networkd's DHCPv4 support 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 the server. If a conflict is
|
after a DHCP offer is received from a server. If a conflict is
|
||||||
detected, the address is declined. The DHCPv4 client also gained
|
detected the address is declined. The DHCPv4 support 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 its sense inverted.
|
with it's 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.
|
||||||
|
|
||||||
* New User= and SuppressPrefixLength= settings have been implemented
|
* A new User= setting has been implemented for the [RoutingPolicyRule]
|
||||||
for the [RoutingPolicyRule] section of .network files to configure
|
section of .network files for configuring source routing based on UID
|
||||||
source routing based on UID ranges and prefix length, respectively.
|
ranges.
|
||||||
|
|
||||||
* sd-bus gained a new API call sd_bus_message_sensitive() that marks a
|
* sd-bus gained a new API call sd_bus_message_sensitive() for marking a
|
||||||
D-Bus message object as "sensitive". Those objects are erased from
|
D-Bus message object as "sensitive". Objects that are marked that way
|
||||||
memory when they are freed. This concept is intended to be used for
|
are erased from memory when they are freed. This concept is intended
|
||||||
messages that contain security sensitive data. A new flag
|
to be used for messages that contain security sensitive data that
|
||||||
SD_BUS_VTABLE_SENSITIVE has been introduced as well to mark methods
|
should be erased after use. A new flag SD_BUS_VTABLE_SENSITIVE has
|
||||||
in sd-bus vtables, causing any incoming and outgoing messages of
|
been introduced as well that allows marking method calls in sd-bus
|
||||||
those methods to be implicitly marked as "sensitive".
|
vtables like this, so that this new message flag is implicitly set
|
||||||
|
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) to standard output for
|
contents of a message (or parts thereof) onto standard output, for
|
||||||
debugging purposes.
|
debugging purposes.
|
||||||
|
|
||||||
* systemd-sysusers gained support for creating users with the primary
|
* systemd-sysusers gained support for creating users with primary
|
||||||
group named differently than the user.
|
groups named differently than the user itself.
|
||||||
|
|
||||||
* systemd-resolved's DNS-over-TLS support gained SNI validation.
|
* systemd-resolved's DNS-over-TLS support gained SNI validation.
|
||||||
|
|
||||||
|
@ -173,8 +178,8 @@ CHANGES WITH 245:
|
||||||
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 already in the
|
set the specified encrypted volume is unlocked in the initrd
|
||||||
initrd. This concept corresponds to the x-initrd.mount option in
|
already. 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
|
||||||
|
@ -189,41 +194,42 @@ CHANGES WITH 245:
|
||||||
|
|
||||||
* 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. systemd also acquired a new logo, thanks to Tobias
|
repository. In particular, systemd acquired a new logo, thanks to
|
||||||
Bernard.
|
Tobias 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. This
|
generated via all supported naming schemes to each interface in
|
||||||
may be further tweaked with .link files and the AlternativeName= and
|
parallel. This may be further tweaked with .link drop-in files, and
|
||||||
AlternativeNamesPolicy= settings. Other components of systemd have
|
the AlternativeName= and AlternativeNamesPolicy= settings. All other
|
||||||
been updated to support the new alternative names wherever
|
components of systemd have been updated to support the new
|
||||||
appropriate. For example, systemd-nspawn will now generate
|
alternative names too, wherever that is appropriate. For example,
|
||||||
alternative interface names for the host-facing side of container
|
systemd-nspawn will now generate alternative interface names for the
|
||||||
veth links based on the full container name without truncation.
|
host-facing side of container veth links based on the full container
|
||||||
|
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) based on the container name is truncated, a
|
"alternative" names) is the truncated result of container name a
|
||||||
simple hashing scheme is used to give different interface names to
|
simple hashing scheme is used that ensures that multiple containers
|
||||||
multiple containers whose names all begin with the same prefix. Since
|
whose name all begin the same are likely resulting in different
|
||||||
this changes the primary interface names pointing to containers if
|
interface names. Since this changes the primary interface names
|
||||||
truncation happens, the old scheme may still be requested by
|
pointing to containers if truncation happens the old scheme may still
|
||||||
selecting an older naming scheme, via the net.naming-scheme= kernel
|
be requested by selecting a different naming scheme than the v245
|
||||||
command line option.
|
one, via the net.naming-scheme= kernel 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 set the
|
node access to /dev/rtc as well as the system calls that allow to set
|
||||||
system clock and the CAP_SYS_TIME and CAP_WAKE_ALARM capabilities.
|
the system clock. It also removes the CAP_SYS_TIME and CAP_WAKE_ALARM
|
||||||
Note that this option does not affect access to auxiliary services
|
capabilities. Note that this option does not affect access to
|
||||||
that allow changing the clock, for example access to
|
auxiliary services that allow changing the clock, for example access
|
||||||
systemd-timedated.
|
to 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
|
||||||
|
@ -246,54 +252,20 @@ CHANGES WITH 245:
|
||||||
* 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.
|
||||||
|
|
||||||
* The [TrafficControlQueueingDiscipline] section in .network files has
|
* systemd-logind will now validate access to the operation for changing
|
||||||
been renamed to [NetworkEmulator] with the "NetworkEmulator" prefix
|
virtual terminals via a PolicyKit action. By default only users with
|
||||||
dropped from the individual setting names.
|
at least one session on a local VT will get access to the method call.
|
||||||
|
|
||||||
* Any .link and .network files that have an empty [Match] section (this
|
* When systemd sets up PAM sessions that invoked service processes shall
|
||||||
also includes empty and commented-out files) will now be
|
run in, the pam_setcred() API is now invoked, thus permitting PAM
|
||||||
rejected. systemd-udev and systemd-networkd started warning about
|
modules to set additional credentials for the processes.
|
||||||
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:
|
||||||
|
|
||||||
|
@ -7209,9 +7181,10 @@ 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 ignore
|
* The (.ini) configuration file parser will now silently
|
||||||
sections whose names begin with "X-". This may be used to maintain
|
ignore sections whose name begins with "X-". This may be
|
||||||
application-specific extension sections in unit files.
|
used to maintain application-specific extension sections in unit
|
||||||
|
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
|
||||||
enqueue stop jobs from a defer event that processes queue instead of
|
enqeue 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,12 +69,6 @@
|
||||||
|
|
||||||
<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,7 +195,6 @@ 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',
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
<?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>MIN_OPERSTATE</replaceable><optional>:<replaceable>MAX_OPERSTATE</replaceable></optional></optional></term>
|
<term><option>-i</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>
|
<term><option>--interface=</option><replaceable>INTERFACE</replaceable><optional>:<replaceable>OPERSTATE</replaceable></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 and maximum operational
|
for all specified interfaces to be online. Optionally, required minimum operational state can be
|
||||||
states can be specified after a colon <literal>:</literal>. Please see
|
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>MIN_OPERSTATE</replaceable><optional>:<replaceable>MAX_OPERSTATE</replaceable></optional></term>
|
<term><option>-o</option> <replaceable>OPERSTATE</replaceable></term>
|
||||||
<term><option>--operational-state=</option><replaceable>MIN_OPERSTATE</replaceable><optional>:<replaceable>MAX_OPERSTATE</replaceable></optional></term>
|
<term><option>--operational-state=</option><replaceable>OPERSTATE</replaceable></term>
|
||||||
|
|
||||||
<listitem><para>Takes a minimum operational state and an optional maximum operational state.
|
<listitem><para>Takes an operational state. Please see
|
||||||
Please see <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
<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,14 +206,13 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>RequiredForOnline=</varname></term>
|
<term><varname>RequiredForOnline=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Takes a boolean or a minimum operational state and an optional maximum operational state.
|
<para>Takes a boolean or operational state. Please see
|
||||||
Please see <citerefentry><refentrytitle>networkctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
<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 a minimum operational state and an optional maximum operational
|
when checking for online state. When an operational state is set, <literal>yes</literal> is implied,
|
||||||
state are set, <literal>yes</literal> is implied, and this controls the minimum and maximum
|
and this controls the operational state required for the network interface to be considered online.
|
||||||
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,19 +848,20 @@
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><filename>blockdev@.target</filename></term>
|
<term><filename>blockdev@.target</filename></term>
|
||||||
<listitem><para>This template unit is used to order mount units and other consumers of block
|
<listitem><para>This template unit may be used to order mount units and other consumers of block
|
||||||
devices after services that synthesize these block devices. In particular, this is intended to be
|
devices against services that synthesize these block devices. This is intended to be used to order
|
||||||
used with storage services (such as
|
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. Storage services are ordered before an instance of
|
that allocate and manage a virtual block device against mount units and other consumers of
|
||||||
<filename>blockdev@.target</filename>, and the consumer units after it. The ordering is
|
it. Specifically, the storage services are supposed to be orderd before an instance of
|
||||||
particularly relevant during shutdown, as it ensures that the mount is deactivated first and the
|
<filename>blockdev@.target</filename>, and the mount unit (or other consuming unit, such as a swap
|
||||||
service backing the mount later. The <filename>blockdev@.target</filename> instance should be
|
unit) after it. The ordering is particular relevant during shutdown, as it ensures that the mount
|
||||||
pulled in via a <option>Wants=</option> dependency of the storage daemon and thus generally not be
|
is deactivated first and the service backing the mount only deactivated after that completed. The
|
||||||
part of any transaction unless a storage daemon is used. The instance name for instances of this
|
<filename>blockdev@.target</filename> instance should be pulled in via a <option>Wants=</option>
|
||||||
template unit must be a properly escaped block device node path, e.g.
|
dependency of the storage daemon and thus generally not be part of any transaction unless a storage
|
||||||
<filename>blockdev@dev-mapper-foobar.target</filename> for the storage device
|
daemon is used. The instance name for instances of this template unit is supposed to be the
|
||||||
<filename>/dev/mapper/foobar</filename>.</para></listitem>
|
properly escaped bock device node path, e.g. <filename>blockdev@dev-mapper-foobar.target</filename>
|
||||||
|
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,16 +25,6 @@
|
||||||
<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>
|
||||||
|
@ -91,13 +81,11 @@ r - lowest-highest</programlisting>
|
||||||
|
|
||||||
<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
|
u root 0 "Superuser" /root /bin/zsh</programlisting>
|
||||||
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>
|
||||||
|
@ -121,7 +109,7 @@ r - 500-900
|
||||||
<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 creates a matching group. The group will be
|
implicitly create 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 : '245',
|
version : '244',
|
||||||
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.28.0'
|
libsystemd_version = '0.27.1'
|
||||||
libudev_version = '1.6.17'
|
libudev_version = '1.6.16'
|
||||||
|
|
||||||
# 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,7 +685,6 @@ 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,27 +4207,3 @@ _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,7 +26,6 @@ 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",
|
||||||
|
@ -57,49 +56,3 @@ 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,7 +8,6 @@
|
||||||
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,
|
||||||
|
@ -48,13 +47,3 @@ 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,14 +3957,8 @@ 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",
|
fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s\n",
|
||||||
strempty(link_operstate_to_string(link->network->required_operstate_for_online.min)));
|
strempty(link_operstate_to_string(link->network->required_operstate_for_online)));
|
||||||
|
|
||||||
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_RANGE_DEFAULT,
|
.required_operstate_for_online = LINK_OPERSTATE_DEGRADED,
|
||||||
.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;
|
||||||
LinkOperationalStateRange range;
|
LinkOperationalState s;
|
||||||
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_RANGE_DEFAULT;
|
network->required_operstate_for_online = LINK_OPERSTATE_DEGRADED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = parse_operational_state_range(rvalue, &range);
|
s = link_operstate_from_string(rvalue);
|
||||||
if (r < 0) {
|
if (s < 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;
|
||||||
range = LINK_OPERSTATE_RANGE_DEFAULT;
|
s = LINK_OPERSTATE_DEGRADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
network->required_for_online = required;
|
network->required_for_online = required;
|
||||||
network->required_operstate_for_online = range;
|
network->required_operstate_for_online = s;
|
||||||
|
|
||||||
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? */
|
||||||
LinkOperationalStateRange required_operstate_for_online;
|
LinkOperationalState 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_RANGE_DEFAULT,
|
.required_operstate = LINK_OPERSTATE_DEGRADED,
|
||||||
};
|
};
|
||||||
|
|
||||||
r = hashmap_put(m->links_by_name, l->ifname, l);
|
r = hashmap_put(m->links_by_name, l->ifname, l);
|
||||||
|
@ -105,6 +105,7 @@ 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);
|
||||||
|
@ -120,21 +121,19 @@ 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 {
|
||||||
r = parse_operational_state_range(required_operstate, &l->required_operstate);
|
s = link_operstate_from_string(required_operstate);
|
||||||
if (r < 0)
|
if (s < 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;
|
||||||
LinkOperationalStateRange required_operstate;
|
LinkOperationalState 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, LinkOperationalStateRange s) {
|
static int manager_link_is_online(Manager *m, Link *l, LinkOperationalState 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,18 +46,13 @@ static int manager_link_is_online(Manager *m, Link *l, LinkOperationalStateRange
|
||||||
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.min < 0)
|
if (s < 0)
|
||||||
s.min = m->required_operstate.min >= 0 ? m->required_operstate.min
|
s = m->required_operstate >= 0 ? m->required_operstate : l->required_operstate;
|
||||||
: l->required_operstate.min;
|
|
||||||
|
|
||||||
if (s.max < 0)
|
if (l->operational_state < s) {
|
||||||
s.max = m->required_operstate.max >= 0 ? m->required_operstate.max
|
log_link_debug(l, "Operational state '%s' is below '%s'",
|
||||||
: 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.min), link_operstate_to_string(s.max));
|
link_operstate_to_string(s));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,14 +70,9 @@ 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) {
|
||||||
LinkOperationalStateRange *range = p;
|
LinkOperationalState s = PTR_TO_INT(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)
|
||||||
|
@ -90,7 +80,7 @@ bool manager_configured(Manager *m) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manager_link_is_online(m, l, *range) <= 0) {
|
if (manager_link_is_online(m, l, s) <= 0) {
|
||||||
if (!m->any)
|
if (!m->any)
|
||||||
return false;
|
return false;
|
||||||
continue;
|
continue;
|
||||||
|
@ -112,9 +102,7 @@ bool manager_configured(Manager *m) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = manager_link_is_online(m, l,
|
r = manager_link_is_online(m, l, _LINK_OPERSTATE_INVALID);
|
||||||
(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)
|
||||||
|
@ -301,7 +289,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,
|
||||||
LinkOperationalStateRange required_operstate,
|
LinkOperationalState 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;
|
||||||
|
|
||||||
LinkOperationalStateRange required_operstate;
|
LinkOperationalState 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,
|
||||||
LinkOperationalStateRange required_operstate,
|
LinkOperationalState 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 LinkOperationalStateRange arg_required_operstate = { _LINK_OPERSTATE_INVALID, _LINK_OPERSTATE_INVALID };
|
static LinkOperationalState arg_required_operstate = _LINK_OPERSTATE_INVALID;
|
||||||
static bool arg_any = false;
|
static bool arg_any = false;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_interfaces, hashmap_free_free_keyp);
|
||||||
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[:MIN_OPERSTATE[:MAX_OPERSTATE]]\n"
|
" -i --interface=INTERFACE[: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=MIN_OPERSTATE[:MAX_OPERSTATE]\n"
|
" -o --operational-state=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_range(const char *str) {
|
static int parse_interface_with_operstate(const char *str) {
|
||||||
_cleanup_free_ char *ifname = NULL;
|
_cleanup_free_ char *ifname = NULL;
|
||||||
_cleanup_free_ LinkOperationalStateRange *range;
|
LinkOperationalState s;
|
||||||
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) {
|
||||||
r = parse_operational_state_range(p + 1, range);
|
if (isempty(p + 1))
|
||||||
if (r < 0)
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
log_error_errno(r, "Invalid operational state range '%s'", p + 1);
|
"Operational state is empty.");
|
||||||
|
|
||||||
|
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 {
|
||||||
range->min = _LINK_OPERSTATE_INVALID;
|
s = _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_range(const char *str) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = hashmap_put(arg_interfaces, ifname, TAKE_PTR(range));
|
r = hashmap_put(arg_interfaces, ifname, INT_TO_PTR(s));
|
||||||
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_range(optarg);
|
r = parse_interface_with_operstate(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': {
|
||||||
LinkOperationalStateRange range;
|
LinkOperationalState s;
|
||||||
|
|
||||||
r = parse_operational_state_range(optarg, &range);
|
s = link_operstate_from_string(optarg);
|
||||||
if (r < 0)
|
if (s < 0)
|
||||||
return log_error_errno(r, "Invalid operational state range '%s'", optarg);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Invalid operational state '%s'", optarg);
|
||||||
arg_required_operstate = range;
|
|
||||||
|
|
||||||
|
arg_required_operstate = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARG_ANY:
|
case ARG_ANY:
|
||||||
|
|
|
@ -30,34 +30,6 @@ 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,
|
||||||
|
@ -65,7 +37,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 *ret_error) {
|
sd_bus_error *e) {
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -88,7 +60,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;
|
const char *sender, **k, **v;
|
||||||
|
|
||||||
sender = sd_bus_message_get_sender(call);
|
sender = sd_bus_message_get_sender(call);
|
||||||
if (!sender)
|
if (!sender)
|
||||||
|
@ -112,7 +84,17 @@ int bus_test_polkit(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = bus_message_append_strv_key_value(request, details);
|
r = sd_bus_message_open_container(request, 'a', "{ss}");
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -120,11 +102,11 @@ int bus_test_polkit(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_bus_call(call->bus, request, 0, ret_error, &reply);
|
r = sd_bus_call(call->bus, request, 0, e, &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(ret_error, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
|
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
|
||||||
sd_bus_error_free(ret_error);
|
sd_bus_error_free(e);
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,17 +137,15 @@ 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;
|
||||||
|
|
||||||
|
@ -177,72 +157,32 @@ 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) {
|
||||||
goto fail;
|
r = sd_bus_reply_method_errno(q->request, r, NULL);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_bus_enqueue_for_read(sd_bus_message_get_bus(q->request), q->request);
|
r = q->callback(q->request, q->userdata, &error_buffer);
|
||||||
if (r < 0)
|
r = bus_maybe_reply_error(q->request, r, &error_buffer);
|
||||||
goto fail;
|
|
||||||
|
|
||||||
return 1;
|
finish:
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,14 +196,16 @@ int bus_verify_polkit_async(
|
||||||
bool interactive,
|
bool interactive,
|
||||||
uid_t good_user,
|
uid_t good_user,
|
||||||
Hashmap **registry,
|
Hashmap **registry,
|
||||||
sd_bus_error *ret_error) {
|
sd_bus_error *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);
|
||||||
|
@ -279,17 +221,11 @@ int bus_verify_polkit_async(
|
||||||
if (q) {
|
if (q) {
|
||||||
int authorized, challenge;
|
int authorized, challenge;
|
||||||
|
|
||||||
/* This is the second invocation of this function, and there's already a response from
|
/* This is the second invocation of this function, and
|
||||||
* polkit, let's process it */
|
* there's already a response from polkit, let's
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
@ -301,7 +237,7 @@ int bus_verify_polkit_async(
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
/* Copy error from polkit reply */
|
/* Copy error from polkit reply */
|
||||||
sd_bus_error_copy(ret_error, e);
|
sd_bus_error_copy(error, e);
|
||||||
return -sd_bus_error_get_errno(e);
|
return -sd_bus_error_get_errno(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +251,7 @@ int bus_verify_polkit_async(
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (challenge)
|
if (challenge)
|
||||||
return sd_bus_error_set(ret_error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
|
return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
|
||||||
|
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
@ -327,11 +263,20 @@ 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;
|
||||||
|
@ -360,7 +305,17 @@ int bus_verify_polkit_async(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = bus_message_append_strv_key_value(pk, details);
|
r = sd_bus_message_open_container(pk, 'a', "{ss}");
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -368,25 +323,13 @@ int bus_verify_polkit_async(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
q = new(AsyncPolkitQuery, 1);
|
q = new0(AsyncPolkitQuery, 1);
|
||||||
if (!q)
|
if (!q)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*q = (AsyncPolkitQuery) {
|
q->request = sd_bus_message_ref(call);
|
||||||
.request = sd_bus_message_ref(call),
|
q->callback = callback;
|
||||||
};
|
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,7 +207,6 @@ 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,7 +2,6 @@
|
||||||
Description=Test for CapabilityBoundingSet
|
Description=Test for CapabilityBoundingSet
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c '! capsh --print | grep "^Bounding set .*cap_chown"'
|
||||||
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,6 +3,5 @@ Description=Test CAP_MKNOD capability for PrivateDevices=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=no
|
PrivateDevices=no
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_mknod'
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,6 +3,5 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=no
|
PrivateDevices=no
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_rawio'
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,6 +3,5 @@ Description=Test CAP_MKNOD capability for PrivateDevices=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=yes
|
PrivateDevices=yes
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_mknod'
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,6 +3,5 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PrivateDevices=yes
|
PrivateDevices=yes
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_rawio'
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,6 +3,5 @@ Description=Test CAP_SYSLOG for ProtectKernelLogs=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelLogs=no
|
ProtectKernelLogs=no
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_syslog'
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_syslog'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,6 +3,5 @@ Description=Test CAP_SYSLOG for ProtectKernelLogs=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelLogs=yes
|
ProtectKernelLogs=yes
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_syslog'
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_syslog'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,6 +3,5 @@ Description=Test CAP_SYS_MODULE ProtectKernelModules=no
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelModules=no
|
ProtectKernelModules=no
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_module'
|
||||||
ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -3,6 +3,5 @@ Description=Test CAP_SYS_MODULE for ProtectKernelModules=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ProtectKernelModules=yes
|
ProtectKernelModules=yes
|
||||||
# sed: remove dropped capabilities (cap_xxx-[epi]) from the output
|
ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_module'
|
||||||
ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module'
|
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
|
@ -27,7 +27,6 @@ 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)
|
||||||
|
@ -165,7 +164,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', 'systemd-udevd.service', 'firewalld.service']:
|
for u in ['systemd-networkd.socket', 'systemd-networkd.service', 'systemd-resolved.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)
|
||||||
|
@ -227,34 +226,21 @@ 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', 'systemd-udevd.service']:
|
for u in ['systemd-networkd.service', 'systemd-resolved.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:
|
||||||
|
@ -3582,7 +3568,6 @@ 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')
|
||||||
|
@ -3595,11 +3580,10 @@ 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.udevd_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.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')
|
||||||
|
@ -3609,8 +3593,6 @@ 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